summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2009-09-17 07:15:29 +0200
committerBoris Kolpackov <boris@codesynthesis.com>2009-09-17 07:15:29 +0200
commitf0510d2f90467de8e8f260b47d79a9baaf9bef17 (patch)
tree0b9929946f06a9cbe9b9e8f2a7600dae4e048f79
Start tracking XSD with git
-rw-r--r--FLOSSE89
-rw-r--r--GPLv2340
-rw-r--r--INSTALL48
-rw-r--r--LICENSE26
-rw-r--r--NEWS1048
-rw-r--r--README27
-rw-r--r--build/bootstrap.make54
-rw-r--r--build/configuration-rules.make18
-rw-r--r--build/configuration.make33
-rwxr-xr-xbuild/configure73
-rw-r--r--build/import/libace/LICENSE340
-rw-r--r--build/import/libace/configuration-rules.make15
-rwxr-xr-xbuild/import/libace/configure58
-rw-r--r--build/import/libace/rules.make29
-rw-r--r--build/import/libace/stub.make32
-rw-r--r--build/import/libace/version1
-rw-r--r--build/import/libbackend-elements/LICENSE340
-rw-r--r--build/import/libbackend-elements/configuration-rules.make15
-rwxr-xr-xbuild/import/libbackend-elements/configure55
-rw-r--r--build/import/libbackend-elements/stub.make32
-rw-r--r--build/import/libboost/LICENSE340
-rw-r--r--build/import/libboost/configuration-rules.make15
-rwxr-xr-xbuild/import/libboost/configure83
-rw-r--r--build/import/libboost/date-time/rules.make39
-rw-r--r--build/import/libboost/date-time/stub.make32
-rw-r--r--build/import/libboost/filesystem/rules.make41
-rw-r--r--build/import/libboost/filesystem/stub.make32
-rw-r--r--build/import/libboost/regex/rules.make38
-rw-r--r--build/import/libboost/regex/stub.make32
-rw-r--r--build/import/libboost/serialization/rules.make38
-rw-r--r--build/import/libboost/serialization/stub.make32
-rw-r--r--build/import/libboost/version1
-rw-r--r--build/import/libcult/LICENSE340
-rw-r--r--build/import/libcult/configuration-rules.make15
-rwxr-xr-xbuild/import/libcult/configure55
-rw-r--r--build/import/libcult/stub.make30
-rw-r--r--build/import/libdbxml/LICENSE340
-rw-r--r--build/import/libdbxml/configuration-rules.make15
-rwxr-xr-xbuild/import/libdbxml/configure58
-rw-r--r--build/import/libdbxml/rules.make42
-rw-r--r--build/import/libdbxml/stub.make32
-rw-r--r--build/import/libdbxml/version1
-rw-r--r--build/import/libxerces-c/LICENSE340
-rw-r--r--build/import/libxerces-c/configuration-rules.make15
-rwxr-xr-xbuild/import/libxerces-c/configure73
-rw-r--r--build/import/libxerces-c/rules.make52
-rw-r--r--build/import/libxerces-c/stub.make32
-rw-r--r--build/import/libxerces-c/version1
-rw-r--r--build/import/libxqilla/LICENSE340
-rw-r--r--build/import/libxqilla/configuration-rules.make15
-rwxr-xr-xbuild/import/libxqilla/configure57
-rw-r--r--build/import/libxqilla/rules.make30
-rw-r--r--build/import/libxqilla/stub.make32
-rw-r--r--build/import/libxqilla/version1
-rw-r--r--build/import/libxsd-frontend/LICENSE22
-rw-r--r--build/import/libxsd-frontend/configuration-rules.make15
-rwxr-xr-xbuild/import/libxsd-frontend/configure55
-rw-r--r--build/import/libxsd-frontend/stub.make30
-rw-r--r--build/xsd/parser/xsd-cxx.make72
-rw-r--r--build/xsd/tree/xsd-cxx.make43
-rw-r--r--documentation/cxx/parser/guide/figure-1.pngbin0 -> 34195 bytes
-rw-r--r--documentation/cxx/parser/guide/figure-1.svg373
-rw-r--r--documentation/cxx/parser/guide/guide.html2ps65
-rw-r--r--documentation/cxx/parser/guide/index.xhtml4126
-rw-r--r--documentation/cxx/parser/guide/makefile12
l---------documentation/cxx/tree/dbxml/driver.cxx1
-rw-r--r--documentation/cxx/tree/dbxml/index.xhtml350
l---------documentation/cxx/tree/dbxml/library.xsd1
-rw-r--r--documentation/cxx/tree/guide/guide.html2ps65
-rw-r--r--documentation/cxx/tree/guide/index.xhtml2678
-rw-r--r--documentation/cxx/tree/guide/makefile12
-rw-r--r--documentation/cxx/tree/manual/index.xhtml5868
-rw-r--r--documentation/cxx/tree/manual/makefile12
-rw-r--r--documentation/cxx/tree/manual/manual.html2ps66
-rw-r--r--documentation/cxx/tree/reference/footer.html6
-rw-r--r--documentation/cxx/tree/reference/libxsd.doxygen1316
-rw-r--r--documentation/cxx/tree/reference/makefile18
-rw-r--r--documentation/default.css319
-rw-r--r--documentation/future.xhtml103
-rw-r--r--documentation/makefile20
-rw-r--r--documentation/schema-authoring-guide.xhtml187
-rw-r--r--documentation/xsd.11770
-rw-r--r--documentation/xsd.xhtml1508
-rw-r--r--examples/cxx/parser/README45
-rw-r--r--examples/cxx/parser/generated/README32
-rw-r--r--examples/cxx/parser/generated/library.xml53
-rw-r--r--examples/cxx/parser/generated/library.xsd79
-rw-r--r--examples/cxx/parser/generated/makefile72
-rw-r--r--examples/cxx/parser/hello/README28
-rw-r--r--examples/cxx/parser/hello/driver.cxx68
-rw-r--r--examples/cxx/parser/hello/hello.xml20
-rw-r--r--examples/cxx/parser/hello/hello.xsd22
-rw-r--r--examples/cxx/parser/hello/makefile67
-rw-r--r--examples/cxx/parser/library/README44
-rw-r--r--examples/cxx/parser/library/driver.cxx110
-rw-r--r--examples/cxx/parser/library/library-pimpl.cxx184
-rw-r--r--examples/cxx/parser/library/library-pimpl.hxx136
-rw-r--r--examples/cxx/parser/library/library.hxx242
-rw-r--r--examples/cxx/parser/library/library.map16
-rw-r--r--examples/cxx/parser/library/library.xml53
-rw-r--r--examples/cxx/parser/library/library.xsd79
-rw-r--r--examples/cxx/parser/library/makefile68
-rw-r--r--examples/cxx/parser/makefile19
-rw-r--r--examples/cxx/parser/mixed/README49
-rw-r--r--examples/cxx/parser/mixed/anchor.hxx34
-rw-r--r--examples/cxx/parser/mixed/driver.cxx101
-rw-r--r--examples/cxx/parser/mixed/makefile68
-rw-r--r--examples/cxx/parser/mixed/text.map7
-rw-r--r--examples/cxx/parser/mixed/text.xml18
-rw-r--r--examples/cxx/parser/mixed/text.xsd29
-rw-r--r--examples/cxx/parser/mixin/README34
-rw-r--r--examples/cxx/parser/mixin/driver.cxx104
-rw-r--r--examples/cxx/parser/mixin/instance.xml17
-rw-r--r--examples/cxx/parser/mixin/makefile68
-rw-r--r--examples/cxx/parser/mixin/schema.map8
-rw-r--r--examples/cxx/parser/mixin/schema.xsd31
-rw-r--r--examples/cxx/parser/mixin/types.hxx44
-rw-r--r--examples/cxx/parser/multiroot/README51
-rw-r--r--examples/cxx/parser/multiroot/balance.xml17
-rw-r--r--examples/cxx/parser/multiroot/deposit.xml18
-rw-r--r--examples/cxx/parser/multiroot/driver.cxx162
-rw-r--r--examples/cxx/parser/multiroot/makefile68
-rw-r--r--examples/cxx/parser/multiroot/protocol-pimpl.cxx47
-rw-r--r--examples/cxx/parser/multiroot/protocol-pimpl.hxx49
-rw-r--r--examples/cxx/parser/multiroot/protocol.hxx62
-rw-r--r--examples/cxx/parser/multiroot/protocol.map12
-rw-r--r--examples/cxx/parser/multiroot/protocol.xsd51
-rw-r--r--examples/cxx/parser/multiroot/withdraw.xml18
-rw-r--r--examples/cxx/parser/performance/README44
-rw-r--r--examples/cxx/parser/performance/driver.cxx308
-rw-r--r--examples/cxx/parser/performance/gen.cxx76
-rw-r--r--examples/cxx/parser/performance/makefile68
-rw-r--r--examples/cxx/parser/performance/test-500k.xml1
-rw-r--r--examples/cxx/parser/performance/test-50k.xml1
-rw-r--r--examples/cxx/parser/performance/test-5k.xml1
-rw-r--r--examples/cxx/parser/performance/test.xsd50
-rw-r--r--examples/cxx/parser/performance/time.cxx47
-rw-r--r--examples/cxx/parser/performance/time.hxx111
-rw-r--r--examples/cxx/parser/polymorphism/README30
-rw-r--r--examples/cxx/parser/polymorphism/driver.cxx71
-rw-r--r--examples/cxx/parser/polymorphism/makefile68
-rw-r--r--examples/cxx/parser/polymorphism/supermen-pimpl.cxx86
-rw-r--r--examples/cxx/parser/polymorphism/supermen-pimpl.hxx69
-rw-r--r--examples/cxx/parser/polymorphism/supermen.xml26
-rw-r--r--examples/cxx/parser/polymorphism/supermen.xsd49
-rw-r--r--examples/cxx/parser/polyroot/README36
-rw-r--r--examples/cxx/parser/polyroot/batman.xml17
-rw-r--r--examples/cxx/parser/polyroot/driver.cxx139
-rw-r--r--examples/cxx/parser/polyroot/makefile68
-rw-r--r--examples/cxx/parser/polyroot/person.xml16
-rw-r--r--examples/cxx/parser/polyroot/superman.xml17
-rw-r--r--examples/cxx/parser/polyroot/supermen-pimpl.cxx86
-rw-r--r--examples/cxx/parser/polyroot/supermen-pimpl.hxx65
-rw-r--r--examples/cxx/parser/polyroot/supermen.xsd37
-rw-r--r--examples/cxx/parser/wildcard/README27
-rw-r--r--examples/cxx/parser/wildcard/driver.cxx240
-rw-r--r--examples/cxx/parser/wildcard/email.xml32
-rw-r--r--examples/cxx/parser/wildcard/email.xsd51
-rw-r--r--examples/cxx/parser/wildcard/makefile67
-rw-r--r--examples/cxx/tree/README70
-rw-r--r--examples/cxx/tree/binary/README16
-rw-r--r--examples/cxx/tree/binary/boost/README49
-rw-r--r--examples/cxx/tree/binary/boost/boost-archive-extraction.hxx188
-rw-r--r--examples/cxx/tree/binary/boost/boost-archive-insertion.hxx177
-rw-r--r--examples/cxx/tree/binary/boost/driver.cxx73
-rw-r--r--examples/cxx/tree/binary/boost/library-prologue.hxx9
-rw-r--r--examples/cxx/tree/binary/boost/library.xml53
-rw-r--r--examples/cxx/tree/binary/boost/library.xsd76
-rw-r--r--examples/cxx/tree/binary/boost/makefile79
-rw-r--r--examples/cxx/tree/binary/cdr/README36
-rw-r--r--examples/cxx/tree/binary/cdr/driver.cxx88
-rw-r--r--examples/cxx/tree/binary/cdr/library.xml53
-rw-r--r--examples/cxx/tree/binary/cdr/library.xsd76
-rw-r--r--examples/cxx/tree/binary/cdr/makefile78
-rw-r--r--examples/cxx/tree/binary/makefile30
-rw-r--r--examples/cxx/tree/binary/xdr/README34
-rw-r--r--examples/cxx/tree/binary/xdr/driver.cxx149
-rw-r--r--examples/cxx/tree/binary/xdr/library.xml53
-rw-r--r--examples/cxx/tree/binary/xdr/library.xsd76
-rw-r--r--examples/cxx/tree/binary/xdr/makefile78
-rw-r--r--examples/cxx/tree/caching/README29
-rw-r--r--examples/cxx/tree/caching/driver.cxx179
-rw-r--r--examples/cxx/tree/caching/library.xml53
-rw-r--r--examples/cxx/tree/caching/library.xsd73
-rw-r--r--examples/cxx/tree/caching/makefile71
-rw-r--r--examples/cxx/tree/custom/README37
-rw-r--r--examples/cxx/tree/custom/calendar/README47
-rw-r--r--examples/cxx/tree/custom/calendar/calendar.xml23
-rw-r--r--examples/cxx/tree/custom/calendar/calendar.xsd32
-rw-r--r--examples/cxx/tree/custom/calendar/driver.cxx40
-rw-r--r--examples/cxx/tree/custom/calendar/makefile90
-rw-r--r--examples/cxx/tree/custom/calendar/xml-schema-custom.cxx57
-rw-r--r--examples/cxx/tree/custom/calendar/xml-schema-custom.hxx34
-rw-r--r--examples/cxx/tree/custom/comments/README57
-rw-r--r--examples/cxx/tree/custom/comments/dom-parse.cxx118
-rw-r--r--examples/cxx/tree/custom/comments/dom-parse.hxx23
-rw-r--r--examples/cxx/tree/custom/comments/driver.cxx91
-rw-r--r--examples/cxx/tree/custom/comments/makefile84
-rw-r--r--examples/cxx/tree/custom/comments/people.xml21
-rw-r--r--examples/cxx/tree/custom/comments/people.xsd30
-rw-r--r--examples/cxx/tree/custom/comments/xml-schema-custom.cxx118
-rw-r--r--examples/cxx/tree/custom/comments/xml-schema-custom.hxx58
-rw-r--r--examples/cxx/tree/custom/contacts/README40
-rw-r--r--examples/cxx/tree/custom/contacts/contacts-custom.cxx51
-rw-r--r--examples/cxx/tree/custom/contacts/contacts-custom.hxx44
-rw-r--r--examples/cxx/tree/custom/contacts/contacts.xml21
-rw-r--r--examples/cxx/tree/custom/contacts/contacts.xsd32
-rw-r--r--examples/cxx/tree/custom/contacts/driver.cxx39
-rw-r--r--examples/cxx/tree/custom/contacts/makefile77
-rw-r--r--examples/cxx/tree/custom/double/README62
-rw-r--r--examples/cxx/tree/custom/double/double-custom.cxx97
-rw-r--r--examples/cxx/tree/custom/double/double-custom.hxx68
-rw-r--r--examples/cxx/tree/custom/double/driver.cxx32
-rw-r--r--examples/cxx/tree/custom/double/makefile79
-rw-r--r--examples/cxx/tree/custom/double/order.xsd26
-rw-r--r--examples/cxx/tree/custom/makefile22
-rw-r--r--examples/cxx/tree/custom/taxonomy/README50
-rw-r--r--examples/cxx/tree/custom/taxonomy/driver.cxx39
-rw-r--r--examples/cxx/tree/custom/taxonomy/makefile82
-rw-r--r--examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx20
-rw-r--r--examples/cxx/tree/custom/taxonomy/people-custom.cxx180
-rw-r--r--examples/cxx/tree/custom/taxonomy/people-custom.hxx103
-rw-r--r--examples/cxx/tree/custom/taxonomy/people.xml27
-rw-r--r--examples/cxx/tree/custom/taxonomy/people.xsd45
-rw-r--r--examples/cxx/tree/custom/wildcard/README45
-rw-r--r--examples/cxx/tree/custom/wildcard/driver.cxx48
-rw-r--r--examples/cxx/tree/custom/wildcard/makefile79
-rw-r--r--examples/cxx/tree/custom/wildcard/wildcard-custom.cxx85
-rw-r--r--examples/cxx/tree/custom/wildcard/wildcard-custom.hxx67
-rw-r--r--examples/cxx/tree/custom/wildcard/wildcard.xml15
-rw-r--r--examples/cxx/tree/custom/wildcard/wildcard.xsd26
-rw-r--r--examples/cxx/tree/dbxml/README45
-rw-r--r--examples/cxx/tree/dbxml/driver.cxx175
-rw-r--r--examples/cxx/tree/dbxml/library.xsd75
-rw-r--r--examples/cxx/tree/dbxml/makefile76
-rw-r--r--examples/cxx/tree/hello/README26
-rw-r--r--examples/cxx/tree/hello/driver.cxx37
-rw-r--r--examples/cxx/tree/hello/hello.xml20
-rw-r--r--examples/cxx/tree/hello/hello.xsd53
-rw-r--r--examples/cxx/tree/hello/makefile71
-rw-r--r--examples/cxx/tree/library/README32
-rw-r--r--examples/cxx/tree/library/driver.cxx131
-rw-r--r--examples/cxx/tree/library/library.xml53
-rw-r--r--examples/cxx/tree/library/library.xsd73
-rw-r--r--examples/cxx/tree/library/makefile73
-rw-r--r--examples/cxx/tree/makefile27
-rw-r--r--examples/cxx/tree/messaging/README58
-rw-r--r--examples/cxx/tree/messaging/balance.xml17
-rw-r--r--examples/cxx/tree/messaging/deposit.xml18
-rw-r--r--examples/cxx/tree/messaging/dom-parse.cxx118
-rw-r--r--examples/cxx/tree/messaging/dom-parse.hxx23
-rw-r--r--examples/cxx/tree/messaging/dom-serialize.cxx89
-rw-r--r--examples/cxx/tree/messaging/dom-serialize.hxx21
-rw-r--r--examples/cxx/tree/messaging/driver.cxx145
-rw-r--r--examples/cxx/tree/messaging/makefile72
-rw-r--r--examples/cxx/tree/messaging/protocol.xsd54
-rw-r--r--examples/cxx/tree/messaging/withdraw.xml18
-rw-r--r--examples/cxx/tree/mixed/README38
-rw-r--r--examples/cxx/tree/mixed/driver.cxx121
-rw-r--r--examples/cxx/tree/mixed/makefile73
-rw-r--r--examples/cxx/tree/mixed/text.xml18
-rw-r--r--examples/cxx/tree/mixed/text.xsd29
-rw-r--r--examples/cxx/tree/multiroot/README45
-rw-r--r--examples/cxx/tree/multiroot/balance.xml17
-rw-r--r--examples/cxx/tree/multiroot/deposit.xml18
-rw-r--r--examples/cxx/tree/multiroot/dom-parse.cxx118
-rw-r--r--examples/cxx/tree/multiroot/dom-parse.hxx23
-rw-r--r--examples/cxx/tree/multiroot/driver.cxx125
-rw-r--r--examples/cxx/tree/multiroot/makefile71
-rw-r--r--examples/cxx/tree/multiroot/protocol.xsd51
-rw-r--r--examples/cxx/tree/multiroot/withdraw.xml18
-rw-r--r--examples/cxx/tree/performance/README60
-rw-r--r--examples/cxx/tree/performance/driver.cxx91
-rw-r--r--examples/cxx/tree/performance/gen.cxx76
-rw-r--r--examples/cxx/tree/performance/makefile72
-rw-r--r--examples/cxx/tree/performance/parsing.cxx200
-rw-r--r--examples/cxx/tree/performance/serialization.cxx151
-rw-r--r--examples/cxx/tree/performance/test-500k.xml1
-rw-r--r--examples/cxx/tree/performance/test-50k.xml1
-rw-r--r--examples/cxx/tree/performance/test-5k.xml1
-rw-r--r--examples/cxx/tree/performance/test.xsd50
-rw-r--r--examples/cxx/tree/performance/time.cxx47
-rw-r--r--examples/cxx/tree/performance/time.hxx111
-rw-r--r--examples/cxx/tree/polymorphism/README28
-rw-r--r--examples/cxx/tree/polymorphism/driver.cxx60
-rw-r--r--examples/cxx/tree/polymorphism/makefile72
-rw-r--r--examples/cxx/tree/polymorphism/supermen.xml26
-rw-r--r--examples/cxx/tree/polymorphism/supermen.xsd49
-rw-r--r--examples/cxx/tree/streaming/README22
-rw-r--r--examples/cxx/tree/streaming/driver.cxx65
-rw-r--r--examples/cxx/tree/streaming/makefile74
-rw-r--r--examples/cxx/tree/streaming/records.xsd37
-rw-r--r--examples/cxx/tree/wildcard/README34
-rw-r--r--examples/cxx/tree/wildcard/driver.cxx160
-rw-r--r--examples/cxx/tree/wildcard/email.xml32
-rw-r--r--examples/cxx/tree/wildcard/email.xsd51
-rw-r--r--examples/cxx/tree/wildcard/makefile72
-rw-r--r--examples/cxx/tree/xpath/README47
-rw-r--r--examples/cxx/tree/xpath/dom-parse.cxx113
-rw-r--r--examples/cxx/tree/xpath/dom-parse.hxx26
-rw-r--r--examples/cxx/tree/xpath/driver-2.cxx139
-rw-r--r--examples/cxx/tree/xpath/driver.cxx137
-rw-r--r--examples/cxx/tree/xpath/makefile71
-rw-r--r--examples/cxx/tree/xpath/people.xml29
-rw-r--r--examples/cxx/tree/xpath/people.xsd39
-rw-r--r--examples/makefile17
-rw-r--r--libxsd/FLOSSE89
-rw-r--r--libxsd/GPLv2340
-rw-r--r--libxsd/INSTALL17
-rw-r--r--libxsd/LICENSE26
-rw-r--r--libxsd/README13
-rw-r--r--libxsd/makefile20
-rw-r--r--libxsd/xsd/cxx/auto-array.hxx114
-rw-r--r--libxsd/xsd/cxx/compilers/vc-7/post.hxx6
-rw-r--r--libxsd/xsd/cxx/compilers/vc-7/pre.hxx36
-rw-r--r--libxsd/xsd/cxx/compilers/vc-8/post.hxx6
-rw-r--r--libxsd/xsd/cxx/compilers/vc-8/pre.hxx28
-rw-r--r--libxsd/xsd/cxx/config.hxx15
-rw-r--r--libxsd/xsd/cxx/exceptions.hxx21
-rw-r--r--libxsd/xsd/cxx/parser/document.hxx90
-rw-r--r--libxsd/xsd/cxx/parser/document.txx129
-rw-r--r--libxsd/xsd/cxx/parser/elements.hxx95
-rw-r--r--libxsd/xsd/cxx/parser/elements.txx60
-rw-r--r--libxsd/xsd/cxx/parser/error-handler.hxx57
-rw-r--r--libxsd/xsd/cxx/parser/error-handler.txx41
-rw-r--r--libxsd/xsd/cxx/parser/exceptions.hxx153
-rw-r--r--libxsd/xsd/cxx/parser/exceptions.ixx129
-rw-r--r--libxsd/xsd/cxx/parser/exceptions.txx59
-rw-r--r--libxsd/xsd/cxx/parser/expat/elements.hxx344
-rw-r--r--libxsd/xsd/cxx/parser/expat/elements.txx822
-rw-r--r--libxsd/xsd/cxx/parser/map.hxx79
-rw-r--r--libxsd/xsd/cxx/parser/map.ixx27
-rw-r--r--libxsd/xsd/cxx/parser/map.txx31
-rw-r--r--libxsd/xsd/cxx/parser/non-validating/parser.hxx248
-rw-r--r--libxsd/xsd/cxx/parser/non-validating/parser.txx464
-rw-r--r--libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.hxx791
-rw-r--r--libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.ixx129
-rw-r--r--libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.txx2068
-rw-r--r--libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.hxx647
-rw-r--r--libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.ixx1249
-rw-r--r--libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.txx69
-rw-r--r--libxsd/xsd/cxx/parser/schema-exceptions.hxx187
-rw-r--r--libxsd/xsd/cxx/parser/schema-exceptions.ixx145
-rw-r--r--libxsd/xsd/cxx/parser/schema-exceptions.txx75
-rw-r--r--libxsd/xsd/cxx/parser/substitution-map.hxx230
-rw-r--r--libxsd/xsd/cxx/parser/substitution-map.txx76
-rw-r--r--libxsd/xsd/cxx/parser/validating/exceptions.hxx153
-rw-r--r--libxsd/xsd/cxx/parser/validating/exceptions.ixx163
-rw-r--r--libxsd/xsd/cxx/parser/validating/exceptions.txx97
-rw-r--r--libxsd/xsd/cxx/parser/validating/inheritance-map.hxx92
-rw-r--r--libxsd/xsd/cxx/parser/validating/inheritance-map.txx65
-rw-r--r--libxsd/xsd/cxx/parser/validating/parser.hxx471
-rw-r--r--libxsd/xsd/cxx/parser/validating/parser.txx667
-rw-r--r--libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.hxx1121
-rw-r--r--libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.ixx676
-rw-r--r--libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.txx2746
-rw-r--r--libxsd/xsd/cxx/parser/validating/xml-schema-pskel.hxx647
-rw-r--r--libxsd/xsd/cxx/parser/validating/xml-schema-pskel.ixx1249
-rw-r--r--libxsd/xsd/cxx/parser/validating/xml-schema-pskel.txx69
-rw-r--r--libxsd/xsd/cxx/parser/xerces/elements.hxx462
-rw-r--r--libxsd/xsd/cxx/parser/xerces/elements.txx964
-rw-r--r--libxsd/xsd/cxx/parser/xml-schema.hxx572
-rw-r--r--libxsd/xsd/cxx/parser/xml-schema.ixx1022
-rw-r--r--libxsd/xsd/cxx/parser/xml-schema.txx34
-rw-r--r--libxsd/xsd/cxx/post.hxx13
-rw-r--r--libxsd/xsd/cxx/pre.hxx15
-rw-r--r--libxsd/xsd/cxx/ro-string.hxx430
-rw-r--r--libxsd/xsd/cxx/ro-string.txx133
-rw-r--r--libxsd/xsd/cxx/tree/ace-cdr-stream-common.hxx26
-rw-r--r--libxsd/xsd/cxx/tree/ace-cdr-stream-extraction.hxx334
-rw-r--r--libxsd/xsd/cxx/tree/ace-cdr-stream-insertion.hxx249
-rw-r--r--libxsd/xsd/cxx/tree/bits/literals.hxx183
-rw-r--r--libxsd/xsd/cxx/tree/bits/literals.ixx606
-rw-r--r--libxsd/xsd/cxx/tree/buffer.hxx336
-rw-r--r--libxsd/xsd/cxx/tree/buffer.txx153
-rw-r--r--libxsd/xsd/cxx/tree/comparison-map.hxx109
-rw-r--r--libxsd/xsd/cxx/tree/comparison-map.txx287
-rw-r--r--libxsd/xsd/cxx/tree/containers-wildcard.hxx1335
-rw-r--r--libxsd/xsd/cxx/tree/containers.hxx1398
-rw-r--r--libxsd/xsd/cxx/tree/containers.txx284
-rw-r--r--libxsd/xsd/cxx/tree/date-time-extraction.txx157
-rw-r--r--libxsd/xsd/cxx/tree/date-time-insertion.txx188
-rw-r--r--libxsd/xsd/cxx/tree/date-time-ostream.txx324
-rw-r--r--libxsd/xsd/cxx/tree/date-time.hxx1951
-rw-r--r--libxsd/xsd/cxx/tree/date-time.ixx893
-rw-r--r--libxsd/xsd/cxx/tree/date-time.txx94
-rw-r--r--libxsd/xsd/cxx/tree/element-map.hxx146
-rw-r--r--libxsd/xsd/cxx/tree/element-map.txx71
-rw-r--r--libxsd/xsd/cxx/tree/elements.hxx1448
-rw-r--r--libxsd/xsd/cxx/tree/elements.txx57
-rw-r--r--libxsd/xsd/cxx/tree/error-handler.hxx62
-rw-r--r--libxsd/xsd/cxx/tree/error-handler.txx34
-rw-r--r--libxsd/xsd/cxx/tree/exceptions.hxx1036
-rw-r--r--libxsd/xsd/cxx/tree/exceptions.ixx467
-rw-r--r--libxsd/xsd/cxx/tree/exceptions.txx338
-rw-r--r--libxsd/xsd/cxx/tree/facet.hxx43
-rw-r--r--libxsd/xsd/cxx/tree/istream-fwd.hxx21
-rw-r--r--libxsd/xsd/cxx/tree/istream.hxx258
-rw-r--r--libxsd/xsd/cxx/tree/list.hxx132
-rw-r--r--libxsd/xsd/cxx/tree/ostream.hxx245
-rw-r--r--libxsd/xsd/cxx/tree/parsing.hxx12
-rw-r--r--libxsd/xsd/cxx/tree/parsing.txx915
-rw-r--r--libxsd/xsd/cxx/tree/parsing/boolean.hxx76
-rw-r--r--libxsd/xsd/cxx/tree/parsing/byte.hxx80
-rw-r--r--libxsd/xsd/cxx/tree/parsing/date-time.txx702
-rw-r--r--libxsd/xsd/cxx/tree/parsing/decimal.hxx85
-rw-r--r--libxsd/xsd/cxx/tree/parsing/double.hxx94
-rw-r--r--libxsd/xsd/cxx/tree/parsing/element-map.txx42
-rw-r--r--libxsd/xsd/cxx/tree/parsing/float.hxx94
-rw-r--r--libxsd/xsd/cxx/tree/parsing/int.hxx80
-rw-r--r--libxsd/xsd/cxx/tree/parsing/long.hxx80
-rw-r--r--libxsd/xsd/cxx/tree/parsing/short.hxx80
-rw-r--r--libxsd/xsd/cxx/tree/parsing/unsigned-byte.hxx80
-rw-r--r--libxsd/xsd/cxx/tree/parsing/unsigned-int.hxx80
-rw-r--r--libxsd/xsd/cxx/tree/parsing/unsigned-long.hxx80
-rw-r--r--libxsd/xsd/cxx/tree/parsing/unsigned-short.hxx80
-rw-r--r--libxsd/xsd/cxx/tree/serialization.hxx66
-rw-r--r--libxsd/xsd/cxx/tree/serialization.txx762
-rw-r--r--libxsd/xsd/cxx/tree/serialization/boolean.hxx52
-rw-r--r--libxsd/xsd/cxx/tree/serialization/byte.hxx46
-rw-r--r--libxsd/xsd/cxx/tree/serialization/date-time.txx620
-rw-r--r--libxsd/xsd/cxx/tree/serialization/decimal.hxx126
-rw-r--r--libxsd/xsd/cxx/tree/serialization/double.hxx96
-rw-r--r--libxsd/xsd/cxx/tree/serialization/element-map.txx40
-rw-r--r--libxsd/xsd/cxx/tree/serialization/float.hxx94
-rw-r--r--libxsd/xsd/cxx/tree/serialization/int.hxx46
-rw-r--r--libxsd/xsd/cxx/tree/serialization/long.hxx46
-rw-r--r--libxsd/xsd/cxx/tree/serialization/short.hxx46
-rw-r--r--libxsd/xsd/cxx/tree/serialization/unsigned-byte.hxx46
-rw-r--r--libxsd/xsd/cxx/tree/serialization/unsigned-int.hxx46
-rw-r--r--libxsd/xsd/cxx/tree/serialization/unsigned-long.hxx46
-rw-r--r--libxsd/xsd/cxx/tree/serialization/unsigned-short.hxx46
-rw-r--r--libxsd/xsd/cxx/tree/std-ostream-map.hxx110
-rw-r--r--libxsd/xsd/cxx/tree/std-ostream-map.txx279
-rw-r--r--libxsd/xsd/cxx/tree/std-ostream-operators.hxx274
-rw-r--r--libxsd/xsd/cxx/tree/stream-extraction-map.hxx97
-rw-r--r--libxsd/xsd/cxx/tree/stream-extraction-map.txx294
-rw-r--r--libxsd/xsd/cxx/tree/stream-extraction.hxx303
-rw-r--r--libxsd/xsd/cxx/tree/stream-insertion-map.hxx150
-rw-r--r--libxsd/xsd/cxx/tree/stream-insertion-map.txx325
-rw-r--r--libxsd/xsd/cxx/tree/stream-insertion.hxx273
-rw-r--r--libxsd/xsd/cxx/tree/text.hxx30
-rw-r--r--libxsd/xsd/cxx/tree/text.txx77
-rw-r--r--libxsd/xsd/cxx/tree/type-factory-map.hxx151
-rw-r--r--libxsd/xsd/cxx/tree/type-factory-map.txx436
-rw-r--r--libxsd/xsd/cxx/tree/type-serializer-map.hxx217
-rw-r--r--libxsd/xsd/cxx/tree/type-serializer-map.txx539
-rw-r--r--libxsd/xsd/cxx/tree/types.hxx3788
-rw-r--r--libxsd/xsd/cxx/tree/types.txx610
-rw-r--r--libxsd/xsd/cxx/tree/xdr-stream-common.hxx26
-rw-r--r--libxsd/xsd/cxx/tree/xdr-stream-extraction.hxx295
-rw-r--r--libxsd/xsd/cxx/tree/xdr-stream-insertion.hxx259
-rw-r--r--libxsd/xsd/cxx/version.hxx29
-rw-r--r--libxsd/xsd/cxx/xml/bits/literals.hxx83
-rw-r--r--libxsd/xsd/cxx/xml/bits/literals.ixx261
-rw-r--r--libxsd/xsd/cxx/xml/dom/auto-ptr.hxx158
-rw-r--r--libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.hxx61
-rw-r--r--libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.txx80
-rw-r--r--libxsd/xsd/cxx/xml/dom/elements.hxx36
-rw-r--r--libxsd/xsd/cxx/xml/dom/elements.txx57
-rw-r--r--libxsd/xsd/cxx/xml/dom/parsing-header.hxx24
-rw-r--r--libxsd/xsd/cxx/xml/dom/parsing-source.hxx138
-rw-r--r--libxsd/xsd/cxx/xml/dom/parsing-source.txx458
-rw-r--r--libxsd/xsd/cxx/xml/dom/serialization-header.hxx81
-rw-r--r--libxsd/xsd/cxx/xml/dom/serialization-header.txx192
-rw-r--r--libxsd/xsd/cxx/xml/dom/serialization-source.hxx152
-rw-r--r--libxsd/xsd/cxx/xml/dom/serialization-source.txx394
-rw-r--r--libxsd/xsd/cxx/xml/dom/wildcard-source.hxx31
-rw-r--r--libxsd/xsd/cxx/xml/dom/wildcard-source.txx39
-rw-r--r--libxsd/xsd/cxx/xml/elements.hxx113
-rw-r--r--libxsd/xsd/cxx/xml/elements.txx73
-rw-r--r--libxsd/xsd/cxx/xml/error-handler.hxx60
-rw-r--r--libxsd/xsd/cxx/xml/qualified-name.hxx84
-rw-r--r--libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.hxx81
-rw-r--r--libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.txx89
-rw-r--r--libxsd/xsd/cxx/xml/sax/std-input-source.hxx174
-rw-r--r--libxsd/xsd/cxx/xml/std-memory-manager.hxx50
-rw-r--r--libxsd/xsd/cxx/xml/string.hxx90
-rw-r--r--libxsd/xsd/cxx/xml/string.ixx225
-rw-r--r--libxsd/xsd/cxx/xml/string.txx441
-rw-r--r--libxsd/xsd/cxx/zc-istream.hxx92
-rw-r--r--libxsd/xsd/cxx/zc-istream.txx94
-rw-r--r--makefile41
-rw-r--r--tests/clash/clash.xsd25
-rw-r--r--tests/clash/foo.xsd11
-rw-r--r--tests/code/name-conflict/test.xsd40
-rw-r--r--tests/code/name-escaping/test.xsd60
-rw-r--r--tests/cxx/makefile19
-rw-r--r--tests/cxx/parser/built-in/driver.cxx531
-rw-r--r--tests/cxx/parser/built-in/makefile75
-rw-r--r--tests/cxx/parser/built-in/output164
-rw-r--r--tests/cxx/parser/built-in/test.xml199
-rw-r--r--tests/cxx/parser/built-in/test.xsd63
-rw-r--r--tests/cxx/parser/enumeration/driver.cxx83
-rw-r--r--tests/cxx/parser/enumeration/gender.hxx15
-rw-r--r--tests/cxx/parser/enumeration/makefile75
-rw-r--r--tests/cxx/parser/enumeration/output3
-rw-r--r--tests/cxx/parser/enumeration/test.map7
-rw-r--r--tests/cxx/parser/enumeration/test.xml10
-rw-r--r--tests/cxx/parser/enumeration/test.xsd35
-rw-r--r--tests/cxx/parser/generated-impl/makefile81
-rw-r--r--tests/cxx/parser/generated-impl/output122
-rw-r--r--tests/cxx/parser/generated-impl/test.xml168
-rw-r--r--tests/cxx/parser/generated-impl/test.xsd142
-rw-r--r--tests/cxx/parser/list/driver.cxx107
-rw-r--r--tests/cxx/parser/list/makefile74
-rw-r--r--tests/cxx/parser/list/output26
-rw-r--r--tests/cxx/parser/list/test.xml25
-rw-r--r--tests/cxx/parser/list/test.xsd25
-rw-r--r--tests/cxx/parser/makefile24
-rw-r--r--tests/cxx/parser/name-clash/inheritance/driver.cxx64
-rw-r--r--tests/cxx/parser/name-clash/inheritance/makefile75
-rw-r--r--tests/cxx/parser/name-clash/inheritance/output2
-rw-r--r--tests/cxx/parser/name-clash/inheritance/test.xml8
-rw-r--r--tests/cxx/parser/name-clash/inheritance/test.xsd22
-rw-r--r--tests/cxx/parser/polymorphism/makefile22
-rw-r--r--tests/cxx/parser/polymorphism/same-type/driver.cxx64
-rw-r--r--tests/cxx/parser/polymorphism/same-type/makefile75
-rw-r--r--tests/cxx/parser/polymorphism/same-type/output4
-rw-r--r--tests/cxx/parser/polymorphism/same-type/test.xml10
-rw-r--r--tests/cxx/parser/polymorphism/same-type/test.xsd21
-rw-r--r--tests/cxx/parser/recursive/driver.cxx141
-rw-r--r--tests/cxx/parser/recursive/makefile75
-rw-r--r--tests/cxx/parser/recursive/output22
-rw-r--r--tests/cxx/parser/recursive/test.xml11
-rw-r--r--tests/cxx/parser/recursive/test.xsd27
-rw-r--r--tests/cxx/parser/test-template/driver.cxx68
-rw-r--r--tests/cxx/parser/test-template/makefile74
-rw-r--r--tests/cxx/parser/test-template/output1
-rw-r--r--tests/cxx/parser/test-template/test.xml7
-rw-r--r--tests/cxx/parser/test-template/test.xsd12
-rw-r--r--tests/cxx/parser/union/driver.cxx62
-rw-r--r--tests/cxx/parser/union/makefile74
-rw-r--r--tests/cxx/parser/union/output2
-rw-r--r--tests/cxx/parser/union/test.xml10
-rw-r--r--tests/cxx/parser/union/test.xsd16
-rw-r--r--tests/cxx/parser/validation/all/driver.cxx100
-rw-r--r--tests/cxx/parser/validation/all/makefile85
-rw-r--r--tests/cxx/parser/validation/all/test-000.std46
-rw-r--r--tests/cxx/parser/validation/all/test-000.xml53
-rw-r--r--tests/cxx/parser/validation/all/test-001.std6
-rw-r--r--tests/cxx/parser/validation/all/test-001.xml11
-rw-r--r--tests/cxx/parser/validation/all/test-002.std4
-rw-r--r--tests/cxx/parser/validation/all/test-002.xml9
-rw-r--r--tests/cxx/parser/validation/all/test-003.std6
-rw-r--r--tests/cxx/parser/validation/all/test-003.xml12
-rw-r--r--tests/cxx/parser/validation/all/test.xsd20
-rw-r--r--tests/cxx/parser/validation/any/driver.cxx123
-rw-r--r--tests/cxx/parser/validation/any/makefile85
-rw-r--r--tests/cxx/parser/validation/any/test-000.std29
-rw-r--r--tests/cxx/parser/validation/any/test-000.xml21
-rw-r--r--tests/cxx/parser/validation/any/test.xsd20
-rw-r--r--tests/cxx/parser/validation/attribute/driver.cxx199
-rw-r--r--tests/cxx/parser/validation/attribute/makefile85
-rw-r--r--tests/cxx/parser/validation/attribute/test-000.std24
-rw-r--r--tests/cxx/parser/validation/attribute/test-000.xml10
-rw-r--r--tests/cxx/parser/validation/attribute/test.xsd71
-rw-r--r--tests/cxx/parser/validation/built-in/any-type/driver.cxx156
-rw-r--r--tests/cxx/parser/validation/built-in/any-type/makefile85
-rw-r--r--tests/cxx/parser/validation/built-in/any-type/test-000.std99
-rw-r--r--tests/cxx/parser/validation/built-in/any-type/test-000.xml41
-rw-r--r--tests/cxx/parser/validation/built-in/any-type/test.xsd31
-rw-r--r--tests/cxx/parser/validation/built-in/binary/driver.cxx155
-rw-r--r--tests/cxx/parser/validation/built-in/binary/makefile60
-rw-r--r--tests/cxx/parser/validation/built-in/boolean/driver.cxx147
-rw-r--r--tests/cxx/parser/validation/built-in/boolean/makefile60
-rw-r--r--tests/cxx/parser/validation/built-in/byte/driver.cxx258
-rw-r--r--tests/cxx/parser/validation/built-in/byte/makefile60
-rw-r--r--tests/cxx/parser/validation/built-in/date-time/driver.cxx1535
-rw-r--r--tests/cxx/parser/validation/built-in/date-time/makefile60
-rw-r--r--tests/cxx/parser/validation/built-in/float/driver.cxx287
-rw-r--r--tests/cxx/parser/validation/built-in/float/makefile60
-rw-r--r--tests/cxx/parser/validation/built-in/int/driver.cxx118
-rw-r--r--tests/cxx/parser/validation/built-in/int/makefile60
-rw-r--r--tests/cxx/parser/validation/built-in/integer/driver.cxx305
-rw-r--r--tests/cxx/parser/validation/built-in/integer/makefile60
-rw-r--r--tests/cxx/parser/validation/built-in/long/driver.cxx118
-rw-r--r--tests/cxx/parser/validation/built-in/long/makefile60
-rw-r--r--tests/cxx/parser/validation/built-in/makefile21
-rw-r--r--tests/cxx/parser/validation/built-in/qname/driver.cxx107
-rw-r--r--tests/cxx/parser/validation/built-in/qname/makefile60
-rw-r--r--tests/cxx/parser/validation/built-in/short/driver.cxx118
-rw-r--r--tests/cxx/parser/validation/built-in/short/makefile60
-rw-r--r--tests/cxx/parser/validation/built-in/string/driver.cxx514
-rw-r--r--tests/cxx/parser/validation/built-in/string/makefile60
-rw-r--r--tests/cxx/parser/validation/built-in/uri/driver.cxx55
-rw-r--r--tests/cxx/parser/validation/built-in/uri/makefile60
-rw-r--r--tests/cxx/parser/validation/choice/driver.cxx128
-rw-r--r--tests/cxx/parser/validation/choice/makefile85
-rw-r--r--tests/cxx/parser/validation/choice/test-000.std22
-rw-r--r--tests/cxx/parser/validation/choice/test-000.xml30
-rw-r--r--tests/cxx/parser/validation/choice/test-001.std4
-rw-r--r--tests/cxx/parser/validation/choice/test-001.xml10
-rw-r--r--tests/cxx/parser/validation/choice/test-002.std11
-rw-r--r--tests/cxx/parser/validation/choice/test-002.xml17
-rw-r--r--tests/cxx/parser/validation/choice/test-003.std5
-rw-r--r--tests/cxx/parser/validation/choice/test-003.xml11
-rw-r--r--tests/cxx/parser/validation/choice/test-004.std4
-rw-r--r--tests/cxx/parser/validation/choice/test-004.xml11
-rw-r--r--tests/cxx/parser/validation/choice/test.xsd24
-rw-r--r--tests/cxx/parser/validation/makefile22
-rw-r--r--tests/cxx/parser/validation/restriction/driver.cxx109
-rw-r--r--tests/cxx/parser/validation/restriction/makefile85
-rw-r--r--tests/cxx/parser/validation/restriction/test-000.std0
-rw-r--r--tests/cxx/parser/validation/restriction/test-000.xml31
-rw-r--r--tests/cxx/parser/validation/restriction/test-001.std1
-rw-r--r--tests/cxx/parser/validation/restriction/test-001.xml11
-rw-r--r--tests/cxx/parser/validation/restriction/test-002.std1
-rw-r--r--tests/cxx/parser/validation/restriction/test-002.xml12
-rw-r--r--tests/cxx/parser/validation/restriction/test-003.std1
-rw-r--r--tests/cxx/parser/validation/restriction/test-003.xml16
-rw-r--r--tests/cxx/parser/validation/restriction/test-004.std1
-rw-r--r--tests/cxx/parser/validation/restriction/test-004.xml10
-rw-r--r--tests/cxx/parser/validation/restriction/test-005.std1
-rw-r--r--tests/cxx/parser/validation/restriction/test-005.xml11
-rw-r--r--tests/cxx/parser/validation/restriction/test.xsd82
-rw-r--r--tests/cxx/parser/validation/sequence/driver.cxx141
-rw-r--r--tests/cxx/parser/validation/sequence/makefile85
-rw-r--r--tests/cxx/parser/validation/sequence/test-000.std56
-rw-r--r--tests/cxx/parser/validation/sequence/test-000.xml46
-rw-r--r--tests/cxx/parser/validation/sequence/test-001.std4
-rw-r--r--tests/cxx/parser/validation/sequence/test-001.xml10
-rw-r--r--tests/cxx/parser/validation/sequence/test-002.std20
-rw-r--r--tests/cxx/parser/validation/sequence/test-002.xml27
-rw-r--r--tests/cxx/parser/validation/sequence/test-003.std5
-rw-r--r--tests/cxx/parser/validation/sequence/test-003.xml17
-rw-r--r--tests/cxx/parser/validation/sequence/test-004.std4
-rw-r--r--tests/cxx/parser/validation/sequence/test-004.xml14
-rw-r--r--tests/cxx/parser/validation/sequence/test-005.std6
-rw-r--r--tests/cxx/parser/validation/sequence/test-005.xml15
-rw-r--r--tests/cxx/parser/validation/sequence/test-006.std13
-rw-r--r--tests/cxx/parser/validation/sequence/test-006.xml17
-rw-r--r--tests/cxx/parser/validation/sequence/test.xsd28
-rw-r--r--tests/cxx/tree/binary/cdr/driver.cxx137
-rw-r--r--tests/cxx/tree/binary/cdr/makefile86
-rw-r--r--tests/cxx/tree/binary/cdr/test.xml91
-rw-r--r--tests/cxx/tree/binary/cdr/test.xsd120
-rw-r--r--tests/cxx/tree/binary/makefile20
-rw-r--r--tests/cxx/tree/binary/polymorphic/driver.cxx151
-rw-r--r--tests/cxx/tree/binary/polymorphic/makefile87
-rw-r--r--tests/cxx/tree/binary/polymorphic/test.xml92
-rw-r--r--tests/cxx/tree/binary/polymorphic/test.xsd125
-rw-r--r--tests/cxx/tree/binary/xdr/driver.cxx181
-rw-r--r--tests/cxx/tree/binary/xdr/makefile81
-rw-r--r--tests/cxx/tree/binary/xdr/test.xml91
-rw-r--r--tests/cxx/tree/binary/xdr/test.xsd120
-rw-r--r--tests/cxx/tree/built-in/attributes.xml73
-rw-r--r--tests/cxx/tree/built-in/driver.cxx94
-rw-r--r--tests/cxx/tree/built-in/elements.xml84
-rw-r--r--tests/cxx/tree/built-in/inherited.xml84
-rw-r--r--tests/cxx/tree/built-in/makefile93
-rw-r--r--tests/cxx/tree/built-in/types.xsd460
-rw-r--r--tests/cxx/tree/chameleon/driver.cxx37
-rw-r--r--tests/cxx/tree/chameleon/includee.xsd13
-rw-r--r--tests/cxx/tree/chameleon/includer.xsd12
-rw-r--r--tests/cxx/tree/chameleon/makefile82
-rw-r--r--tests/cxx/tree/chameleon/output3
-rw-r--r--tests/cxx/tree/chameleon/test.xml8
-rw-r--r--tests/cxx/tree/comparison/driver.cxx40
-rw-r--r--tests/cxx/tree/comparison/makefile81
-rw-r--r--tests/cxx/tree/comparison/test.xml19
-rw-r--r--tests/cxx/tree/comparison/test.xsd30
-rw-r--r--tests/cxx/tree/compilation/driver.cxx119
-rw-r--r--tests/cxx/tree/compilation/makefile81
-rw-r--r--tests/cxx/tree/compilation/test.xsd12
-rw-r--r--tests/cxx/tree/complex/ctor/driver.cxx112
-rw-r--r--tests/cxx/tree/complex/ctor/makefile83
-rw-r--r--tests/cxx/tree/complex/ctor/test.xsd182
-rw-r--r--tests/cxx/tree/complex/makefile20
-rw-r--r--tests/cxx/tree/containment/driver.cxx77
-rw-r--r--tests/cxx/tree/containment/makefile81
-rw-r--r--tests/cxx/tree/containment/test.xsd27
-rw-r--r--tests/cxx/tree/default/driver.cxx48
-rw-r--r--tests/cxx/tree/default/makefile83
-rw-r--r--tests/cxx/tree/default/output26
-rw-r--r--tests/cxx/tree/default/test.xml11
-rw-r--r--tests/cxx/tree/default/test.xsd39
-rw-r--r--tests/cxx/tree/encoding/char/lcp/driver.cxx42
-rw-r--r--tests/cxx/tree/encoding/char/lcp/makefile81
-rw-r--r--tests/cxx/tree/encoding/char/lcp/test.std6
-rw-r--r--tests/cxx/tree/encoding/char/lcp/test.xml7
-rw-r--r--tests/cxx/tree/encoding/char/lcp/test.xsd12
-rw-r--r--tests/cxx/tree/encoding/char/makefile22
-rw-r--r--tests/cxx/tree/encoding/char/utf-8/driver.cxx67
-rw-r--r--tests/cxx/tree/encoding/char/utf-8/makefile82
-rw-r--r--tests/cxx/tree/encoding/char/utf-8/test.stdbin0 -> 796 bytes
-rw-r--r--tests/cxx/tree/encoding/char/utf-8/test.xml15
-rw-r--r--tests/cxx/tree/encoding/char/utf-8/test.xsd33
-rw-r--r--tests/cxx/tree/encoding/makefile22
-rw-r--r--tests/cxx/tree/encoding/wchar/driver.cxx57
-rw-r--r--tests/cxx/tree/encoding/wchar/makefile82
-rw-r--r--tests/cxx/tree/encoding/wchar/test.stdbin0 -> 768 bytes
-rw-r--r--tests/cxx/tree/encoding/wchar/test.xml14
-rw-r--r--tests/cxx/tree/encoding/wchar/test.xsd33
-rw-r--r--tests/cxx/tree/enumeration/ctor/driver.cxx32
-rw-r--r--tests/cxx/tree/enumeration/ctor/makefile82
-rw-r--r--tests/cxx/tree/enumeration/ctor/test.xsd41
-rw-r--r--tests/cxx/tree/enumeration/inheritance/driver.cxx49
-rw-r--r--tests/cxx/tree/enumeration/inheritance/makefile81
-rw-r--r--tests/cxx/tree/enumeration/inheritance/output1
-rw-r--r--tests/cxx/tree/enumeration/inheritance/test.xml3
-rw-r--r--tests/cxx/tree/enumeration/inheritance/test.xsd22
-rw-r--r--tests/cxx/tree/enumeration/makefile20
-rw-r--r--tests/cxx/tree/float/driver.cxx55
-rw-r--r--tests/cxx/tree/float/makefile81
-rw-r--r--tests/cxx/tree/float/test.std68
-rw-r--r--tests/cxx/tree/float/test.xml35
-rw-r--r--tests/cxx/tree/float/test.xsd74
-rw-r--r--tests/cxx/tree/list/ctor/driver.cxx52
-rw-r--r--tests/cxx/tree/list/ctor/makefile82
-rw-r--r--tests/cxx/tree/list/ctor/test.xsd18
-rw-r--r--tests/cxx/tree/list/makefile20
-rw-r--r--tests/cxx/tree/makefile43
-rw-r--r--tests/cxx/tree/name-clash/inheritance/driver.cxx37
-rw-r--r--tests/cxx/tree/name-clash/inheritance/makefile81
-rw-r--r--tests/cxx/tree/name-clash/inheritance/output3
-rw-r--r--tests/cxx/tree/name-clash/inheritance/test.xml8
-rw-r--r--tests/cxx/tree/name-clash/inheritance/test.xsd53
-rw-r--r--tests/cxx/tree/name-clash/makefile20
-rw-r--r--tests/cxx/tree/naming/camel/driver.cxx145
-rw-r--r--tests/cxx/tree/naming/camel/makefile87
-rw-r--r--tests/cxx/tree/naming/camel/test.xsd31
-rw-r--r--tests/cxx/tree/naming/java/driver.cxx145
-rw-r--r--tests/cxx/tree/naming/java/makefile87
-rw-r--r--tests/cxx/tree/naming/java/test.xsd31
-rw-r--r--tests/cxx/tree/naming/knr/driver.cxx145
-rw-r--r--tests/cxx/tree/naming/knr/makefile87
-rw-r--r--tests/cxx/tree/naming/knr/test.xsd31
-rw-r--r--tests/cxx/tree/naming/makefile20
-rw-r--r--tests/cxx/tree/polymorphism/comparison/driver.cxx75
-rw-r--r--tests/cxx/tree/polymorphism/comparison/makefile82
-rw-r--r--tests/cxx/tree/polymorphism/comparison/test.xml7
-rw-r--r--tests/cxx/tree/polymorphism/comparison/test.xsd39
-rw-r--r--tests/cxx/tree/polymorphism/makefile20
-rw-r--r--tests/cxx/tree/polymorphism/ostream/driver.cxx36
-rw-r--r--tests/cxx/tree/polymorphism/ostream/makefile83
-rw-r--r--tests/cxx/tree/polymorphism/ostream/output13
-rw-r--r--tests/cxx/tree/polymorphism/ostream/test.xml9
-rw-r--r--tests/cxx/tree/polymorphism/ostream/test.xsd39
-rw-r--r--tests/cxx/tree/polymorphism/same-type/driver.cxx37
-rw-r--r--tests/cxx/tree/polymorphism/same-type/makefile82
-rw-r--r--tests/cxx/tree/polymorphism/same-type/output9
-rw-r--r--tests/cxx/tree/polymorphism/same-type/test.xml10
-rw-r--r--tests/cxx/tree/polymorphism/same-type/test.xsd21
-rw-r--r--tests/cxx/tree/prefix/bar.xsd34
-rw-r--r--tests/cxx/tree/prefix/driver.cxx36
-rw-r--r--tests/cxx/tree/prefix/foo.xsd16
-rw-r--r--tests/cxx/tree/prefix/makefile76
-rw-r--r--tests/cxx/tree/prefix/output22
-rw-r--r--tests/cxx/tree/prefix/test.xml19
-rw-r--r--tests/cxx/tree/prefix/test.xsd40
-rw-r--r--tests/cxx/tree/test-template/driver.cxx37
-rw-r--r--tests/cxx/tree/test-template/makefile81
-rw-r--r--tests/cxx/tree/test-template/output2
-rw-r--r--tests/cxx/tree/test-template/test.xml7
-rw-r--r--tests/cxx/tree/test-template/test.xsd12
-rw-r--r--tests/cxx/tree/types-only/driver.cxx33
-rw-r--r--tests/cxx/tree/types-only/makefile81
-rw-r--r--tests/cxx/tree/types-only/test.xsd52
-rw-r--r--tests/cxx/tree/union/ctor/driver.cxx32
-rw-r--r--tests/cxx/tree/union/ctor/makefile82
-rw-r--r--tests/cxx/tree/union/ctor/test.xsd14
-rw-r--r--tests/cxx/tree/union/makefile20
-rw-r--r--tests/cxx/tree/wildcard/driver.cxx202
-rw-r--r--tests/cxx/tree/wildcard/makefile83
-rw-r--r--tests/cxx/tree/wildcard/output24
-rw-r--r--tests/cxx/tree/wildcard/test.xml19
-rw-r--r--tests/cxx/tree/wildcard/test.xsd18
-rw-r--r--tests/failed/test-00.xsd12
-rw-r--r--tests/makefile18
-rw-r--r--tests/morphing/anonymous/attribute-group/test.xsd31
-rw-r--r--tests/morphing/anonymous/cyclic-inclusion/includee.xsd18
-rw-r--r--tests/morphing/anonymous/cyclic-inclusion/includer.xsd18
-rw-r--r--tests/morphing/anonymous/group/test.xsd29
-rw-r--r--tests/morphing/anonymous/test-000.xsd20
-rw-r--r--tests/morphing/anonymous/unstable/includee-1.xsd12
-rw-r--r--tests/morphing/anonymous/unstable/includee-2.xsd14
-rw-r--r--tests/morphing/anonymous/unstable/includer.xsd18
-rw-r--r--tests/processing/inheritance/test-000.xsd22
-rw-r--r--tests/processing/inheritance/test-001.xsd26
-rw-r--r--tests/schema/anonymous/test.xsd143
-rw-r--r--tests/schema/any-attribute/test.xsd22
-rw-r--r--tests/schema/any-type/test.xsd22
-rw-r--r--tests/schema/any/fail.xsd19
-rw-r--r--tests/schema/any/test.xsd19
-rw-r--r--tests/schema/attribute-group/global.xsd50
-rw-r--r--tests/schema/attribute/global.xsd21
-rw-r--r--tests/schema/attribute/local.xsd37
-rw-r--r--tests/schema/attribute/ref.xsd42
-rw-r--r--tests/schema/cardinality/test.xsd46
-rw-r--r--tests/schema/chameleon/includer.xsd17
-rw-r--r--tests/schema/chameleon/schemas/includee.xsd12
-rw-r--r--tests/schema/enumeration/test.xsd89
-rw-r--r--tests/schema/forward/test.xsd32
-rw-r--r--tests/schema/group/global.xsd39
-rw-r--r--tests/schema/group/test.xsd148
-rw-r--r--tests/schema/import/importer.xsd20
-rw-r--r--tests/schema/import/schemas/importee.xsd15
-rw-r--r--tests/schema/include/includer.xsd17
-rw-r--r--tests/schema/include/schemas/includee.xsd14
-rw-r--r--tests/schema/inheritance/cycle.xsd34
-rw-r--r--tests/schema/inheritance/sourced-forward/includee.xsd10
-rw-r--r--tests/schema/inheritance/sourced-forward/includer.xsd14
-rw-r--r--tests/schema/list/anonymous/test.xsd16
-rw-r--r--tests/schema/list/any-simple-type/test.xsd12
-rw-r--r--tests/schema/list/driver.cxx13
-rw-r--r--tests/schema/list/test.xsd72
-rw-r--r--tests/schema/no-namespace/test.xsd15
-rw-r--r--tests/schema/recursive/test.xsd43
-rw-r--r--tests/schema/ref-type/idref.xsd42
-rw-r--r--tests/schema/ref-type/idrefs.xsd43
-rw-r--r--tests/schema/ref-type/invalid-0.xsd17
-rw-r--r--tests/schema/ref-type/invalid-1.xsd11
-rw-r--r--tests/schema/restriction/test.xsd67
-rw-r--r--tests/schema/union/test.xsd65
-rw-r--r--version1
-rw-r--r--xsd/cxx/elements.cxx1020
-rw-r--r--xsd/cxx/elements.hxx577
-rw-r--r--xsd/cxx/parser/attribute-validation-source.cxx410
-rw-r--r--xsd/cxx/parser/attribute-validation-source.hxx22
-rw-r--r--xsd/cxx/parser/characters-validation-source.cxx77
-rw-r--r--xsd/cxx/parser/characters-validation-source.hxx22
-rw-r--r--xsd/cxx/parser/cli.hxx152
-rw-r--r--xsd/cxx/parser/driver-source.cxx768
-rw-r--r--xsd/cxx/parser/driver-source.hxx22
-rw-r--r--xsd/cxx/parser/element-validation-source.cxx1587
-rw-r--r--xsd/cxx/parser/element-validation-source.hxx22
-rw-r--r--xsd/cxx/parser/elements.cxx262
-rw-r--r--xsd/cxx/parser/elements.hxx312
-rw-r--r--xsd/cxx/parser/generator.cxx1450
-rw-r--r--xsd/cxx/parser/generator.hxx55
-rw-r--r--xsd/cxx/parser/impl-header.cxx237
-rw-r--r--xsd/cxx/parser/impl-header.hxx22
-rw-r--r--xsd/cxx/parser/impl-source.cxx389
-rw-r--r--xsd/cxx/parser/impl-source.hxx22
-rw-r--r--xsd/cxx/parser/name-processor.cxx1205
-rw-r--r--xsd/cxx/parser/name-processor.hxx34
-rw-r--r--xsd/cxx/parser/parser-forward.cxx115
-rw-r--r--xsd/cxx/parser/parser-forward.hxx22
-rw-r--r--xsd/cxx/parser/parser-header.cxx1440
-rw-r--r--xsd/cxx/parser/parser-header.hxx22
-rw-r--r--xsd/cxx/parser/parser-inline.cxx407
-rw-r--r--xsd/cxx/parser/parser-inline.hxx22
-rw-r--r--xsd/cxx/parser/parser-source.cxx924
-rw-r--r--xsd/cxx/parser/parser-source.hxx22
-rw-r--r--xsd/cxx/parser/print-impl-common.hxx643
-rw-r--r--xsd/cxx/parser/state-processor.cxx318
-rw-r--r--xsd/cxx/parser/state-processor.hxx28
-rw-r--r--xsd/cxx/parser/type-processor.cxx352
-rw-r--r--xsd/cxx/parser/type-processor.hxx37
-rw-r--r--xsd/cxx/parser/validator.cxx714
-rw-r--r--xsd/cxx/parser/validator.hxx35
-rw-r--r--xsd/cxx/tree/cli.hxx220
-rw-r--r--xsd/cxx/tree/counter.cxx265
-rw-r--r--xsd/cxx/tree/counter.hxx28
-rw-r--r--xsd/cxx/tree/elements.cxx1327
-rw-r--r--xsd/cxx/tree/elements.hxx2030
-rw-r--r--xsd/cxx/tree/fundamental-header.hxx1186
-rw-r--r--xsd/cxx/tree/generator.cxx1689
-rw-r--r--xsd/cxx/tree/generator.hxx49
-rw-r--r--xsd/cxx/tree/name-processor.cxx2100
-rw-r--r--xsd/cxx/tree/name-processor.hxx34
-rw-r--r--xsd/cxx/tree/parser-header.cxx474
-rw-r--r--xsd/cxx/tree/parser-header.hxx23
-rw-r--r--xsd/cxx/tree/parser-source.cxx544
-rw-r--r--xsd/cxx/tree/parser-source.hxx24
-rw-r--r--xsd/cxx/tree/serialization-header.cxx581
-rw-r--r--xsd/cxx/tree/serialization-header.hxx22
-rw-r--r--xsd/cxx/tree/serialization-source.cxx1342
-rw-r--r--xsd/cxx/tree/serialization-source.hxx24
-rw-r--r--xsd/cxx/tree/stream-extraction-source.cxx754
-rw-r--r--xsd/cxx/tree/stream-extraction-source.hxx22
-rw-r--r--xsd/cxx/tree/stream-header.cxx183
-rw-r--r--xsd/cxx/tree/stream-header.hxx22
-rw-r--r--xsd/cxx/tree/stream-insertion-header.cxx178
-rw-r--r--xsd/cxx/tree/stream-insertion-header.hxx22
-rw-r--r--xsd/cxx/tree/stream-insertion-source.cxx532
-rw-r--r--xsd/cxx/tree/stream-insertion-source.hxx22
-rw-r--r--xsd/cxx/tree/stream-source.cxx489
-rw-r--r--xsd/cxx/tree/stream-source.hxx24
-rw-r--r--xsd/cxx/tree/tree-forward.cxx324
-rw-r--r--xsd/cxx/tree/tree-forward.hxx22
-rw-r--r--xsd/cxx/tree/tree-header.cxx3778
-rw-r--r--xsd/cxx/tree/tree-header.hxx22
-rw-r--r--xsd/cxx/tree/tree-inline.cxx1025
-rw-r--r--xsd/cxx/tree/tree-inline.hxx22
-rw-r--r--xsd/cxx/tree/tree-source.cxx3461
-rw-r--r--xsd/cxx/tree/tree-source.hxx24
-rw-r--r--xsd/cxx/tree/validator.cxx675
-rw-r--r--xsd/cxx/tree/validator.hxx33
-rw-r--r--xsd/elements.hxx135
-rw-r--r--xsd/makefile132
-rw-r--r--xsd/processing/cardinality/processor.cxx407
-rw-r--r--xsd/processing/cardinality/processor.hxx32
-rw-r--r--xsd/processing/inheritance/processor.cxx474
-rw-r--r--xsd/processing/inheritance/processor.hxx32
-rw-r--r--xsd/type-map/lexer.cxx133
-rw-r--r--xsd/type-map/lexer.hxx80
-rw-r--r--xsd/type-map/parser.cxx281
-rw-r--r--xsd/type-map/parser.hxx46
-rw-r--r--xsd/type-map/type-map.hxx160
-rw-r--r--xsd/usage.hxx226
-rw-r--r--xsd/xsd.cxx1219
-rw-r--r--xsd/xsd.hxx80
904 files changed, 150229 insertions, 0 deletions
diff --git a/FLOSSE b/FLOSSE
new file mode 100644
index 0000000..cbf8b2c
--- /dev/null
+++ b/FLOSSE
@@ -0,0 +1,89 @@
+1. Intent
+
+We want specified Free/Libre and Open Source Software ("FLOSS") to be
+able to use the specified GPL-licensed XSD runtime library (libxsd) and
+XSD generated code (collectively called the "Program") despite the fact
+that not all FLOSS licenses are compatible with version 2 of the GNU
+General Public License (the "GPL").
+
+It is our intent to allow distribution of the entire Derivative Work
+(including the Program) under one or more of the FLOSS licenses listed
+in section 3 (section 2.a). It is also our intent to disallow simple
+relicensing of the Program for the sole purpose of using it in
+proprietary applications (section 2.b and 2.c). As an example, consider
+two hypothetical scenarios:
+
+ a) You created a program that uses the XSD generated code and the XSD
+ runtime library to access information in XML instance documents.
+ Your program performs useful computations based on this information
+ (sections 2.b and 2.c are satisfied). You distribute your program,
+ including the XSD generated code and the XSD runtime library under
+ the BSD license and make it available at no charge to all third
+ parties (section 2.a is satisfied). Later you (or someone else) may
+ choose to base their proprietary application on your code since the
+ BSD license does not prohibit it.
+
+ This scenario falls under this FLOSS Exception.
+
+
+ b) You created a library that uses the XSD generated code and the XSD
+ runtime library to access information in XML instance documents. You
+ did not add to the library any other useful code that uses the XSD
+ generated code or the XSD runtime library (neither section 2.b nor
+ 2.c is satisfied). You distribute your library, including the XSD
+ generated code and the XSD runtime library under the BSD license and
+ make it available at no charge to all third parties (section 2.a
+ is satisfied). Later you base your proprietary application on this
+ library since the BSD license does not prohibit it.
+
+ This scenario does not fall under this FLOSS Exception (neither
+ section 2.b nor 2.c is satisfied). You created the library for the
+ sole purpose of making the XSD generated code and the XSD runtime
+ library available to your proprietary application.
+
+
+2. Legal Terms and Conditions
+
+As a special exception to the terms and conditions of version 2 of
+the GPL you are free to distribute a verbatim copy of the Program
+as part of the Derivative Work that is formed from the Program or
+any part thereof and one or more works (each, a "FLOSS Work") as
+long as you also meet all of these conditions:
+
+ a) You must cause the Derivative Work that in whole or in part
+ contains or is derived from the Program or any part thereof,
+ to be licensed as a whole at no charge to all third parties
+ under the terms of one or more of the licenses listed in
+ section 3.
+
+ b) The Derivative Work should contain one or more FLOSS Work that
+ can be reasonably considered as derived from the Program or some
+ part thereof.
+
+ c) The Derivative Work should not contain any part of the Program
+ that cannot be reasonably considered as a base of one or more
+ FLOSS Work.
+
+
+3. FLOSS License List
+
+ a) Any license listed in the "GPL-Compatible Free Software Licenses"
+ and the "GPL-Incompatible Free Software Licenses" sections of the
+ License List as published by the Free Software Foundation (FSF):
+
+ http://www.gnu.org/licenses/license-list.html
+
+
+4. Definitions
+
+Terms used, but not defined, herein shall have the meaning provided in
+the GPL.
+
+Derivative Work means a derivative work under copyright law.
+
+
+5. Applicability
+
+You may choose to redistribute a copy of the Program exclusively under
+the terms of the GPL by removing the FLOSS Exception notice from that
+copy of the Program.
diff --git a/GPLv2 b/GPLv2
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/GPLv2
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/INSTALL b/INSTALL
new file mode 100644
index 0000000..0fadd0f
--- /dev/null
+++ b/INSTALL
@@ -0,0 +1,48 @@
+Compiler Prerequisites
+
+ build-time:
+
+ - build >= 0.3.3 http://kolpackov.net/projects/build/
+ - g++ >= 3.4.3 http://gcc.gnu.org
+
+ run-time:
+
+ - libxsd-frontend >= 1.15.0 http://codesynthesis.com/projects/libxsd-frontend/
+ - libbackend-elements >= 1.6.0 http://kolpackov.net/projects/libbackend-elements/
+ - libcult >= 1.4.2 http://kolpackov.net/projects/libcult/
+ - libxerces-c >= 2.6.0 http://xerces.apache.org/xerces-c/
+ - libboost_filesystem >= 1.33.1 http://boost.org
+ - libboost_regex >= 1.33.1 http://boost.org
+
+Generated Code Prerequisites
+
+ build-time:
+
+ - libxsd (header-only XSD runtime library, part of the XSD distribution)
+
+ run-time:
+
+ - libxerces-c >= 2.5.0 (C++/Tree and C++/Parser mappings)
+ http://xerces.apache.org/xerces-c/
+
+ - libexpat >= 1.95.8 (C++/Parser mapping, alternative to libxerces-c)
+ http://www.libexpat.org
+
+
+Building XSD
+
+ To build in the source directory simply run 'make'. You can also
+ build in a separate directory, e.g.,
+
+ $ mkdir xsd-i686-pc-linux-gnu
+ $ cd xsd-i686-pc-linux-gnu
+ $ make -f ../xsd-x.y.z/makefile
+
+
+Installing XSD
+
+ To install XSD, run 'make install'. Use the install_prefix command
+ line variable to specify installation location (default is /usr/local),
+ e.g.,
+
+ $ make install_prefix=/usr install
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..42346bf
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,26 @@
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+In addition, as a special exception, Code Synthesis Tools CC gives
+permission to link this program with the Xerces-C++ library (or with
+modified versions of Xerces-C++ that use the same license as Xerces-C++),
+and distribute linked combinations including the two. You must obey
+the GNU General Public License version 2 in all respects for all of
+the code used other than Xerces-C++. If you modify this copy of the
+program, you may extend this exception to your version of the program,
+but you are not obligated to do so. If you do not wish to do so, delete
+this exception statement from your version.
+
+In addition, Code Synthesis Tools CC makes a special exception for
+the Free/Libre and Open Source Software (FLOSS) which is described
+in the accompanying FLOSSE file.
diff --git a/NEWS b/NEWS
new file mode 100644
index 0000000..60f7071
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,1048 @@
+Version 3.3.0
+
+ * When built with Xerces-C++ 3-series, enable handling of multiple
+ imports for the same namespace. Before, all subsequent imports for
+ a namespace were ignored which caused error in some schemas.
+
+ * Warning id's have changed to start with a letter identifying the
+ component issuing the warning. F - compiler frontend, D - compiler
+ driver, P - C++/Parser mapping, T - C++/Tree mapping.
+
+ C++/Tree
+
+ * New option, --generate-element-type, triggers generation of types
+ instead of parsing/serialization functions for root elements. This
+ is primarily useful to distinguish object models with the same root
+ type but with different root elements. For more information refer
+ to the messaging example and Section 2.9.1, "Element Types" in the
+ C++/Tree Mapping User Manual. To support customization of the
+ element type naming the --element-type-regex option has been added.
+ See the NAMING CONVENTION section in the compiler command line manual
+ (man pages) for details.
+
+ * New option, --generate-element-map, triggers generation of a root
+ element map. The element map allows uniform parsing and serialization
+ of multiple root elements. This option can only be used together with
+ --generate-element-type. For more information refer to the messaging
+ example and Section 2.9.2, "Element Map" in the C++/Tree Mapping
+ User Manual.
+
+ * New option, --export-xml-schema, causes the compiler to export/import
+ types in the XML Schema namespace using the export symbol provided
+ with the --export-symbol option.
+
+Version 3.2.0
+
+ * New option, --disable-warning, disables printing of a warning with
+ the specified id. Specifying 'all' for the warning id disables all
+ warnings.
+
+ * New options, --export-maps and --import-maps, provide support for
+ splitting a polymorphic type hierarchy across several Win32 DLLs.
+ See the compiler command line manual (man pages) for details.
+
+ C++/Tree
+
+ * During serialization the generated code automatically assigns
+ generic prefixes (p1, p2, etc) to XML namespaces used in the
+ vocabulary and for which no custom prefix-namespace mapping
+ was provided via the xml_schema::namespace_infomap argument.
+ The xml_schema::namespace_infomap argument in the serialization
+ functions is now default-initialized to an empty map. The
+ xml_schema::no_namespace_mapping and xml_schema::xsi_already_in_use
+ exceptions have been removed.
+
+ * New example, 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.
+
+ * New example, xpath, shows how to use the C++/Tree mapping together
+ with XPath.
+
+ * New options, --one-accessor-regex, --opt-accessor-regex,
+ --seq-accessor-regex, --one-modifier-regex, --opt-modifier-regex,
+ and --seq-modifier-regex, allow specification of transformations
+ for accessor and modifier function names for elements and attributes
+ with specific cardinalities. For more information see the NAMING
+ CONVENTION section in the compiler command line manual (man pages).
+
+ * Support for comparison (--generate-comparison) and printing
+ (--generate-ostream) of polymorphic object models.
+
+ * New serialization flag, xml_schema::flags::dont_pretty_print,
+ disables extra spaces and new lines that make the resulting XML
+ slightly bigger but easier to read.
+
+ * New example, custom/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.
+
+ * Support for fractionDigits and totalDigits facets in serialization
+ of types derived from xsd:decimal.
+
+ * New set of compile-time macros that control how the xsd:float,
+ xsd:double, and xsd:decimal types are serialized. The following
+ macros control the format:
+
+ XSD_CXX_TREE_FLOAT_FIXED
+ XSD_CXX_TREE_FLOAT_SCIENTIFIC
+ XSD_CXX_TREE_DOUBLE_FIXED
+ XSD_CXX_TREE_DOUBLE_SCIENTIFIC
+
+ The following macros control the precision:
+
+ XSD_CXX_TREE_FLOAT_PRECISION_MAX
+ XSD_CXX_TREE_FLOAT_PRECISION
+ XSD_CXX_TREE_DOUBLE_PRECISION_MAX
+ XSD_CXX_TREE_DOUBLE_PRECISION
+ XSD_CXX_TREE_DECIMAL_PRECISION_MAX
+ XSD_CXX_TREE_DECIMAL_PRECISION
+
+ If the *_PRECISION_MAX macro is defined then the maximum number of
+ potentially significant decimal digits that the type can represent
+ is used. Otherwise, if the *_PRECISION macro is defined then its
+ value is used. By default the precision is set to the number of
+ decimal digits that the type can represent without change. For
+ more information on these options, refer to the following paper:
+
+ http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf
+
+ The old macro, XSD_FP_ALL_DIGITS, that was equivalent to defining
+ all three *_PRECISION_MAX macros has been removed.
+
+ An alternative to using these macros is to customize the floating
+ point type as shown in the custom/double example.
+
+ * An additional constructor is generated in situations where a type
+ contains one or more required element of complex type (that is,
+ it itself contains elements or attributes). In this constructor,
+ initializers for such elements are passed as std::auto_ptr and the
+ newly created instance is directly initialized with and assumes
+ ownership of the pointed to objects. This constructor is a logical
+ addition to the non-copying modifiers that were introduced in the
+ previous version.
+
+ * Extra conversion operators in the fundamental_base class template
+ which is used to emulate inheritance from fundamental types are now
+ disabled by default since they cause problems on several compilers.
+ To enable them compile your code with the XSD_TREE_EXTRA_FUND_CONV
+ macro defined.
+
+ C++/Parser
+
+ * New options, --generate-xml-schema and --extern-xml-schema, trigger
+ generation of the mapping for the XML Schema namespace to a separate
+ header file and inclusion of that header into other generated header
+ files instead of generating the necessary declarations inline,
+ respectively. See the compiler command line manual (man pages) for
+ details.
+
+ * New example, performance, measures the performance of XML parsing.
+ This example also shows how to structure your code to achieve the
+ maximum performance for this operation.
+
+ * Type map files can now include comments. A comment starts with #
+ and ends with a new line or end of file. To specify a name that
+ contains # enclose it in "".
+
+ * In type map files the optional argument type now defaults to the
+ return type if the return type ends with * or & (that is, it is
+ a pointer or a reference) and 'const return type&' otherwise.
+
+ * The interface for polymorphic parsing has been simplified. Calling the
+ *_parser() functions multiple times to specify several parsers is no
+ longer supported. Instead you need to pass the xml_schema::parser_map
+ object which contains the parsers. For more information refer to
+ Section 5.4, "Support for Polymorphism" in the C++/Parser Mapping
+ Getting Started Guide.
+
+ * The use of virtual inheritance has been reduced which results in a
+ much smaller object code size (more than factor of 2 on some tests)
+ and faster C++ compilation with less RAM used.
+
+ * The low-level Expat-specific parsing API (parse_begin() and parse_end())
+ has been extended to provide XML and XML Schema error translation to
+ exceptions or error handler calls. See Section 7.2, "Expat Document
+ Parser" in the C++/Parser Mapping Getting Started Guide for more
+ information.
+
+Version 3.1.0
+
+ * New option, --file-per-type, triggers generation of a separate set
+ of C++ files for each type defined in XML Schema. This compilation
+ mode is primarily useful when some of your schemas cannot be compiled
+ separately or have cyclic dependencies which involve inheritance.
+ Other new options that are useful in this compilation mode are
+ --type-file-regex, --type-file-regex-trace, and --file-list. See the
+ compiler command line manual (man pages) for more information.
+
+ * New option, --options-file, allows additional command line options
+ to be provided in files, with one option per line.
+
+ * New option, --reserved-name, allows insertion of additional names
+ with optional replacements to the list of names that should not be
+ used as identifiers. See the compiler command line manual (man pages)
+ for details.
+
+ * New options, --location-map, --location-regex, and
+ --location-regex-trace, allow re-mapping of schema locations
+ specified in the include and import elements without modifying the
+ schema files. See the compiler command line manual (man pages) for
+ more information.
+
+ * New option, --guard-prefix, allows specification of a prefix that
+ should be added to generated header inclusion guards.
+
+ * New option, --file-list, triggers creation of a file with a list of
+ generated C++ files. This option is primarily useful in the file-per-
+ type compilation mode (--file-per-type) to create a list of generated
+ C++ files, for example, as a makefile fragment. Other new options
+ that are useful with --file-list are --file-list-prologue,
+ --file-list-epilogue, and --file-list-delim. See the compiler command
+ line manual (man pages) for more information.
+
+ * Support for the upcoming Xerces-C++ 3.0.0 release.
+
+ C++/Tree
+
+ * New option, --generate-intellisense, triggers generation of workarounds
+ for IntelliSense bugs in Visual Studio 2005 (8.0). When this option is
+ used, the resulting code is slightly more verbose. IntelliSense in
+ Visual Studio 2008 (9.0) does not require these workarounds. Support
+ for IntelliSense in Visual Studio 2003 (7.1) is improved with this
+ option but is still incomplete.
+
+ * New options, --type-naming and --function-naming, allow specification
+ of the type and function naming conventions that should be used in the
+ generated code. Supported values for --type-naming are: knr (K&R), ucc
+ (upper-camel-case), and java. Supported values for --function-naming
+ are: knr (K&R), lcc (lower-camel-case), and java. For more information
+ see the NAMING CONVENTION section in the compiler command line manual
+ (man pages).
+
+ * New options, --type-regex, --accessor-regex, --modifier-regex,
+ --parser-regex, --serializer-regex, and --enumerator-regex, allow
+ specification of transformations for type, accessor function,
+ modifier function, parsing function, serialization function, and
+ enumerator names in order to produce the generated code using a
+ custom naming convention. For more information see the NAMING
+ CONVENTION section in the compiler command line manual (man pages).
+
+ * Generated list classes now provide a complete set of constructors and
+ conform to the standard C++ sequence interface.
+
+ * String-based types now provide two extra constructors that expect a
+ C string and std::string as their arguments. This allows direct
+ initialization of string-based types from string literals.
+
+ * New implementations of the XML Schema date/time types (date, dateTime,
+ duration, gDay, gMonth, gMonthDay, gYear, gYearMonth, and time) that
+ represent the information in the numerical form.
+
+ * New binary serialization examples: binary/boost, which shows how to
+ save/load the object model to/from a custom format using the Boost
+ serialization library as an example, and binary/xdr, which 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.
+
+ * The non-copying modifier functions can now be used to assemble object
+ models from scratch. For more information see Section 4.4, "Creating
+ the Object Model from Scratch" in the C++/Tree Mapping Getting Started
+ Guide as well as Section 2.8, "Mapping for Local Elements and Attributes"
+ in the C++/Tree Mapping User Manual.
+
+ * Doxygen documentation was added to the XSD runtime for the built-in XML
+ Schema types, exceptions, etc. This allows linking of the generated
+ documentation to the XSD runtime documentation using the Doxygen tags
+ mechanism. The Doxygen configuration file for the XSD runtime is
+ provided in the documentation/cxx/tree/reference/ directory.
+
+ * Support for customization of anyType. Because anyType is a base type
+ for every generated type, customizing it allows one to implement custom
+ functionality that spans the entire type system. See the comments
+ example in the examples/cxx/tree/custom/ directory.
+
+ * New option, --omit-default-attributes, triggers generation of extra
+ checks that exclude attributes with default and fixed values from the
+ serialized XML documents.
+
+ * The parsing functions that used to read from DOMInputSource were changed
+ to use InputSource to ease support of Xerces-C++ 3 and 2 series in the
+ same code base.
+
+ * The parsing function that used to parse DOMDocument* was changed to
+ parse xml_schema::dom::auto_ptr<DOMDocument>& instead. If the keep_dom
+ and own_dom flags are specified then this parsing function resets the
+ passed automatic pointer and the returned object model assumes
+ ownership of the DOM document. xml_schema::dom::auto_ptr is a simple
+ automatic pointer for Xerces-C++ DOM with the same interface as
+ std::auto_ptr.
+
+ * The xml_schema::tree_node_key DOM user data key was moved to
+ xml_schema::dom::tree_node_key.
+
+ C++/Parser
+
+ * New option, --generate-polymorphic, triggers generation of polymorphism-
+ aware code. This option should be used on XML vocabularies which use
+ xsi:type and/or substitution groups. For more information see Section
+ 5.4, "Support for Polymorphism" in the C++/Parser Mapping Getting
+ Started Guide we well as the polymorphism and polyroot examples in the
+ examples/cxx/parser/ directory.
+
+ * The date/time types (date, dateTime, gDay, gMonth, gMonthDay, gYear,
+ gYearMonth, and time) now represent time zone in the numerical form.
+
+ * In order to support parsing of polymorphic XML documents, the signatures
+ of the start_* functions (_start_element, _start_any_element, and
+ start_root_element) have changed to include a third argument of type
+ const ro_string<C>*. This argument contains the resolved type name and
+ namespace in case the xsi:type attribute was specified.
+
+Version 3.0.0
+
+ * Anonymous type morphing (automatic type naming) is now performed by
+ default in both mappings. The --morph-anonymous option does not have
+ any effect but is preserved for backwards compatibility. A new option,
+ --preserve-anonymous, disables anonymous type morphing. This option is
+ useful together with --show-anonymous if you want to make sure your
+ schemas do not have any anonymous types.
+
+ * A number of bugs fixed in both C++/Tree and C++/Parser mappings.
+
+ C++/Tree
+
+ * The new C++/Tree Mapping Getting Started Guide is available in the
+ documentation/cxx/tree/guide/ directory.
+
+ * The type definitions for local elements and attributes in the form
+ name::type have been changed to name_type. For example, an element
+ bar in type foo with maxOccurs="unbounded" used to have its iterator
+ type defined as foo::bar::iterator. With this change it becomes
+ foo::bar_iterator. Furthermore, the container type name for sequence
+ elements has changed from foo::bar::container to foo::bar_sequence
+ and for optional elements and attributes from foo::bar::container
+ to foo::bar_optional. This is a backwards incompatible change and
+ may require application code adjustments (the C++ compiler will
+ pinpoint the affected places).
+
+ * New option, --generate-doxygen, triggers generation of documentation
+ comments suitable for extraction by the Doxygen documentation system.
+ Documentation from annotations is added to the comments if present in
+ the schema.
+
+ * New option, --generate-wildcard, triggers generation of the new
+ wildcard (any and anyAttribute) mapping. This mapping represents the
+ content matched by wildcards as DOM fragments. For more information on
+ the new mapping see Section 2.12, "Mapping for any and anyAttribute"
+ in the C++/Tree Mapping User Manual as well as the wildcard example in
+ the examples/cxx/tree/ directory.
+
+ * New option, --generate-comparison, triggers generation of comparison
+ operators (== and !=) for complex types. Comparison is performed
+ memberwise.
+
+ * Support for the RPC XDR binary stream in addition to ACE CDR.
+
+ * New constructor is generated for complex types with ultimate bases
+ that are simple types and can be default-initialized. This constructor
+ includes initializers for all required members but omits the initializer
+ for the base type. See Section 2.7, "Mapping for Complex Types" in the
+ C++/Tree Mapping User Manual for more information.
+
+ * Support for polymorphic binary serialization and extraction. Note that
+ the semantics of the --generate-insertion and --generate-extraction
+ options has changed. See the the compiler command line manual (man
+ pages) for details.
+
+ * New parsing function with the DOMDocument* argument and the own_dom
+ flag allow the tree to assume the ownership of the DOM document
+ being parsed when DOM association is requested (keep_dom flag).
+ See the C++/Tree Mapping User Manual for more information.
+
+ * New example, multiroot, shows how to handle XML vocabularies with
+ multiple root elements.
+
+ * New example, caching, shows how to parse several XML documents while
+ reusing the underlying XML parser and caching the schemas used for
+ validation.
+
+ * The mapping of built-in XML Schema type decimal has changed from
+ long double to double. The old mapping can be obtained by providing
+ a custom mapping for this type.
+
+ * The xml_schema::errors type which is used in the xml_schema::parsing
+ and xml_schema::serialization exceptions has been renamed to
+ xml_schema::diagnostics and extended to include warnings in addition
+ to errors.
+
+ * Serialization operators now clear the element being serialized to from
+ existing child nodes and attributes (except for special attributes such
+ as prefix-namespace mappings, etc.).
+
+ * Improved built-in type parsing, including support for normalization and
+ whitespace collapsing.
+
+ * Optimizations for the generated code size and compilation time,
+ including space optimizations for polymorphic parsing and
+ serialization. Optimizations for XML parsing speed.
+
+ C++/Parser
+
+ * The C++/Parser mapping have been significantly redesigned. See the new
+ Getting Started Guide in documentation/cxx/parser/guide/ for details.
+
+ * The new C++/Parser Mapping Getting Started Guide is available in the
+ documentation/cxx/parser/guide/ directory.
+
+ * The mapping now provides parser implementations for all built-in XML
+ Schema types. See Chapter 6, "Built-In XML Schema Type Parsers" in
+ the C++/Parser Mapping Getting Started Guide for more information.
+
+ * The mapping now supports automatic generation of sample parser
+ implementations and a test driver. The --generate-noop-impl option
+ triggers generation of a sample implementation with empty function
+ bodies. The --generate-print-impl option triggers generation of a
+ sample implementation that prints the data stored in XML to STDOUT.
+ The --generate-test-driver option trigger generation of a test driver.
+ For more information on this feature see the compiler command line
+ manual (man pages) and the generated example in the examples/cxx/parser/
+ directory. Other relevant options include: --force-overwrite,
+ --root-element-first, --root-element-last, and --root-element.
+
+ * New example, wildcard, shows how to parse the XML data matched by
+ XML Schema wildcards (any and anyAttribute).
+
+ * The xml_schema::document parser has been extended with overridable
+ virtual functions start_root_element and end_root_element to support
+ parsing of XML vocabularies with multiple document roots. See the
+ multiroot example in the examples/cxx/parser/ directory for more
+ information.
+
+ * The xml_schema::errors type which is used in the xml_schema::parsing
+ exception has been renamed to xml_schema::diagnostics and extended to
+ include warnings in addition to errors.
+
+Version 2.3.1
+
+ * The compiler is now capable of translating multiple schemas with
+ one invocation.
+
+ * New option, --sloc-limit, allows one to limit the amount of the
+ generated code.
+
+ * New option, --proprietary-license, instructs the compiler not to
+ include the GPL banner in each generated file. Instead a short
+ notice about a required proprietary license is generated. You
+ should not use this option unless you have obtained a proprietary
+ license from Code Synthesis Tools CC.
+
+ * The default encoding for the 'char' character type is now UTF-8.
+ To get the previous behavior (local code page via the Xerces-C++
+ transcode functions) define the XSD_USE_LCP preprocessor macro
+ when compiling your source code.
+
+ C++/Tree
+
+ * The --parts option has been improved to split generated code more
+ evenly by analyzing the complexity of the generated schema constructs.
+
+ * Ability to customize serialization, std::ostream, and binary
+ insertion/extraction operators. See examples/cxx/tree/custom/wildcard
+ for an example on how to handle XML Schema wildcards (xsd:any and
+ xsd:anyAttribute) by customizing the parsing constructor and
+ serialization operators.
+
+ * Optimizations for the run-time memory consumption.
+
+ * Optimizations for space in the generated code.
+
+ * Number of bug fixes.
+
+ C++/Parser
+
+ * Proper handling of an xsd:any nested content. Nested elements,
+ attributes, and text are reported via _any_* hooks of the current
+ parser.
+
+ * Number of bug fixes, mostly in the generated validation code.
+
+
+Version 2.3.0
+
+ * Name conflicts across type inheritance hierarchies are now detected
+ and resolved via name escaping.
+
+ C++/Tree
+
+ * New option, --suppress-parsing, suppresses generation of the parsing
+ constructors and functions. This can be used to minimize the generated
+ code footprint when parsing from XML is not used.
+
+ * New option, --generate-forward, triggers generation of a forward
+ declaration header file for types defined in the schema. A set of
+ --fwd-* options that control the resulting file name as well as
+ prologue and epilogue code are available.
+
+ * New option, --generate-xml-schema, triggers generation of the mapping
+ for the XML Schema namespace to a separate header file. See the man
+ pages for details and examples/cxx/tree/custom/calendar for an example.
+
+ * New option, --extern-xml-schema, triggers inclusion of a header
+ file for the XML Schema namespace instead of generating the
+ necessary declarations inline. See the man pages for details and
+ examples/cxx/tree/custom/calendar for an example.
+
+ * New options, --custom-type and --custom-type-regex, instruct the
+ compiler to use custom C++ type for a type defined in the schema.
+ The standard mapping can still be generated (with a different name)
+ usually to be used as a base. Built-in XML Schema types can be
+ customized using this mechanism. See the man pages for details and
+ examples/cxx/tree/custom/* for examples.
+
+ * The generated parsing constructors and serialization operators have
+ been changed to use the Xerces-C++ DOM elements and attributes
+ instead of the internal wrapper types. This should provide easier
+ integration with other code and libraries that use the Xerces-C++
+ DOM types such as Berkeley DB XML.
+
+ * New example, examples/cxx/tree/dbxml, shows how to use the C++/Tree
+ mapping on top of the Berkeley DB XML database.
+
+ C++/Parser
+
+ * Validation of the attribute structure in the generated code.
+
+ * Validation of the character content models including mixed content in
+ the generated code.
+
+ * Validation of the built-in XML Schema types.
+
+ * Optimizations for space and time in the generated code. In particular
+ data coping during parsing and validation was significantly reduced.
+
+
+Version 2.2.0
+
+ * Detection of a version mismatch between the generated code and
+ the runtime.
+
+ C++/Tree
+
+ * Escaping of a global element name that conflicts with a global type
+ name. This is a backwards-incompatible change. Previous versions
+ map them to the same name.
+
+ * New options, --generate--insertion and --generate-extraction,
+ trigger generation of (binary) data representation stream
+ insertion and extraction operators, respectively. This allows
+ one to serialize/deserialize in-memory representation to/from
+ data representation streams such as XSD, CDR, etc. ACE CDR
+ streams are supported out of the box (see the binary example).
+ User-supplied streams can be used via an adaptation layer.
+
+ * New serialization flag, no_xml_declaration, instructs the XML
+ serialization functions to omit an XML declaration. This is useful
+ for streaming serialization (see the streaming example).
+
+ * Optimizations to reduce generated code size.
+
+
+ C++/Parser
+
+ * New options, --generate-validation and --suppress-validation,
+ trigger and suppress generation of the validation code,
+ respectively. The validation code is the implementation of the
+ XML Schema validation in the generated code (also known as
+ "perfect" parser). In this version validation of the element
+ structure has been implemented.
+
+ * New architecture for underlying XML parsers. This is a backwards-
+ incompatible change. Existing applications will have to be
+ modified. See examples for details.
+
+
+Version 2.1.1
+
+ C++/Tree
+
+ * New option, --namespace-map, allows direct mapping of XML Schema
+ namespaces to C++ namespaces without the use of regular expressions.
+
+ * Further optimizations in the container code and enum mapping to
+ reduce generated code size.
+
+ * Number of bug fixes in the generated code.
+
+
+ C++/Parser
+
+ * New option, --namespace-map, allows direct mapping of XML Schema
+ namespaces to C++ namespaces without the use of regular expressions.
+
+
+Version 2.1.0
+
+ * Automatic handling of forward inheritance. XML Schema allows
+ inheritance from yet undefined types while it is illegal to do
+ so in C++. Now the translator automatically handles forward
+ inheritance by re-arranging the schema during compilation.
+
+
+ C++/Tree
+
+ * New enum mapping with support for inheritance. Enumerators are
+ now parsed using binary search instead of linear search.
+
+ * Associated DOM nodes now retain "back" pointers to tree nodes.
+
+ * Optimizations to reduce generated code size.
+
+
+ C++/Parser
+
+ * Specialization for void. You can now use void as a hook argument
+ type if you don't want to pass any data between parsers.
+
+ * Support for re-use of implementations of base parsers in derived
+ parsers using the mixin C++ idiom. See the examples/cxx/parser/mixin
+ for more information.
+
+ * Support for uninitialized parser. If you don't provide a parser
+ for element/attribute, that element/attribute will be ignored
+ during parsing.
+
+
+Version 2.0.0
+
+ * New cardinality calculator. This improves support for schemas that
+ use complex structures with repeated elements, e.g.,
+
+ <complexType name="Type">
+ <choice>
+ <sequence>
+ <element name="a" type="string"/>
+ <element name="c" type="string"/>
+ </sequence>
+ <sequence>
+ <element name="b" type="string"/>
+ <element name="c" type="string"/>
+ </sequence>
+ </choice>
+ </complexType>
+
+
+ * New identifier escaping code. With this feature xsd generates proper
+ code for schemas that use the same name for an element and an attribute
+ in the same type or use several elements/attributes with different
+ qualified names but with the same local name, e.g.,
+
+ <!-- base.xsd -->
+ <schema xmlns="http://codesynthesis.com/xmlns/test/foo"
+ targetNamespace="http://codesynthesis.com/xmlns/test/foo">
+
+ <element name="foo" type="int"/>
+ </schema>
+
+ <schema xmlns="http://codesynthesis.com/xmlns/test/bar"
+ xmlns:f="http://codesynthesis.com/xmlns/test/foo"
+ targetNamespace="http://codesynthesis.com/xmlns/test/bar">
+
+ <import namespace="http://codesynthesis.com/xmlns/test/foo"
+ schemaLocation="base.xsd"/>
+
+ <element name="foo" type="string"/>
+
+ <complexType name="Foo">
+ <sequence>
+ <element ref="foo"/>
+ <element name="foo" type="long"/>
+ <element ref="f:foo"/>
+ <element ref="f:foo"/>
+ </sequence>
+ <attribute name="foo" type="string"/>
+ </complexType>
+ </schema>
+
+
+ C++/Tree
+
+ * New option, --generate-polymorphic, triggers generation of
+ polymorphism-aware code. Before this release xsd used to always
+ generate polymorphism-aware code. However, it appears to be quite
+ wasteful in terms of the generated code size (up to 40%). You will
+ now need to explicitly specify this option if you use substitution
+ groups or xsi:type. A warning is issued if this option is not
+ specified but the schema makes use of substitution groups.
+
+ * New options, --root-element-first, --root-element-last,
+ --root-element-all, --root-element-none, and --root-element, control
+ generation of parsing and serialization functions. With these options
+ you can avoid generating extra code for global elements that are not
+ document roots. See the man pages for details.
+
+ * New options, --parts and -parts-suffix, allows you to split generated
+ source code into a number of parts. This is useful when translating
+ large, monolithic schemas and a C++ compiler is not able to compile
+ the resulting source code at once (usually due to insufficient memory).
+
+ * New option, --generate-default-ctor, triggers generation of default
+ constructors even for types that have required members. Required
+ members of an instance constructed using such a constructor are not
+ initialized and accessing them results in undefined behavior. Thanks
+ to Jean-Francois Dube <jf at magnu.polymtl.ca> for suggesting this
+ feature.
+
+ * New option, --generate-from-base-ctor, triggers generation of
+ constructors that expect an instance of a base type followed by all
+ required members. Thanks to Jean-Francois Dube <jf at magnu.polymtl.ca>
+ for suggesting this feature.
+
+ * Information scopes for attributes and elements with default/fixed values
+ now define the public static default_value function which allows one to
+ obtain the default/fixed value for the element/attribute. Thanks to
+ Dave Moss <david.r.moss at selex-comm.com> for suggesting this feature.
+
+ * MSVC 7.1 has a limit on the length of the "if else if" chain. This
+ results in ICE when compiling generated code for enumerations with
+ a large number of values. This version addresses this issue. Thanks
+ to Cyrille Chépélov <cyrille at chepelov.org> for reporting this and
+ suggesting a fix.
+
+
+ C++/Parser
+
+ * The parser construction API has changed. Now, for element 'foo',
+ the name of the parser modifier function is 'foo_parser'. Likewise,
+ operator() for setting all parsers at once has been changed to the
+ 'parsers' function.
+
+
+Version 1.9.0
+
+ C++/Tree
+
+ * The size modifier function in the base64_binary and hex_binary
+ built-in types automatically adjusts capacity if needed.
+
+ * More internal names (names that start with _xsd_) were made
+ private or protected.
+
+ C++/Parser
+
+ * Typedef for the parser base in the xml_schema namespace.
+
+ C++/Parser-E
+
+ * C++/Parser mapping optimized for embedded systems. For now it
+ is equivalent to 'cxx-parser --xml-parser expat'.
+
+
+Version 1.8.0
+
+ * Moved to the build 0.2 series.
+
+ C++/Tree
+
+ * Support for default and fixed values in attributes. An optional
+ attribute with a default or fixed value is mapped to the One
+ cardinality class instead of the Optional cardinality class.
+
+ * Mapping for base64Binary and hexBinary has improved. Now these
+ types support a basic buffer abstraction and perform automatic
+ encoding and decoding.
+
+ * Internal names are protected. We've noticed (via bug reports) a
+ wide use of internal names (names that start with _xsd_) in user
+ code. This is not portable and instead you should use public
+ names. To prevent this from happening in the future we've made
+ all internal names protected.
+
+ C++/Parser
+
+ * Support for Expat as the underlying XML parser in addition to
+ Xerces-C++. This allows one to use the C++/Parser mapping in
+ memory-constrained environments such as embedded systems. To
+ select Expat instead of Xerces-C++ (default) add
+ '--xml-parser expat' to the command line. At the moment only
+ 'char' (UTF-8) is supported as the base character type when
+ Expat is selected.
+
+ * The invalid_instance exception has been renamed to parsing.
+
+ * Generic error_handler interface has been added in addition
+ to Xerces-C++-specific DOMErrorHandler. It allows you to
+ handle parsing errors and warnings without having to deal
+ with Xerces-C++ specifics.
+
+ * The default error handling behavior has changed in parsing
+ functions. Instead of printing errors and warnings to STDERR,
+ the errors are now collected and thrown as part of the parsing
+ exception.
+
+ * In parsing functions, the name, namespace arguments order has
+ been reversed to be consistent with the one used in parsing
+ hooks.
+
+Version 1.7.0
+
+ * Number of bug fixes in libxsd and the generated code.
+
+ C++/Tree
+
+ * Comprehensive XML Schema C++/Tree Mapping User Manual.
+
+ * Basic support for union. A simple type that is defined using
+ derivation by union is mapped to a C++ class that derives from
+ string.
+
+ * The _clone function has its arguments default-initialized.
+
+ * The invalid_instance exception has been renamed to parsing.
+
+ * Generic error_handler interface has been added in addition
+ to Xerces-C++-specific DOMErrorHandler. It allows you to
+ handle parsing/serialization errors and warnings without
+ having to deal with Xerces-C++ specifics. See the user
+ manual for more information.
+
+ * The default error handling behavior has changed in parsing
+ and serialization functions. Instead of printing errors and
+ warnings to STDERR, the errors are now collected and thrown
+ as part of the parsing/serialization exception. See the user
+ manual for more information.
+
+ * The optional and sequence containers now support operators ==,
+ !=, <, >, <=, and >=.
+
+ * Flags argument has been added to serialization functions. The
+ only flag that is currently supported is dont_initialize.
+
+ * Generated code cleanups.
+
+ C++/Parser
+
+ * Basic support for union. A simple type that is defined using
+ derivation by union is mapped to a C++ class template that
+ is just an alias for the generic parser. You are expected to
+ override the _characters function in your implementation.
+
+ * Properties argument to parsing functions which allows to
+ programmatically specify schemas for instance document
+ validation.
+
+ * Flags argument to parsing functions. The following flags
+ are supported:
+
+ dont_validate - do not validate instance documents
+ dont_initialize - do not initialize the Xerces-C++ runtime
+
+Version 1.6.0
+
+ * Number of bug fixes in libxsd and the generated code.
+
+ C++/Tree
+
+ * Support for xsi:type and substitution groups in parsing and
+ serialization. See examples/cxx/tree/polymorphism for a code
+ sample.
+
+ * Properties argument to parsing functions which allows to
+ programmatically specify schemas for instance document
+ validation.
+
+ * Extra checks in parsing code which prevents construction
+ of inconsistent in-memory representation from invalid
+ instance documents. Should be useful when validation is
+ disabled.
+
+ * Accessors and modifier were made normal member functions.
+ Before they were implemented via functors.
+
+ * Workaround for g++-3.3 bug# 16650:
+
+ http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16650
+
+ C++/Parser
+
+ * All "service" functions were renamed to start with '_'.
+ This should prevent hiding of service functions by
+ elements/attributes with the same names.
+
+Version 1.5.0
+
+ * Number of bug fixes in libxsd and the generated code.
+
+ C++/Tree
+
+ * Basic support for inheritance-by-restriction in complex types.
+
+ * The following parsing flags have been introduced:
+
+ keep_dom - keep association with underlying DOM nodes
+ dont_validate - do not validate instance documents
+ dont_initialize - do not initialize the Xerces-C++ runtime
+
+ * "Type-less content" such as mixed content models, xsd:anyType/
+ xsd:anySimpleType, and xsd:any/xsd:anyAttribute is supported by
+ exposing corresponding DOM nodes (see the keep_dom parsing flag).
+ Note that only a subset of XML Schema xsd:any functionality is
+ supported. The compiler will issue diagnostics for unsupported
+ cases. See examples/cxx/tree/mixed for a code sample.
+
+ C++/Parser
+
+ * Support for inheritance-by-restriction in complex types.
+
+ * "Type-less content" such as mixed content models, xsd:anyType/
+ xsd:anySimpleType, and xsd:any/xsd:anyAttribute is supported
+ by forwarding parsing events to a set of "unexpected" hooks.
+ Note that only a subset of XML Schema xsd:any functionality is
+ supported. The compiler will issue diagnostics for unsupported
+ cases. See examples/cxx/parser/mixed for a code sample.
+
+Version 1.4.0
+
+ * Number of improvements and bug fixes in the diagnostics code.
+
+ * libxsd has been reorganized to provide a clean split of code with
+ regards to char/wchar_t use. It should be possible to use libxsd
+ and the xsd-generated code on platforms that lack wchar_t support,
+ such as mingw.
+
+ C++/Tree
+
+ * Work around for g++ bug# 23206.
+
+ * Support for xsd:list.
+
+ * Type/member name conflicts are auto-resolved. Such conflicts
+ occur when a type and an element or attribute withing this type
+ share the same name.
+
+ * XML Schema extension, the 'refType' attribute, allows one to
+ specify referenced type for xsd:IDREF and xsd:IDREFS data types.
+ See examples/cxx/tree/library for details.
+
+ * New option, --morph-anonymous, allows automatic morphing
+ of anonymous types to named ones. See the man pages for
+ details.
+
+ * New option, --namespace-regex-trace, allows one to trace the
+ namespace mapping process. See the man pages for details.
+
+ * Mapping for optional elements/attributes (cardinality 0..1)
+ has changed in a backwards-incompatible way. In the previous
+ version you would write:
+
+ Bar& bar = ...
+
+ if (bar.foo.present ()) // test
+ {
+ Foo& foo (bar.foo ()); // get
+
+ bar.foo (Foo (...)); // set
+
+ bar.foo.reset (); // reset
+ }
+
+ Now you would write it like this:
+
+ if (bar.foo ().present ()) // test
+ {
+ Foo& foo (bar.foo ().get ()); // get
+
+ bar.foo (Foo (...)); // set
+
+ bar.foo ().reset (); // reset
+ }
+
+ Or using the pointer notation:
+
+ if (bar.foo ()) // test
+ {
+ Foo& foo (*bar.foo ()); // get
+
+ bar.foo (Foo (...)); // set
+
+ bar.foo ().reset (); // reset
+ }
+
+ C++/Parser
+
+ * Support for xsd:list.
+
+ * Type/member name conflicts are auto-resolved. Such conflicts
+ occur when a type and an element or attribute withing this type
+ share the same name.
+
+ * New option, --namespace-regex-trace, allows one to trace the
+ namespace mapping process. See the man pages for details.
+
+Version 1.3.0
+
+ * Numerous bug fixes.
+
+ * The XML subsystem of libxsd has been reorganized to provide
+ a clean split of DOM and SAX functionalities.
+
+ C++/Parser
+
+ * New option, --morph-anonymous, allows automatic morphing
+ of anonymous types to named ones. See the man pages for
+ details.
+
+ C++/Tree
+
+ * Additional parser functions provide support for reading
+ from std::istream.
+
+Version 1.2.0
+
+ C++/Parser
+
+ * New backend that generates the C++/Parser mapping.
+
+Version 1.1.1
+
+ all backends
+
+ * Bug fixes in the filesystem path handling logic.
+
+Version 1.1.0
+
+ C++/Tree
+
+ * New option, --generate-serialization, triggers generation of
+ serialization functions. Serialization functions convert an in-memory
+ representation back to XML.
+
+ * xsd::cxx::tree::vector has been extended to closely follow std::vector
+ API. This allows you to access and modify element sequences as if they
+ were of type std::vector.
+
+ * Generated constructors from xml::attribute and xml::element are made
+ explicit.
+
+ * The library example was extended to showcase modification and
+ serialization of the in-memory representation.
+
+ * New "XML Schema C++/Tree Mapping Serialization Guide" has an in-depth
+ treatment of the serialization mechanisms provided by xsd.
+
+Version 1.0.1
+
+ all backends
+
+ * Improved diagnostics.
+
+ * Bug fixes in the schema inclusion/importing logic.
+
+ C++/Tree
+
+ * Two new options: --include-with-brackets and --include-prefix
+
+Version 1.0.0
+
+ * First public release.
diff --git a/README b/README
new file mode 100644
index 0000000..b7d30d7
--- /dev/null
+++ b/README
@@ -0,0 +1,27 @@
+CodeSynthesis XSD is a W3C XML Schema to C++ data binding compiler.
+It generates vocabulary-specific, statically-typed C++ mappings (also
+called bindings) from XML Schema definitions. XSD supports two C++
+mappings: in-memory C++/Tree and event-driven C++/Parser.
+
+The C++/Tree mapping consists of 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.
+
+The C++/Parser mapping provides parser templates for data types
+defined in XML Schema. Using these parser templates you can build
+your own in-memory representations or perform immediate processing
+of XML instance documents.
+
+See the NEWS file for the user-visible changes from the previous release.
+
+See the LICENSE file for distribution conditions.
+
+See the INSTALL file for prerequisites and installation instructions.
+
+See the documentation/ directory for documentation.
+
+The project page is at http://codesynthesis.com/projects/xsd/.
+
+Send bug reports or any other feedback to the xsd-users@codesynthesis.com
+mailing list.
diff --git a/build/bootstrap.make b/build/bootstrap.make
new file mode 100644
index 0000000..1c3d21e
--- /dev/null
+++ b/build/bootstrap.make
@@ -0,0 +1,54 @@
+# file : build/bootstrap.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+project_name := XSD
+
+include build-0.3/bootstrap.make
+
+# Configuration
+#
+
+$(call include,$(scf_root)/configuration.make)
+
+
+# Aliases
+#
+ifdef %interactive%
+
+.PHONY: test $(out_base)/.test \
+ install $(out_base)/.install \
+ clean $(out_base)/.clean
+
+test: $(out_base)/.test
+install: $(out_base)/.install
+clean: $(out_base)/.clean
+
+ifeq ($(.DEFAULT_GOAL),test)
+.DEFAULT_GOAL :=
+endif
+
+ifeq ($(.DEFAULT_GOAL),install)
+.DEFAULT_GOAL :=
+endif
+
+ifeq ($(.DEFAULT_GOAL),clean)
+.DEFAULT_GOAL :=
+endif
+
+endif
+
+
+# Don't include dependency info if we are cleaning.
+#
+define include-dep
+endef
+
+ifneq ($(MAKECMDGOALS),clean)
+ifneq ($(MAKECMDGOALS),disfigure)
+define include-dep
+$(call -include,$1)
+endef
+endif
+endif
diff --git a/build/configuration-rules.make b/build/configuration-rules.make
new file mode 100644
index 0000000..3d468c4
--- /dev/null
+++ b/build/configuration-rules.make
@@ -0,0 +1,18 @@
+# file : build/configuration-rules.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+$(dcf_root)/configuration-dynamic.make: | $(dcf_root)/.
+ $(call message,,$(scf_root)/configure $@)
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $$1,rm -f $$1,$(dcf_root)/configuration-dynamic.make)
+
+endif
+
+ifeq ($(.DEFAULT_GOAL),$(dcf_root)/configuration-dynamic.make)
+.DEFAULT_GOAL :=
+endif
diff --git a/build/configuration.make b/build/configuration.make
new file mode 100644
index 0000000..49cd176
--- /dev/null
+++ b/build/configuration.make
@@ -0,0 +1,33 @@
+# file : build/configuration.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+$(call include-once,$(scf_root)/configuration-rules.make,$(dcf_root))
+
+
+# Dynamic configuration.
+#
+xsd_with_ace :=
+xsd_with_xdr :=
+xsd_with_dbxml :=
+xsd_with_xqilla :=
+xsd_with_boost_date_time :=
+xsd_with_boost_serialization :=
+
+$(call -include,$(dcf_root)/configuration-dynamic.make)
+
+ifdef xsd_with_ace
+
+$(out_root)/%: xsd_with_ace := $(xsd_with_ace)
+$(out_root)/%: xsd_with_xdr := $(xsd_with_xdr)
+$(out_root)/%: xsd_with_dbxml := $(xsd_with_dbxml)
+$(out_root)/%: xsd_with_xqilla := $(xsd_with_xqilla)
+$(out_root)/%: xsd_with_boost_date_time := $(xsd_with_boost_date_time)
+$(out_root)/%: xsd_with_boost_serialization := $(xsd_with_boost_serialization)
+
+else
+
+.NOTPARALLEL:
+
+endif
diff --git a/build/configure b/build/configure
new file mode 100755
index 0000000..73b9393
--- /dev/null
+++ b/build/configure
@@ -0,0 +1,73 @@
+#! /usr/bin/env bash
+
+# file : build/configure
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+# $1 out file
+#
+# bld_root - build root
+# project_name - project name
+#
+
+source $bld_root/dialog.bash
+
+
+$echo
+$echo
+$echo "configuring '$project_name'"
+$echo
+$echo
+
+
+$echo
+$echo "Would you like to build optional parts of '$project_name' that require"
+$echo "the 'ACE' library?"
+$echo
+
+with_ace=`read_y_n n`
+
+$echo
+$echo "Would you like to build optional parts of '$project_name' that require"
+$echo "the 'XDR' library (part of the system in most GNU/Linux and"
+$echo "UNIX distributions)?"
+$echo
+
+with_xdr=`read_y_n n`
+
+$echo
+$echo "Would you like to build optional parts of '$project_name' that require"
+$echo "the boost 'serialization' library?"
+$echo
+
+with_boost_serialization=`read_y_n n`
+
+
+$echo
+$echo "Would you like to build optional parts of '$project_name' that require"
+$echo "the boost 'date_time' library?"
+$echo
+
+with_boost_date_time=`read_y_n n`
+
+$echo
+$echo "Would you like to build optional parts of '$project_name' that require"
+$echo "the 'Berkeley DB XML' library?"
+$echo
+
+with_dbxml=`read_y_n n`
+
+$echo
+$echo "Would you like to build optional parts of '$project_name' that require"
+$echo "the XQilla library?"
+$echo
+
+with_xqilla=`read_y_n n`
+
+echo "xsd_with_ace := $with_ace" >$1
+echo "xsd_with_xdr := $with_xdr" >>$1
+echo "xsd_with_dbxml := $with_dbxml" >>$1
+echo "xsd_with_xqilla := $with_xqilla" >>$1
+echo "xsd_with_boost_date_time := $with_boost_date_time" >>$1
+echo "xsd_with_boost_serialization := $with_boost_serialization" >>$1
diff --git a/build/import/libace/LICENSE b/build/import/libace/LICENSE
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/build/import/libace/LICENSE
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/build/import/libace/configuration-rules.make b/build/import/libace/configuration-rules.make
new file mode 100644
index 0000000..8d1230c
--- /dev/null
+++ b/build/import/libace/configuration-rules.make
@@ -0,0 +1,15 @@
+# file : build/import/libace/configuration-rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(dcf_root)/import/libace/configuration-dynamic.make: | $(dcf_root)/import/libace/.
+ $(call message,,$(scf_root)/import/libace/configure $@)
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libace/configuration-dynamic.make,\
+rm -f $(dcf_root)/import/libace/configuration-dynamic.make)
+
+endif
diff --git a/build/import/libace/configure b/build/import/libace/configure
new file mode 100755
index 0000000..eb7bd56
--- /dev/null
+++ b/build/import/libace/configure
@@ -0,0 +1,58 @@
+#! /usr/bin/env bash
+
+# file : build/import/libace/configure
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+
+# $1 - out config file
+#
+# bld_root - build root
+# project_name - project name
+#
+
+source $bld_root/dialog.bash
+
+
+$echo
+$echo "Configuring external dependency on 'ACE' for '$project_name'."
+$echo
+
+$echo
+$echo "Would you like to configure dependency on the installed version"
+$echo "of 'ACE' as opposed to the development build?"
+$echo
+
+installed=`read_y_n y`
+
+path=
+type=
+
+if [ "$installed" = "n" ]; then
+
+ $echo
+ $echo "Please enter the 'ACE' root directory (ACE_ROOT)."
+ $echo
+
+ root=`read_path --directory --exist`
+
+ $echo
+ $echo "Please select the library type you would like to use:"
+ $echo
+ $echo "(1) archive"
+ $echo "(2) shared object"
+ $echo
+
+ type=`read_option "archive shared" "shared"`
+
+fi
+
+echo libace_installed := $installed >$1
+
+if [ "$installed" = "n" ]; then
+
+ echo libace_root := $root >>$1
+ echo libace_type := $type >>$1
+
+fi
diff --git a/build/import/libace/rules.make b/build/import/libace/rules.make
new file mode 100644
index 0000000..9535085
--- /dev/null
+++ b/build/import/libace/rules.make
@@ -0,0 +1,29 @@
+# file : build/import/libace/rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(dcf_root)/import/libace/%: root := $(libace_root)
+
+ifeq ($(libace_type),archive)
+
+$(dcf_root)/import/libace/ace.l: $(libace_root)/lib/libACE.a
+ @echo $< >$@
+else
+
+$(dcf_root)/import/libace/ace.l: $(libace_root)/lib/libACE.so
+ @echo $< >$@
+ @echo rpath:$(root)/lib >>$@
+endif
+
+$(dcf_root)/import/libace/ace.l.cpp-options:
+ @echo include: -I$(root) >$@
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libace/ace.l,\
+rm -f $(dcf_root)/import/libace/ace.l)
+ $(call message,,rm -f $(dcf_root)/import/libace/ace.l.cpp-options)
+
+endif
diff --git a/build/import/libace/stub.make b/build/import/libace/stub.make
new file mode 100644
index 0000000..9482396
--- /dev/null
+++ b/build/import/libace/stub.make
@@ -0,0 +1,32 @@
+# file : build/import/libace/stub.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(scf_root)/import/libace/configuration-rules.make,$(dcf_root))
+
+libace_installed :=
+
+$(call -include,$(dcf_root)/import/libace/configuration-dynamic.make)
+
+ifdef libace_installed
+
+ifeq ($(libace_installed),y)
+
+$(call export,l: -lACE,cpp-options: )
+
+else
+
+$(call include-once,$(scf_root)/import/libace/rules.make,$(dcf_root))
+
+$(call export,\
+ l: $(dcf_root)/import/libace/ace.l,\
+ cpp-options: $(dcf_root)/import/libace/ace.l.cpp-options)
+
+endif
+
+else
+
+.NOTPARALLEL:
+
+endif
diff --git a/build/import/libace/version b/build/import/libace/version
new file mode 100644
index 0000000..0d91a54
--- /dev/null
+++ b/build/import/libace/version
@@ -0,0 +1 @@
+0.3.0
diff --git a/build/import/libbackend-elements/LICENSE b/build/import/libbackend-elements/LICENSE
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/build/import/libbackend-elements/LICENSE
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/build/import/libbackend-elements/configuration-rules.make b/build/import/libbackend-elements/configuration-rules.make
new file mode 100644
index 0000000..1766f03
--- /dev/null
+++ b/build/import/libbackend-elements/configuration-rules.make
@@ -0,0 +1,15 @@
+# file : build/import/libbackend-elements/configuration-rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(dcf_root)/import/libbackend-elements/configuration-dynamic.make: | $(dcf_root)/import/libbackend-elements/.
+ $(call message,,$(scf_root)/import/libbackend-elements/configure $@)
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libbackend-elements/configuration-dynamic.make,\
+rm -f $(dcf_root)/import/libbackend-elements/configuration-dynamic.make)
+
+endif
diff --git a/build/import/libbackend-elements/configure b/build/import/libbackend-elements/configure
new file mode 100755
index 0000000..db3e44d
--- /dev/null
+++ b/build/import/libbackend-elements/configure
@@ -0,0 +1,55 @@
+#! /usr/bin/env bash
+
+# file : build/import/libbackend-elements/configure
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+
+# $1 - out file
+#
+# bld_root - build root
+# project_name - project name
+#
+
+source $bld_root/dialog.bash
+
+
+$echo
+$echo "Configuring external dependency on 'libbackend-elements' for '$project_name'."
+$echo
+
+$echo
+$echo "Would you like to configure dependency on the installed version"
+$echo "of 'libbackend-elements' as opposed to the development build?"
+$echo
+
+installed=`read_y_n y`
+
+path=
+
+if [ "$installed" = "n" ]; then
+
+$echo
+$echo "Please enter the src_root for 'libbackend-elements'."
+$echo
+
+src_root=`read_path --directory --exist`
+
+$echo
+$echo "Please enter the out_root for 'libbackend-elements'."
+$echo
+
+out_root=`read_path --directory $src_root`
+
+fi
+
+echo libbackend_elements_installed := $installed >$1
+
+if [ "$installed" = "n" ]; then
+
+echo src_root := $src_root >>$1
+echo scf_root := \$\(src_root\)/build >>$1
+echo out_root := $out_root >>$1
+
+fi
diff --git a/build/import/libbackend-elements/stub.make b/build/import/libbackend-elements/stub.make
new file mode 100644
index 0000000..b171c30
--- /dev/null
+++ b/build/import/libbackend-elements/stub.make
@@ -0,0 +1,32 @@
+# file : build/import/libbackend-elements/stub.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(scf_root)/import/libbackend-elements/configuration-rules.make,$(dcf_root))
+
+libbackend_elements_installed :=
+
+$(call -include,$(dcf_root)/import/libbackend-elements/configuration-dynamic.make)
+
+ifdef libbackend_elements_installed
+
+ifeq ($(libbackend_elements_installed),y)
+
+#-lbackend-elements
+
+$(call export,l: -lcult -lboost_regex,cpp_options: )
+
+else
+
+# Include export stub.
+#
+$(call include,$(scf_root)/export/libbackend-elements/stub.make)
+
+endif
+
+else
+
+.NOTPARALLEL:
+
+endif
diff --git a/build/import/libboost/LICENSE b/build/import/libboost/LICENSE
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/build/import/libboost/LICENSE
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/build/import/libboost/configuration-rules.make b/build/import/libboost/configuration-rules.make
new file mode 100644
index 0000000..2e89c6e
--- /dev/null
+++ b/build/import/libboost/configuration-rules.make
@@ -0,0 +1,15 @@
+# file : build/import/libboost/configuration-rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(dcf_root)/import/libboost/configuration-dynamic.make: | $(dcf_root)/import/libboost/.
+ $(call message,,$(scf_root)/import/libboost/configure $@)
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libboost/configuration-dynamic.make,\
+rm -f $(dcf_root)/import/libboost/configuration-dynamic.make)
+
+endif
diff --git a/build/import/libboost/configure b/build/import/libboost/configure
new file mode 100755
index 0000000..9bb9085
--- /dev/null
+++ b/build/import/libboost/configure
@@ -0,0 +1,83 @@
+#! /usr/bin/env bash
+
+# file : build/import/libboost/configure
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+
+# $1 - out config file
+#
+# bld_root - build root
+# project_name - project name
+#
+
+source $bld_root/dialog.bash
+
+
+$echo
+$echo "Configuring external dependency on 'boost libraries' for '$project_name'."
+$echo
+
+$echo
+$echo "Would you like to configure dependency on the installed version"
+$echo "of 'boost libraries' as opposed to the development build?"
+$echo
+
+installed=`read_y_n y`
+
+path=
+type=
+
+if [ "$installed" = "n" ]; then
+
+ version=
+
+ while [ -z "$version" ]; do
+
+ $echo
+ $echo "Please enter the 'boost' root directory."
+ $echo
+
+ root=`read_path --directory --exist`
+
+ version=`sed -e 's/^#define BOOST_LIB_VERSION "\(.*\)"[ ]*$/\1/' -e t -e d \
+$root/boost/version.hpp 2>/dev/null`
+
+ if [ $? != 0 -o -z "$version" ]; then
+
+ version=
+ echo "Unable to read version information from $root/boost/version.hpp"
+ fi
+ done
+
+ $echo
+ $echo "Please select the library type you would like to use:"
+ $echo
+ $echo "(1) archive"
+ $echo "(2) shared object"
+ $echo
+
+ type=`read_option "archive shared" "shared"`
+
+ $echo
+ $echo "For boost 1.34.0 and later, please enter the toolset version"
+ $echo "that is embedded into the library names. For example, for"
+ $echo "gcc34 enter 34. For previous versions of boost leave this"
+ $echo "field blank."
+ $echo
+
+ toolset=
+ read -e -p "[]: " toolset
+fi
+
+echo libboost_installed := $installed >$1
+
+if [ "$installed" = "n" ]; then
+
+ echo libboost_root := $root >>$1
+ echo libboost_type := $type >>$1
+ echo libboost_version := $version >>$1
+ echo libboost_toolset := $toolset >>$1
+
+fi
diff --git a/build/import/libboost/date-time/rules.make b/build/import/libboost/date-time/rules.make
new file mode 100644
index 0000000..f136cc4
--- /dev/null
+++ b/build/import/libboost/date-time/rules.make
@@ -0,0 +1,39 @@
+# file : build/import/libboost/date-time/rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(dcf_root)/import/libboost/%: root := $(libboost_root)
+
+$(dcf_root)/import/libboost/date-time/date-time.l: \
+ | $(dcf_root)/import/libboost/date-time/.
+
+ifeq ($(libboost_type),archive)
+
+$(dcf_root)/import/libboost/date-time/date-time.l: \
+ $(libboost_root)/stage/lib/libboost_date_time-gcc$(libboost_toolset)-$(libboost_version).a
+ @echo $< >$@
+
+else
+
+$(dcf_root)/import/libboost/date-time/date-time.l: \
+ $(libboost_root)/stage/lib/libboost_date_time-gcc$(libboost_toolset)-$(libboost_version).so
+ @echo $< >$@
+ @echo rpath:$(root)/stage/lib >>$@
+
+endif
+
+
+$(dcf_root)/import/libboost/date-time/date-time.l.cpp-options: \
+ | $(dcf_root)/import/libboost/date-time/.
+ @echo include: -I$(root) >$@
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libboost/date-time/date-time.l,\
+rm -f $(dcf_root)/import/libboost/date-time/date-time.l)
+ $(call message,,\
+rm -f $(dcf_root)/import/libboost/date-time/date-time.l.cpp-options)
+
+endif
diff --git a/build/import/libboost/date-time/stub.make b/build/import/libboost/date-time/stub.make
new file mode 100644
index 0000000..5f57a42
--- /dev/null
+++ b/build/import/libboost/date-time/stub.make
@@ -0,0 +1,32 @@
+# file : build/import/libboost/date-time/stub.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(scf_root)/import/libboost/configuration-rules.make,$(dcf_root))
+
+libboost_installed :=
+
+$(call -include,$(dcf_root)/import/libboost/configuration-dynamic.make)
+
+ifdef libboost_installed
+
+ifeq ($(libboost_installed),y)
+
+$(call export,l: -lboost_date_time,cpp_options: )
+
+else
+
+$(call include-once,$(scf_root)/import/libboost/date-time/rules.make,$(dcf_root))
+
+$(call export,\
+ l: $(dcf_root)/import/libboost/date-time/date-time.l,\
+ cpp-options: $(dcf_root)/import/libboost/date-time/date-time.l.cpp-options)
+
+endif
+
+else
+
+.NOTPARALLEL:
+
+endif
diff --git a/build/import/libboost/filesystem/rules.make b/build/import/libboost/filesystem/rules.make
new file mode 100644
index 0000000..8a1666e
--- /dev/null
+++ b/build/import/libboost/filesystem/rules.make
@@ -0,0 +1,41 @@
+# file : build/import/libboost/filesystem/rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+#@@ Should use message everywhere.
+#
+
+$(dcf_root)/import/libboost/%: root := $(libboost_root)
+
+$(dcf_root)/import/libboost/filesystem/filesystem.l: \
+ | $(dcf_root)/import/libboost/filesystem/.
+
+ifeq ($(libboost_type),archive)
+
+$(dcf_root)/import/libboost/filesystem/filesystem.l: \
+ $(libboost_root)/stage/lib/libboost_filesystem-gcc$(libboost_toolset)-$(libboost_version).a
+ @echo $< >$@
+
+else
+
+$(dcf_root)/import/libboost/filesystem/filesystem.l: \
+ $(libboost_root)/stage/lib/libboost_filesystem-gcc$(libboost_toolset)-$(libboost_version).so
+ @echo $< >$@
+ @echo rpath:$(root)/stage/lib >>$@
+
+endif
+
+
+$(dcf_root)/import/libboost/filesystem/filesystem.l.cpp-options: \
+ | $(dcf_root)/import/libboost/filesystem/.
+ @echo include: -I$(root) >$@
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libboost/filesystem/filesystem.l,\
+rm -f $(dcf_root)/import/libboost/filesystem/filesystem.l)
+ $(call message,,rm -f $(dcf_root)/import/libboost/filesystem/filesystem.l.cpp-options)
+
+endif
diff --git a/build/import/libboost/filesystem/stub.make b/build/import/libboost/filesystem/stub.make
new file mode 100644
index 0000000..d5e5500
--- /dev/null
+++ b/build/import/libboost/filesystem/stub.make
@@ -0,0 +1,32 @@
+# file : build/import/libboost/filesystem/stub.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(scf_root)/import/libboost/configuration-rules.make,$(dcf_root))
+
+libboost_installed :=
+
+$(call -include,$(dcf_root)/import/libboost/configuration-dynamic.make)
+
+ifdef libboost_installed
+
+ifeq ($(libboost_installed),y)
+
+$(call export,l: -lboost_filesystem,cpp_options: )
+
+else
+
+$(call include-once,$(scf_root)/import/libboost/filesystem/rules.make,$(dcf_root))
+
+$(call export,\
+ l: $(dcf_root)/import/libboost/filesystem/filesystem.l,\
+ cpp-options: $(dcf_root)/import/libboost/filesystem/filesystem.l.cpp-options)
+
+endif
+
+else
+
+.NOTPARALLEL:
+
+endif
diff --git a/build/import/libboost/regex/rules.make b/build/import/libboost/regex/rules.make
new file mode 100644
index 0000000..10303be
--- /dev/null
+++ b/build/import/libboost/regex/rules.make
@@ -0,0 +1,38 @@
+# file : build/import/libboost/regex/rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(dcf_root)/import/libboost/%: root := $(libboost_root)
+
+$(dcf_root)/import/libboost/regex/regex.l: \
+ | $(dcf_root)/import/libboost/regex/.
+
+ifeq ($(libboost_type),archive)
+
+$(dcf_root)/import/libboost/regex/regex.l: \
+ $(libboost_root)/stage/lib/libboost_regex-gcc$(libboost_toolset)-$(libboost_version).a
+ @echo $< >$@
+
+else
+
+$(dcf_root)/import/libboost/regex/regex.l: \
+ $(libboost_root)/stage/lib/libboost_regex-gcc$(libboost_toolset)-$(libboost_version).so
+ @echo $< >$@
+ @echo rpath:$(root)/stage/lib >>$@
+
+endif
+
+
+$(dcf_root)/import/libboost/regex/regex.l.cpp-options: \
+ | $(dcf_root)/import/libboost/regex/.
+ @echo include: -I$(root) >$@
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libboost/regex/regex.l,\
+rm -f $(dcf_root)/import/libboost/regex/regex.l)
+ $(call message,,rm -f $(dcf_root)/import/libboost/regex/regex.l.cpp-options)
+
+endif
diff --git a/build/import/libboost/regex/stub.make b/build/import/libboost/regex/stub.make
new file mode 100644
index 0000000..9af79d2
--- /dev/null
+++ b/build/import/libboost/regex/stub.make
@@ -0,0 +1,32 @@
+# file : build/import/libboost/regex/stub.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(scf_root)/import/libboost/configuration-rules.make,$(dcf_root))
+
+libboost_installed :=
+
+$(call -include,$(dcf_root)/import/libboost/configuration-dynamic.make)
+
+ifdef libboost_installed
+
+ifeq ($(libboost_installed),y)
+
+$(call export,l: -lboost_regex,cpp_options: )
+
+else
+
+$(call include-once,$(scf_root)/import/libboost/regex/rules.make,$(dcf_root))
+
+$(call export,\
+ l: $(dcf_root)/import/libboost/regex/regex.l,\
+ cpp-options: $(dcf_root)/import/libboost/regex/regex.l.cpp-options)
+
+endif
+
+else
+
+.NOTPARALLEL:
+
+endif
diff --git a/build/import/libboost/serialization/rules.make b/build/import/libboost/serialization/rules.make
new file mode 100644
index 0000000..a413c28
--- /dev/null
+++ b/build/import/libboost/serialization/rules.make
@@ -0,0 +1,38 @@
+# file : build/import/libboost/serialization/rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(dcf_root)/import/libboost/%: root := $(libboost_root)
+
+$(dcf_root)/import/libboost/serialization/serialization.l: \
+ | $(dcf_root)/import/libboost/serialization/.
+
+ifeq ($(libboost_type),archive)
+
+$(dcf_root)/import/libboost/serialization/serialization.l: \
+ $(libboost_root)/stage/lib/libboost_serialization-gcc$(libboost_toolset)-$(libboost_version).a
+ @echo $< >$@
+
+else
+
+$(dcf_root)/import/libboost/serialization/serialization.l: \
+ $(libboost_root)/stage/lib/libboost_serialization-gcc$(libboost_toolset)-$(libboost_version).so
+ @echo $< >$@
+ @echo rpath:$(root)/stage/lib >>$@
+
+endif
+
+
+$(dcf_root)/import/libboost/serialization/serialization.l.cpp-options: \
+ | $(dcf_root)/import/libboost/serialization/.
+ @echo include: -I$(root) >$@
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libboost/serialization/serialization.l,\
+rm -f $(dcf_root)/import/libboost/serialization/serialization.l)
+ $(call message,,rm -f $(dcf_root)/import/libboost/serialization/serialization.l.cpp-options)
+
+endif
diff --git a/build/import/libboost/serialization/stub.make b/build/import/libboost/serialization/stub.make
new file mode 100644
index 0000000..2158e49
--- /dev/null
+++ b/build/import/libboost/serialization/stub.make
@@ -0,0 +1,32 @@
+# file : build/import/libboost/serialization/stub.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(scf_root)/import/libboost/configuration-rules.make,$(dcf_root))
+
+libboost_installed :=
+
+$(call -include,$(dcf_root)/import/libboost/configuration-dynamic.make)
+
+ifdef libboost_installed
+
+ifeq ($(libboost_installed),y)
+
+$(call export,l: -lboost_serialization,cpp_options: )
+
+else
+
+$(call include-once,$(scf_root)/import/libboost/serialization/rules.make,$(dcf_root))
+
+$(call export,\
+ l: $(dcf_root)/import/libboost/serialization/serialization.l,\
+ cpp-options: $(dcf_root)/import/libboost/serialization/serialization.l.cpp-options)
+
+endif
+
+else
+
+.NOTPARALLEL:
+
+endif
diff --git a/build/import/libboost/version b/build/import/libboost/version
new file mode 100644
index 0000000..1d0ba9e
--- /dev/null
+++ b/build/import/libboost/version
@@ -0,0 +1 @@
+0.4.0
diff --git a/build/import/libcult/LICENSE b/build/import/libcult/LICENSE
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/build/import/libcult/LICENSE
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/build/import/libcult/configuration-rules.make b/build/import/libcult/configuration-rules.make
new file mode 100644
index 0000000..dc19df4
--- /dev/null
+++ b/build/import/libcult/configuration-rules.make
@@ -0,0 +1,15 @@
+# file : build/import/libcult/configuration-rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(dcf_root)/import/libcult/configuration-dynamic.make: | $(dcf_root)/import/libcult/.
+ $(call message,,$(scf_root)/import/libcult/configure $@)
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libcult/configuration-dynamic.make,\
+rm -f $(dcf_root)/import/libcult/configuration-dynamic.make)
+
+endif
diff --git a/build/import/libcult/configure b/build/import/libcult/configure
new file mode 100755
index 0000000..afa4c9c
--- /dev/null
+++ b/build/import/libcult/configure
@@ -0,0 +1,55 @@
+#! /usr/bin/env bash
+
+# file : build/import/libcult/configure
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+
+# $1 - out file
+#
+# bld_root - build root
+# project_name - project name
+#
+
+source $bld_root/dialog.bash
+
+
+$echo
+$echo "Configuring external dependency on 'libcult' for '$project_name'."
+$echo
+
+$echo
+$echo "Would you like to configure dependency on the installed "
+$echo "version of 'libcult' as opposed to the development build?"
+$echo
+
+installed=`read_y_n y`
+
+path=
+
+if [ "$installed" = "n" ]; then
+
+$echo
+$echo "Please enter the src_root for 'libcult'."
+$echo
+
+src_root=`read_path --directory --exist`
+
+$echo
+$echo "Please enter the out_root for 'libcult'."
+$echo
+
+out_root=`read_path --directory $src_root`
+
+fi
+
+echo libcult_installed := $installed >$1
+
+if [ "$installed" = "n" ]; then
+
+echo src_root := $src_root >>$1
+echo scf_root := \$\(src_root\)/build >>$1
+echo out_root := $out_root >>$1
+
+fi
diff --git a/build/import/libcult/stub.make b/build/import/libcult/stub.make
new file mode 100644
index 0000000..f5f7691
--- /dev/null
+++ b/build/import/libcult/stub.make
@@ -0,0 +1,30 @@
+# file : build/import/libcult/stub.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(scf_root)/import/libcult/configuration-rules.make,$(dcf_root))
+
+libcult_installed :=
+
+$(call -include,$(dcf_root)/import/libcult/configuration-dynamic.make)
+
+ifdef libcult_installed
+
+ifeq ($(libcult_installed),y)
+
+$(call export,l: -lcult,cpp-options: )
+
+else
+
+# Include export stub.
+#
+$(call include,$(scf_root)/export/libcult/stub.make)
+
+endif
+
+else
+
+.NOTPARALLEL:
+
+endif
diff --git a/build/import/libdbxml/LICENSE b/build/import/libdbxml/LICENSE
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/build/import/libdbxml/LICENSE
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/build/import/libdbxml/configuration-rules.make b/build/import/libdbxml/configuration-rules.make
new file mode 100644
index 0000000..823186c
--- /dev/null
+++ b/build/import/libdbxml/configuration-rules.make
@@ -0,0 +1,15 @@
+# file : build/import/libdbxml/configuration-rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(dcf_root)/import/libdbxml/configuration-dynamic.make: | $(dcf_root)/import/libdbxml/.
+ $(call message,,$(scf_root)/import/libdbxml/configure $@)
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libdbxml/configuration-dynamic.make,\
+rm -f $(dcf_root)/import/libdbxml/configuration-dynamic.make)
+
+endif
diff --git a/build/import/libdbxml/configure b/build/import/libdbxml/configure
new file mode 100755
index 0000000..73ce78c
--- /dev/null
+++ b/build/import/libdbxml/configure
@@ -0,0 +1,58 @@
+#! /usr/bin/env bash
+
+# file : build/import/libdbxml/configure
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+
+# $1 - out config file
+#
+# bld_root - build root
+# project_name - project name
+#
+
+source $bld_root/dialog.bash
+
+
+$echo
+$echo "Configuring external dependency on 'Berkeley DB XML' for '$project_name'."
+$echo
+
+$echo
+$echo "Would you like to configure dependency on the installed version"
+$echo "of 'Berkeley DB XML' as opposed to the development build?"
+$echo
+
+installed=`read_y_n y`
+
+path=
+type=
+
+if [ "$installed" = "n" ]; then
+
+ $echo
+ $echo "Please enter the 'Berkeley DB XML' root directory."
+ $echo
+
+ root=`read_path --directory --exist`
+
+ $echo
+ $echo "Please select the library type you would like to use:"
+ $echo
+ $echo "(1) archive"
+ $echo "(2) shared object"
+ $echo
+
+ type=`read_option "archive shared" "shared"`
+
+fi
+
+echo libdbxml_installed := $installed >$1
+
+if [ "$installed" = "n" ]; then
+
+ echo libdbxml_root := $root >>$1
+ echo libdbxml_type := $type >>$1
+
+fi
diff --git a/build/import/libdbxml/rules.make b/build/import/libdbxml/rules.make
new file mode 100644
index 0000000..ac8118c
--- /dev/null
+++ b/build/import/libdbxml/rules.make
@@ -0,0 +1,42 @@
+# file : build/import/libdbxml/rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+#@@ .l construction is compiler-specific
+#
+
+$(dcf_root)/import/libdbxml/%: root := $(libdbxml_root)
+
+ifeq ($(libdbxml_type),archive)
+
+$(dcf_root)/import/libdbxml/dbxml.l: \
+$(libdbxml_root)/install/lib/libdbxml.a \
+$(libdbxml_root)/install/lib/libxqilla.a \
+$(libdbxml_root)/install/lib/libxerces-c.a \
+$(libdbxml_root)/install/lib/libdb_cxx.a \
+$(libdbxml_root)/install/lib/libdb.a
+
+else
+
+$(dcf_root)/import/libdbxml/dbxml.l: \
+$(libdbxml_root)/install/lib/libdbxml.so \
+$(libdbxml_root)/install/lib/libxqilla.so \
+$(libdbxml_root)/install/lib/libxerces-c.so \
+$(libdbxml_root)/install/lib/libdb_cxx.so \
+$(libdbxml_root)/install/lib/libdb.so
+ @echo $^ | xargs -n 1 echo >$@
+ @echo rpath:$(root)/install/lib >>$@
+endif
+
+$(dcf_root)/import/libdbxml/dbxml.l.cpp-options:
+ @echo include: -I$(root)/install/include >$@
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libdbxml/dbxml.l,\
+rm -f $(dcf_root)/import/libdbxml/dbxml.l)
+ $(call message,,rm -f $(dcf_root)/import/libdbxml/dbxml.l.cpp-options)
+
+endif
diff --git a/build/import/libdbxml/stub.make b/build/import/libdbxml/stub.make
new file mode 100644
index 0000000..f8eb9a3
--- /dev/null
+++ b/build/import/libdbxml/stub.make
@@ -0,0 +1,32 @@
+# file : build/import/libdbxml/stub.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(scf_root)/import/libdbxml/configuration-rules.make,$(dcf_root))
+
+libdbxml_installed :=
+
+$(call -include,$(dcf_root)/import/libdbxml/configuration-dynamic.make)
+
+ifdef libdbxml_installed
+
+ifeq ($(libdbxml_installed),y)
+
+$(call export,l: -ldbxml -lxqilla -lxerces-c -ldb_cxx -ldb,cpp-options: )
+
+else
+
+$(call include-once,$(scf_root)/import/libdbxml/rules.make,$(dcf_root))
+
+$(call export,\
+ l: $(dcf_root)/import/libdbxml/dbxml.l,\
+ cpp-options: $(dcf_root)/import/libdbxml/dbxml.l.cpp-options)
+
+endif
+
+else
+
+.NOTPARALLEL:
+
+endif
diff --git a/build/import/libdbxml/version b/build/import/libdbxml/version
new file mode 100644
index 0000000..9e11b32
--- /dev/null
+++ b/build/import/libdbxml/version
@@ -0,0 +1 @@
+0.3.1
diff --git a/build/import/libxerces-c/LICENSE b/build/import/libxerces-c/LICENSE
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/build/import/libxerces-c/LICENSE
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/build/import/libxerces-c/configuration-rules.make b/build/import/libxerces-c/configuration-rules.make
new file mode 100644
index 0000000..fdb2263
--- /dev/null
+++ b/build/import/libxerces-c/configuration-rules.make
@@ -0,0 +1,15 @@
+# file : build/import/libxerces-c/configuration-rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(dcf_root)/import/libxerces-c/configuration-dynamic.make: | $(dcf_root)/import/libxerces-c/.
+ $(call message,,$(scf_root)/import/libxerces-c/configure $@)
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libxerces-c/configuration-dynamic.make,\
+rm -f $(dcf_root)/import/libxerces-c/configuration-dynamic.make)
+
+endif
diff --git a/build/import/libxerces-c/configure b/build/import/libxerces-c/configure
new file mode 100755
index 0000000..26e56a7
--- /dev/null
+++ b/build/import/libxerces-c/configure
@@ -0,0 +1,73 @@
+#! /usr/bin/env bash
+
+# file : build/import/libxerces-c/configure
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+
+# $1 - out config file
+#
+# bld_root - build root
+# project_name - project name
+#
+
+source $bld_root/dialog.bash
+
+
+$echo
+$echo "Configuring external dependency on 'libxerces-c' for '$project_name'."
+$echo
+
+$echo
+$echo "Would you like to configure dependency on the installed version"
+$echo "of 'libxerces-c' as opposed to the development build?"
+$echo
+
+installed=`read_y_n y`
+
+path=
+type=
+
+if [ "$installed" = "n" ]; then
+
+ version=
+
+ while [ -z "$version" ]; do
+
+ $echo
+ $echo "Please enter the 'libxerces-c' root directory."
+ $echo
+
+ root=`read_path --directory --exist`
+
+ version=`sed -e 's/^VER=\([^_]*\)_\([^_]*\)_\([^_]*\)[ ]*$/\1.\2.\3/' \
+-e t -e d $root/version.incl 2>/dev/null`
+
+ if [ $? != 0 -o -z "$version" ]; then
+
+ version=
+ echo "Unable to read version information from $root/version.incl"
+ fi
+ done
+
+ $echo
+ $echo "Please select the library type you would like to use:"
+ $echo
+ $echo "(1) archive"
+ $echo "(2) shared object"
+ $echo
+
+ type=`read_option "archive shared" "shared"`
+
+fi
+
+echo libxerces_c_installed := $installed >$1
+
+if [ "$installed" = "n" ]; then
+
+ echo libxerces_c_root := $root >>$1
+ echo libxerces_c_type := $type >>$1
+ echo libxerces_c_version := $version >>$1
+
+fi
diff --git a/build/import/libxerces-c/rules.make b/build/import/libxerces-c/rules.make
new file mode 100644
index 0000000..7cdca8c
--- /dev/null
+++ b/build/import/libxerces-c/rules.make
@@ -0,0 +1,52 @@
+# file : build/import/libxerces-c/rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(dcf_root)/import/libxerces-c/%: root := $(libxerces_c_root)
+
+ifneq ($(filter 3.%,$(libxerces_c_version)),)
+
+# 3.x.y
+#
+ifeq ($(libxerces_c_type),archive)
+
+$(dcf_root)/import/libxerces-c/xerces-c.l: $(libxerces_c_root)/src/.libs/libxerces-c.a
+ @echo $< >$@
+else
+
+$(dcf_root)/import/libxerces-c/xerces-c.l: $(libxerces_c_root)/src/.libs/libxerces-c.so
+ @echo $< >$@
+ @echo rpath:$(root)/src/.libs >>$@
+endif
+
+$(dcf_root)/import/libxerces-c/xerces-c.l.cpp-options:
+ @echo include: -I$(root)/src >$@
+else
+
+# 2.x.y
+#
+ifeq ($(libxerces_c_type),archive)
+
+$(dcf_root)/import/libxerces-c/xerces-c.l: $(libxerces_c_root)/lib/libxerces-c.a
+ @echo $< >$@
+else
+
+$(dcf_root)/import/libxerces-c/xerces-c.l: $(libxerces_c_root)/lib/libxerces-c.so
+ @echo $< >$@
+ @echo rpath:$(root)/lib >>$@
+endif
+
+$(dcf_root)/import/libxerces-c/xerces-c.l.cpp-options:
+ @echo include: -I$(root)/include >$@
+endif
+
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libxerces-c/xerces-c.l,\
+rm -f $(dcf_root)/import/libxerces-c/xerces-c.l)
+ $(call message,,rm -f $(dcf_root)/import/libxerces-c/xerces-c.l.cpp-options)
+
+endif
diff --git a/build/import/libxerces-c/stub.make b/build/import/libxerces-c/stub.make
new file mode 100644
index 0000000..d4de5ec
--- /dev/null
+++ b/build/import/libxerces-c/stub.make
@@ -0,0 +1,32 @@
+# file : build/import/libxerces-c/stub.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(scf_root)/import/libxerces-c/configuration-rules.make,$(dcf_root))
+
+libxerces_c_installed :=
+
+$(call -include,$(dcf_root)/import/libxerces-c/configuration-dynamic.make)
+
+ifdef libxerces_c_installed
+
+ifeq ($(libxerces_c_installed),y)
+
+$(call export,l: -lxerces-c,cpp-options: )
+
+else
+
+$(call include-once,$(scf_root)/import/libxerces-c/rules.make,$(dcf_root))
+
+$(call export,\
+ l: $(dcf_root)/import/libxerces-c/xerces-c.l,\
+ cpp-options: $(dcf_root)/import/libxerces-c/xerces-c.l.cpp-options)
+
+endif
+
+else
+
+.NOTPARALLEL:
+
+endif
diff --git a/build/import/libxerces-c/version b/build/import/libxerces-c/version
new file mode 100644
index 0000000..a918a2a
--- /dev/null
+++ b/build/import/libxerces-c/version
@@ -0,0 +1 @@
+0.6.0
diff --git a/build/import/libxqilla/LICENSE b/build/import/libxqilla/LICENSE
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/build/import/libxqilla/LICENSE
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/build/import/libxqilla/configuration-rules.make b/build/import/libxqilla/configuration-rules.make
new file mode 100644
index 0000000..c567c76
--- /dev/null
+++ b/build/import/libxqilla/configuration-rules.make
@@ -0,0 +1,15 @@
+# file : build/import/libxqilla/configuration-rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(dcf_root)/import/libxqilla/configuration-dynamic.make: | $(dcf_root)/import/libxqilla/.
+ $(call message,,$(scf_root)/import/libxqilla/configure $@)
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libxqilla/configuration-dynamic.make,\
+rm -f $(dcf_root)/import/libxqilla/configuration-dynamic.make)
+
+endif
diff --git a/build/import/libxqilla/configure b/build/import/libxqilla/configure
new file mode 100755
index 0000000..71cd954
--- /dev/null
+++ b/build/import/libxqilla/configure
@@ -0,0 +1,57 @@
+#! /usr/bin/env bash
+
+# file : build/import/libxqilla/configure
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+
+# $1 - out config file
+#
+# bld_root - build root
+# project_name - project name
+#
+
+source $bld_root/dialog.bash
+
+
+$echo
+$echo "Configuring external dependency on 'libxqilla' for '$project_name'."
+$echo
+
+$echo
+$echo "Would you like to configure dependency on the installed version"
+$echo "of 'libxqilla' as opposed to the development build?"
+$echo
+
+installed=`read_y_n y`
+
+path=
+type=
+
+if [ "$installed" = "n" ]; then
+
+ $echo
+ $echo "Please enter the 'libxqilla' root directory."
+ $echo
+
+ root=`read_path --directory --exist`
+
+ $echo
+ $echo "Please select the library type you would like to use:"
+ $echo
+ $echo "(1) archive"
+ $echo "(2) shared object"
+ $echo
+
+ type=`read_option "archive shared" "shared"`
+fi
+
+echo libxqilla_installed := $installed >$1
+
+if [ "$installed" = "n" ]; then
+
+ echo libxqilla_root := $root >>$1
+ echo libxqilla_type := $type >>$1
+
+fi
diff --git a/build/import/libxqilla/rules.make b/build/import/libxqilla/rules.make
new file mode 100644
index 0000000..780ac50
--- /dev/null
+++ b/build/import/libxqilla/rules.make
@@ -0,0 +1,30 @@
+# file : build/import/libxqilla/rules.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(dcf_root)/import/libxqilla/%: root := $(libxqilla_root)
+
+ifeq ($(libxqilla_type),archive)
+
+$(dcf_root)/import/libxqilla/xqilla.l: $(libxqilla_root)/.libs/libxqilla.a
+ @echo $< >$@
+else
+
+$(dcf_root)/import/libxqilla/xqilla.l: $(libxqilla_root)/.libs/libxqilla.so
+ @echo $< >$@
+ @echo rpath:$(root)/.libs >>$@
+endif
+
+$(dcf_root)/import/libxqilla/xqilla.l.cpp-options:
+ @echo include: -I$(root)/include >$@
+
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libxqilla/xqilla.l,\
+rm -f $(dcf_root)/import/libxqilla/xqilla.l)
+ $(call message,,rm -f $(dcf_root)/import/libxqilla/xqilla.l.cpp-options)
+
+endif
diff --git a/build/import/libxqilla/stub.make b/build/import/libxqilla/stub.make
new file mode 100644
index 0000000..d24f962
--- /dev/null
+++ b/build/import/libxqilla/stub.make
@@ -0,0 +1,32 @@
+# file : build/import/libxqilla/stub.make
+# author : Boris Kolpackov <boris@kolpackov.net>
+# copyright : Copyright (c) 2005-2009 Boris Kolpackov
+# license : GNU GPL v2; see accompanying LICENSE file
+
+$(call include-once,$(scf_root)/import/libxqilla/configuration-rules.make,$(dcf_root))
+
+libxqilla_installed :=
+
+$(call -include,$(dcf_root)/import/libxqilla/configuration-dynamic.make)
+
+ifdef libxqilla_installed
+
+ifeq ($(libxqilla_installed),y)
+
+$(call export,l: -lxqilla,cpp-options: )
+
+else
+
+$(call include-once,$(scf_root)/import/libxqilla/rules.make,$(dcf_root))
+
+$(call export,\
+ l: $(dcf_root)/import/libxqilla/xqilla.l,\
+ cpp-options: $(dcf_root)/import/libxqilla/xqilla.l.cpp-options)
+
+endif
+
+else
+
+.NOTPARALLEL:
+
+endif
diff --git a/build/import/libxqilla/version b/build/import/libxqilla/version
new file mode 100644
index 0000000..6e8bf73
--- /dev/null
+++ b/build/import/libxqilla/version
@@ -0,0 +1 @@
+0.1.0
diff --git a/build/import/libxsd-frontend/LICENSE b/build/import/libxsd-frontend/LICENSE
new file mode 100644
index 0000000..33b4cbc
--- /dev/null
+++ b/build/import/libxsd-frontend/LICENSE
@@ -0,0 +1,22 @@
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for more details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+In addition, as a special exception, Code Synthesis Tools CC gives
+permission to link this program with the Xerces-C++ library (or with
+modified versions of Xerces-C++ that use the same license as Xerces-C++),
+and distribute linked combinations including the two. You must obey
+the GNU General Public License version 2 in all respects for all of
+the code used other than Xerces-C++. If you modify this copy of the
+program, you may extend this exception to your version of the program,
+but you are not obligated to do so. If you do not wish to do so, delete
+this exception statement from your version.
diff --git a/build/import/libxsd-frontend/configuration-rules.make b/build/import/libxsd-frontend/configuration-rules.make
new file mode 100644
index 0000000..eda6378
--- /dev/null
+++ b/build/import/libxsd-frontend/configuration-rules.make
@@ -0,0 +1,15 @@
+# file : build/import/libxsd-frontend/configuration-rules.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+$(dcf_root)/import/libxsd-frontend/configuration-dynamic.make: | $(dcf_root)/import/libxsd-frontend/.
+ $(call message,,$(scf_root)/import/libxsd-frontend/configure $@)
+
+ifndef %foreign%
+
+disfigure::
+ $(call message,rm $(dcf_root)/import/libxsd-frontend/configuration-dynamic.make,\
+rm -f $(dcf_root)/import/libxsd-frontend/configuration-dynamic.make)
+
+endif
diff --git a/build/import/libxsd-frontend/configure b/build/import/libxsd-frontend/configure
new file mode 100755
index 0000000..1571a27
--- /dev/null
+++ b/build/import/libxsd-frontend/configure
@@ -0,0 +1,55 @@
+#! /usr/bin/env bash
+
+# file : build/import/libxsd-frontend/configure
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+
+# $1 - out file
+#
+# bld_root - build root
+# project_name - project name
+#
+
+source $bld_root/dialog.bash
+
+
+$echo
+$echo "Configuring external dependency on 'libxsd-frontend' for '$project_name'."
+$echo
+
+$echo
+$echo "Would you like to configure dependency on the installed "
+$echo "version of 'libxsd-frontend' as opposed to the development build?"
+$echo
+
+installed=`read_y_n y`
+
+path=
+
+if [ "$installed" = "n" ]; then
+
+$echo
+$echo "Please enter the src_root for 'libxsd-frontend'."
+$echo
+
+src_root=`read_path --directory --exist`
+
+$echo
+$echo "Please enter the out_root for 'libxsd-frontend'."
+$echo
+
+out_root=`read_path --directory $src_root`
+
+fi
+
+echo libxsd_frontend_installed := $installed >$1
+
+if [ "$installed" = "n" ]; then
+
+echo src_root := $src_root >>$1
+echo scf_root := \$\(src_root\)/build >>$1
+echo out_root := $out_root >>$1
+
+fi
diff --git a/build/import/libxsd-frontend/stub.make b/build/import/libxsd-frontend/stub.make
new file mode 100644
index 0000000..f861eb6
--- /dev/null
+++ b/build/import/libxsd-frontend/stub.make
@@ -0,0 +1,30 @@
+# file : build/import/libxsd-frontend/stub.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+$(call include-once,$(scf_root)/import/libxsd-frontend/configuration-rules.make,$(dcf_root))
+
+libxsd_frontend_installed :=
+
+$(call -include,$(dcf_root)/import/libxsd-frontend/configuration-dynamic.make)
+
+ifdef libxsd_frontend_installed
+
+ifeq ($(libxsd_frontend_installed),y)
+
+$(call export,l: -lxsd-frontend -lfrontend-elements -lcult -lboost_filesystem -lxerces-c,cpp_options: )
+
+else
+
+# Include export stub.
+#
+$(call include,$(scf_root)/export/libxsd-frontend/stub.make)
+
+endif
+
+else
+
+.NOTPARALLEL:
+
+endif
diff --git a/build/xsd/parser/xsd-cxx.make b/build/xsd/parser/xsd-cxx.make
new file mode 100644
index 0000000..b31568a
--- /dev/null
+++ b/build/xsd/parser/xsd-cxx.make
@@ -0,0 +1,72 @@
+# file : build/xsd/parser/xsd-cxx.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#@@ Need to use extensions from cxx config.
+#
+
+# C++/Parser mapping.
+#
+ifeq ($(xsd_parser_skel_suffix),)
+xsd_parser_skel_suffix := -pskel
+endif
+
+xsd_parser_pattern := \
+$(out_base)/%$(xsd_parser_skel_suffix).cxx \
+$(out_base)/%$(xsd_parser_skel_suffix).hxx \
+$(out_base)/%$(xsd_parser_skel_suffix).ixx
+
+ifneq ($(xsd_parser_impl_suffix),)
+xsd_parser_pattern += \
+$(out_base)/%$(xsd_parser_impl_suffix).cxx \
+$(out_base)/%$(xsd_parser_impl_suffix).hxx \
+$(out_base)/%-driver.cxx
+endif
+
+
+$(xsd_parser_pattern): xsd := xsd
+$(xsd_parser_pattern): xsd_command := cxx-parser
+
+ops := --skel-file-suffix $(xsd_parser_skel_suffix)
+
+ifneq ($(xsd_pimpl_suffix),)
+ops += --impl-file-suffix $(xsd_parser_impl_suffix)
+endif
+
+$(xsd_parser_pattern): xsd_options := $(ops)
+
+
+.PRECIOUS: $(xsd_parser_pattern)
+
+$(xsd_parser_pattern): $(out_base)/%.xsd | $$(dir $$@).
+ $(call message,xsd $<,$(xsd) $(xsd_command) $(xsd_options) --output-dir $(dir $@) $<)
+
+ifneq ($(out_base),$(src_base))
+
+$(xsd_parser_pattern): $(src_base)/%.xsd | $$(dir $$@).
+ $(call message,xsd $<,$(xsd) $(xsd_command) $(xsd_options) --output-dir $(dir $@) $<)
+
+endif
+
+
+.PHONY: $(out_base)/%$(xsd_parser_skel_suffix).cxx.xsd.clean
+
+$(out_base)/%$(xsd_parser_skel_suffix).cxx.xsd.clean:
+ $(call message,rm $$1,rm -f $$1,$(@:.cxx.xsd.clean=.cxx))
+ $(call message,rm $$1,rm -f $$1,$(@:.cxx.xsd.clean=.hxx))
+ $(call message,rm $$1,rm -f $$1,$(@:.cxx.xsd.clean=.ixx))
+
+ifneq ($(xsd_parser_impl_suffix),)
+.PHONY: $(out_base)/%$(xsd_parser_impl_suffix).cxx.xsd.clean
+
+$(out_base)/%$(xsd_parser_impl_suffix).cxx.xsd.clean:
+ $(call message,rm $$1,rm -f $$1,$(@:.cxx.xsd.clean=.cxx))
+ $(call message,rm $$1,rm -f $$1,$(@:.cxx.xsd.clean=.hxx))
+ $(call message,rm $$1,rm -f $$1,$(out_base)/$*-driver.cxx)
+endif
+
+# Reset the config variables so they won't take effect in other places.
+#
+xsd_parser_skel_suffix :=
+xsd_parser_impl_suffix :=
diff --git a/build/xsd/tree/xsd-cxx.make b/build/xsd/tree/xsd-cxx.make
new file mode 100644
index 0000000..55136db
--- /dev/null
+++ b/build/xsd/tree/xsd-cxx.make
@@ -0,0 +1,43 @@
+# file : build/xsd/tree/xsd-cxx.make
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#@@ Need to use extensions from cxx config.
+#
+
+# C++/Tree mapping.
+#
+xsd_tree_pattern := \
+$(out_base)/%$(xsd_tree_suffix).cxx \
+$(out_base)/%$(xsd_tree_suffix).hxx \
+$(out_base)/%$(xsd_tree_suffix).ixx \
+$(out_base)/%$(xsd_tree_suffix)-fwd.hxx
+
+$(xsd_tree_pattern): xsd := xsd
+$(xsd_tree_pattern): xsd_command := cxx-tree
+$(xsd_tree_pattern): xsd_options :=
+
+.PRECIOUS: $(xsd_tree_pattern)
+
+$(xsd_tree_pattern): $(out_base)/%.xsd | $$(dir $$@).
+ $(call message,xsd $<,$(xsd) $(xsd_command) $(xsd_options) --output-dir $(dir $@) $<)
+
+ifneq ($(out_base),$(src_base))
+
+$(xsd_tree_pattern): $(src_base)/%.xsd | $$(dir $$@).
+ $(call message,xsd $<,$(xsd) $(xsd_command) $(xsd_options) --output-dir $(dir $@) $<)
+
+endif
+
+.PHONY: $(out_base)/%$(xsd_tree_suffix).cxx.xsd.clean
+
+$(out_base)/%$(xsd_tree_suffix).cxx.xsd.clean:
+ $(call message,rm $(@:.cxx.xsd.clean=.cxx),rm -f $(@:.cxx.xsd.clean=.cxx))
+ $(call message,rm $(@:.cxx.xsd.clean=.hxx),rm -f $(@:.cxx.xsd.clean=.hxx))
+ $(call message,rm $(@:.cxx.xsd.clean=.ixx),rm -f $(@:.cxx.xsd.clean=.ixx))
+ $(call message,rm $(@:.cxx.xsd.clean=-fwd.hxx),rm -f $(@:.cxx.xsd.clean=-fwd.hxx))
+
+# Reset the config variables so they won't take effect in other places.
+#
+xsd_tree_suffix :=
diff --git a/documentation/cxx/parser/guide/figure-1.png b/documentation/cxx/parser/guide/figure-1.png
new file mode 100644
index 0000000..15d1723
--- /dev/null
+++ b/documentation/cxx/parser/guide/figure-1.png
Binary files differ
diff --git a/documentation/cxx/parser/guide/figure-1.svg b/documentation/cxx/parser/guide/figure-1.svg
new file mode 100644
index 0000000..d994a79
--- /dev/null
+++ b/documentation/cxx/parser/guide/figure-1.svg
@@ -0,0 +1,373 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no"?>
+<!-- Created with Inkscape (http://www.inkscape.org/) -->
+<svg
+ xmlns:dc="http://purl.org/dc/elements/1.1/"
+ xmlns:cc="http://web.resource.org/cc/"
+ xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns:svg="http://www.w3.org/2000/svg"
+ xmlns="http://www.w3.org/2000/svg"
+ xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
+ xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
+ width="744.09448819"
+ height="1052.3622047"
+ id="svg2"
+ sodipodi:version="0.32"
+ inkscape:version="0.44.1"
+ sodipodi:docbase="/tmp"
+ sodipodi:docname="figure-1.svg"
+ inkscape:export-filename="/home/boris/tmp/figure-1.png"
+ inkscape:export-xdpi="76.195885"
+ inkscape:export-ydpi="76.195885">
+ <defs
+ id="defs4">
+ <marker
+ inkscape:stockid="Arrow1Lend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Lend"
+ style="overflow:visible;">
+ <path
+ id="path2934"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+ transform="scale(0.8) rotate(180) translate(12.5,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Dot_l"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Dot_l"
+ style="overflow:visible">
+ <path
+ id="path2875"
+ d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;marker-end:none"
+ transform="scale(0.8) translate(7.4, 1)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Mend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Mend"
+ style="overflow:visible;">
+ <path
+ id="path2928"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;"
+ transform="scale(0.4) rotate(180) translate(10,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Dot_m"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Dot_m"
+ style="overflow:visible">
+ <path
+ id="path2872"
+ d="M -2.5,-1.0 C -2.5,1.7600000 -4.7400000,4.0 -7.5,4.0 C -10.260000,4.0 -12.5,1.7600000 -12.5,-1.0 C -12.5,-3.7600000 -10.260000,-6.0 -7.5,-6.0 C -4.7400000,-6.0 -2.5,-3.7600000 -2.5,-1.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none;marker-end:none"
+ transform="scale(0.4) translate(7.4, 1)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow1Lstart"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow1Lstart"
+ style="overflow:visible">
+ <path
+ id="path2937"
+ d="M 0.0,0.0 L 5.0,-5.0 L -12.5,0.0 L 5.0,5.0 L 0.0,0.0 z "
+ style="fill-rule:evenodd;stroke:#000000;stroke-width:1.0pt;marker-start:none"
+ transform="scale(0.8) translate(12.5,0)" />
+ </marker>
+ <marker
+ inkscape:stockid="Arrow2Mend"
+ orient="auto"
+ refY="0.0"
+ refX="0.0"
+ id="Arrow2Mend"
+ style="overflow:visible;">
+ <path
+ id="path2910"
+ style="font-size:12.0;fill-rule:evenodd;stroke-width:0.62500000;stroke-linejoin:round;"
+ d="M 8.7185878,4.0337352 L -2.2072895,0.016013256 L 8.7185884,-4.0017078 C 6.9730900,-1.6296469 6.9831476,1.6157441 8.7185878,4.0337352 z "
+ transform="scale(0.6) rotate(180) translate(0,0)" />
+ </marker>
+ </defs>
+ <sodipodi:namedview
+ id="base"
+ pagecolor="#ffffff"
+ bordercolor="#666666"
+ borderopacity="1.0"
+ gridtolerance="10000"
+ guidetolerance="10"
+ objecttolerance="10"
+ inkscape:pageopacity="0.0"
+ inkscape:pageshadow="2"
+ inkscape:zoom="0.98994949"
+ inkscape:cx="328.23027"
+ inkscape:cy="733.01096"
+ inkscape:document-units="px"
+ inkscape:current-layer="layer1"
+ inkscape:window-width="1280"
+ inkscape:window-height="991"
+ inkscape:window-x="154"
+ inkscape:window-y="44" />
+ <metadata
+ id="metadata7">
+ <rdf:RDF>
+ <cc:Work
+ rdf:about="">
+ <dc:format>image/svg+xml</dc:format>
+ <dc:type
+ rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
+ </cc:Work>
+ </rdf:RDF>
+ </metadata>
+ <g
+ inkscape:label="Layer 1"
+ inkscape:groupmode="layer"
+ id="layer1">
+ <g
+ id="g3902">
+ <rect
+ y="194.64178"
+ x="24.142784"
+ height="106.2678"
+ width="149.70432"
+ id="rect1872"
+ style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:5.29799986;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ sodipodi:linespacing="125%"
+ id="text3038"
+ y="219.99649"
+ x="28.284279"
+ style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;color:black;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;font-family:Monospace"
+ xml:space="preserve"><tspan
+ y="219.99649"
+ x="28.284279"
+ id="tspan3064"
+ sodipodi:role="line">class people_pimpl</tspan><tspan
+ y="236.24649"
+ x="28.284279"
+ id="tspan3066"
+ sodipodi:role="line">{</tspan><tspan
+ y="252.49649"
+ x="28.284279"
+ id="tspan3068"
+ sodipodi:role="line"> void </tspan><tspan
+ y="268.74649"
+ x="28.284279"
+ id="tspan3070"
+ sodipodi:role="line"> person ();</tspan><tspan
+ y="284.99649"
+ x="28.284279"
+ id="tspan3072"
+ sodipodi:role="line">};</tspan></text>
+ </g>
+ <g
+ id="g3881">
+ <rect
+ y="124.93772"
+ x="252.43373"
+ height="245.67592"
+ width="180.01601"
+ id="rect5750"
+ style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:9.12976837;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <text
+ sodipodi:linespacing="100%"
+ id="text5752"
+ y="148.27567"
+ x="257.5889"
+ style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:100%;writing-mode:lr-tb;text-anchor:start;color:black;fill:black;fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:1;stroke-linecap:butt;stroke-linejoin:miter;marker:none;marker-start:none;marker-mid:none;marker-end:none;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;visibility:visible;display:inline;overflow:visible;font-family:Monospace"
+ xml:space="preserve"><tspan
+ y="148.27567"
+ x="257.5889"
+ id="tspan5900"
+ sodipodi:role="line">class person_pimpl</tspan><tspan
+ y="161.27567"
+ x="257.5889"
+ id="tspan5902"
+ sodipodi:role="line">{</tspan><tspan
+ y="174.27567"
+ x="257.5889"
+ id="tspan5904"
+ sodipodi:role="line"> void</tspan><tspan
+ y="187.27567"
+ x="257.5889"
+ id="tspan5906"
+ sodipodi:role="line"> first_name (string);</tspan><tspan
+ y="200.27567"
+ x="257.5889"
+ id="tspan5908"
+ sodipodi:role="line" /><tspan
+ y="213.27567"
+ x="257.5889"
+ id="tspan5910"
+ sodipodi:role="line"> void</tspan><tspan
+ y="226.27567"
+ x="257.5889"
+ id="tspan5912"
+ sodipodi:role="line"> last_name (string);</tspan><tspan
+ y="239.27567"
+ x="257.5889"
+ id="tspan5914"
+ sodipodi:role="line" /><tspan
+ y="252.27567"
+ x="257.5889"
+ id="tspan5916"
+ sodipodi:role="line"> void</tspan><tspan
+ y="265.27567"
+ x="257.5889"
+ id="tspan5918"
+ sodipodi:role="line"> gender ();</tspan><tspan
+ y="278.27567"
+ x="257.5889"
+ id="tspan5920"
+ sodipodi:role="line" /><tspan
+ y="291.27567"
+ x="257.5889"
+ id="tspan5922"
+ sodipodi:role="line"> void</tspan><tspan
+ y="304.27567"
+ x="257.5889"
+ id="tspan5924"
+ sodipodi:role="line"> age (short);</tspan><tspan
+ y="317.27567"
+ x="257.5889"
+ id="tspan5926"
+ sodipodi:role="line"> </tspan><tspan
+ y="330.27567"
+ x="257.5889"
+ id="tspan5928"
+ sodipodi:role="line"> void</tspan><tspan
+ y="343.27567"
+ x="257.5889"
+ id="tspan5930"
+ sodipodi:role="line"> post_person ();</tspan><tspan
+ y="356.27567"
+ x="257.5889"
+ id="tspan5932"
+ sodipodi:role="line">};</tspan></text>
+ </g>
+ <g
+ id="g3845">
+ <rect
+ y="77.741814"
+ x="506.28357"
+ height="99.610825"
+ width="151.1286"
+ id="rect5955"
+ style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:5.69227886;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
+ <flowRoot
+ transform="translate(-5.050762,12.10153)"
+ style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace"
+ id="flowRoot5957"
+ xml:space="preserve"><flowRegion
+ id="flowRegion5959"><rect
+ style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace"
+ y="74.534515"
+ x="516.18793"
+ height="88.893425"
+ width="143.44167"
+ id="rect5961" /></flowRegion><flowPara
+ id="flowPara5965">class string_pimpl</flowPara><flowPara
+ id="flowPara5967">{</flowPara><flowPara
+ id="flowPara5969"> string</flowPara><flowPara
+ id="flowPara5971"> post_string ();</flowPara><flowPara
+ id="flowPara5973">};</flowPara><flowPara
+ id="flowPara5975" /></flowRoot> </g>
+ <g
+ id="g3857">
+ <rect
+ style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:5.69227886;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect5977"
+ width="151.1286"
+ height="99.610825"
+ x="506.28357"
+ y="316.15808" />
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot5979"
+ style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace"
+ transform="translate(-5.050761,250.5178)"
+ inkscape:export-filename="/tmp/figure-1.png"
+ inkscape:export-xdpi="546.53815"
+ inkscape:export-ydpi="546.53815"><flowRegion
+ id="flowRegion5981"><rect
+ id="rect5983"
+ width="143.44167"
+ height="88.893425"
+ x="516.18793"
+ y="74.534515"
+ style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" /></flowRegion><flowPara
+ id="flowPara5985">class short_pimpl</flowPara><flowPara
+ id="flowPara5987">{</flowPara><flowPara
+ id="flowPara5989"> short</flowPara><flowPara
+ id="flowPara5991"> post_short ();</flowPara><flowPara
+ id="flowPara5993">};</flowPara><flowPara
+ id="flowPara5995" /></flowRoot> </g>
+ <g
+ id="g3869">
+ <rect
+ style="fill:#c5ddf8;fill-opacity:1;fill-rule:evenodd;stroke:#c5ddf8;stroke-width:5.69227886;stroke-linecap:butt;stroke-linejoin:round;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
+ id="rect6023"
+ width="151.1286"
+ height="99.610825"
+ x="505.7785"
+ y="196.93977" />
+ <flowRoot
+ xml:space="preserve"
+ id="flowRoot6025"
+ style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace"
+ transform="translate(-5.555838,129.2792)"><flowRegion
+ id="flowRegion6027"><rect
+ id="rect6029"
+ width="143.44167"
+ height="88.893425"
+ x="516.18793"
+ y="74.534515"
+ style="font-size:13px;font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;text-align:start;line-height:125%;writing-mode:lr-tb;text-anchor:start;font-family:Monospace" /></flowRegion><flowPara
+ id="flowPara6031">class gender_pimpl</flowPara><flowPara
+ id="flowPara6033">{</flowPara><flowPara
+ id="flowPara6035"> void</flowPara><flowPara
+ id="flowPara6037"> post_gender ();</flowPara><flowPara
+ id="flowPara6039">};</flowPara><flowPara
+ id="flowPara6041" /></flowRoot> </g>
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;display:inline;marker-start:url(#Dot_l);marker-end:url(#Arrow1Lend)"
+ d="M 265.67011,339.69956 L 210.41811,339.34242 L 210.77124,264.14332 L 127.7843,264.4432"
+ id="path6051"
+ inkscape:connector-type="polyline"
+ sodipodi:nodetypes="cccs" />
+ <path
+ sodipodi:nodetypes="cccc"
+ inkscape:connector-type="polyline"
+ id="path6077"
+ d="M 518.20825,383.6412 L 471.23616,384.14628 L 471.4887,300.55615 L 368.70568,300.80869"
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Dot_l);marker-end:url(#Arrow1Lend);stroke-opacity:1;display:inline" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Dot_l);marker-end:url(#Arrow1Lend);stroke-opacity:1;display:inline"
+ d="M 517.1981,262.42289 L 353.55339,262.42289"
+ id="path6081"
+ inkscape:connector-type="polyline"
+ sodipodi:nodetypes="cccs" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-start:url(#Dot_l);marker-end:url(#Arrow1Lend);stroke-opacity:1;display:inline"
+ d="M 518.57143,145.93361 L 470.35714,146.14281 L 470.53572,183.07646 L 431.42857,183.79075"
+ id="path6089"
+ inkscape:connector-type="polyline"
+ sodipodi:nodetypes="cccc" />
+ <path
+ style="fill:none;fill-opacity:0.75;fill-rule:evenodd;stroke:black;stroke-width:1px;stroke-linecap:butt;stroke-linejoin:miter;marker-end:url(#Arrow1Lend);stroke-opacity:1;display:inline"
+ d="M 470.46175,178.43361 L 470.89286,222.36218 L 423.21428,222.71932"
+ id="path6091"
+ inkscape:connector-type="polyline"
+ sodipodi:nodetypes="ccc" />
+ </g>
+</svg>
diff --git a/documentation/cxx/parser/guide/guide.html2ps b/documentation/cxx/parser/guide/guide.html2ps
new file mode 100644
index 0000000..e84bc82
--- /dev/null
+++ b/documentation/cxx/parser/guide/guide.html2ps
@@ -0,0 +1,65 @@
+@html2ps {
+ option {
+ toc: hb;
+ colour: 1;
+ hyphenate: 1;
+ titlepage: 1;
+ }
+
+ datefmt: "%B %Y";
+
+ titlepage {
+ content: "
+<div align=center>
+ <h1><big>C++/Parser Mapping</big></h1>
+ <h1><big>Getting Started Guide</big></h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+</div>
+ <p>Copyright &copy; 2005-2009 CODE SYNTHESIS TOOLS CC</p>
+
+ <p>Permission is granted to copy, distribute and/or modify this
+ document under the terms of the
+ <a href='http://www.codesynthesis.com/licenses/fdl-1.2.txt'>GNU Free
+ Documentation License, version 1.2</a>; with no Invariant Sections,
+ no Front-Cover Texts and no Back-Cover Texts.
+ </p>
+
+ <p>This document is available in the following formats:
+ <a href='http://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/index.xhtml'>XHTML</a>,
+ <a href='http://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.pdf'>PDF</a>, and
+ <a href='http://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.ps'>PostScript</a>.</p>";
+ }
+
+ toc {
+ indent: 2em;
+ }
+
+ header {
+ odd-right: $H;
+ even-left: $H;
+ }
+
+ footer {
+ odd-left: $D;
+ odd-center: $T;
+ odd-right: $N;
+
+ even-left: $N;
+ even-center: $T;
+ even-right: $D;
+ }
+}
+
+body {
+ font-size: 12pt;
+ text-align: justify;
+}
+
+pre {
+ font-size: 10pt;
+}
diff --git a/documentation/cxx/parser/guide/index.xhtml b/documentation/cxx/parser/guide/index.xhtml
new file mode 100644
index 0000000..2c00e18
--- /dev/null
+++ b/documentation/cxx/parser/guide/index.xhtml
@@ -0,0 +1,4126 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+
+<head>
+ <title>C++/Parser Mapping Getting Started Guide</title>
+
+ <meta name="copyright" content="&copy; 2005-2009 Code Synthesis Tools CC"/>
+ <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,parser,validation"/>
+ <meta name="description" content="C++/Parser Mapping Getting Started Guide"/>
+
+ <link rel="stylesheet" type="text/css" href="../../../default.css" />
+
+<style type="text/css">
+ pre {
+ padding : 0 0 0 0em;
+ margin : 0em 0em 0em 0;
+
+ font-size : 102%
+ }
+
+ body {
+ min-width: 48em;
+ }
+
+ h1 {
+ font-weight: bold;
+ font-size: 200%;
+ line-height: 1.2em;
+ }
+
+ h2 {
+ font-weight : bold;
+ font-size : 150%;
+
+ padding-top : 0.8em;
+ }
+
+ h3 {
+ font-size : 140%;
+ padding-top : 0.8em;
+ }
+
+ /* Adjust indentation for three levels. */
+ #container {
+ max-width: 48em;
+ }
+
+ #content {
+ padding: 0 0.1em 0 4em;
+ /*background-color: red;*/
+ }
+
+ #content h1 {
+ margin-left: -2.06em;
+ }
+
+ #content h2 {
+ margin-left: -1.33em;
+ }
+
+ /* Title page */
+
+ #titlepage {
+ padding: 2em 0 1em 0;
+ border-bottom: 1px solid black;
+ }
+
+ #titlepage .title {
+ font-weight: bold;
+ font-size: 200%;
+ text-align: center;
+ }
+
+ #titlepage #first-title {
+ padding: 1em 0 0.4em 0;
+ }
+
+ #titlepage #second-title {
+ padding: 0.4em 0 2em 0;
+ }
+
+ /* Lists */
+ ul.list li {
+ padding-top : 0.3em;
+ padding-bottom : 0.3em;
+ }
+
+ ol.steps {
+ padding-left : 1.8em;
+ }
+
+ ol.steps li {
+ padding-top : 0.3em;
+ padding-bottom : 0.3em;
+ }
+
+
+ div.img {
+ text-align: center;
+ padding: 2em 0 2em 0;
+ }
+
+ /* */
+ dl dt {
+ padding : 0.8em 0 0 0;
+ }
+
+ /* Built-in table */
+ #builtin {
+ margin: 2em 0 2em 0;
+
+ border-collapse : collapse;
+ border : 1px solid;
+ border-color : #000000;
+
+ font-size : 11px;
+ line-height : 14px;
+ }
+
+ #builtin th, #builtin td {
+ border: 1px solid;
+ padding : 0.9em 0.9em 0.7em 0.9em;
+ }
+
+ #builtin th {
+ background : #cde8f6;
+ }
+
+ #builtin td {
+ text-align: left;
+ }
+
+ /* XML Schema features table. */
+ #features {
+ margin: 2em 0 2em 0;
+
+ border-collapse : collapse;
+ border : 1px solid;
+ border-color : #000000;
+
+ font-size : 11px;
+ line-height : 14px;
+ }
+
+ #features th, #features td {
+ border: 1px solid;
+ padding : 0.6em 0.6em 0.6em 0.6em;
+ }
+
+ #features th {
+ background : #cde8f6;
+ }
+
+ #features td {
+ text-align: left;
+ }
+
+
+ /* TOC */
+ table.toc {
+ border-style : none;
+ border-collapse : separate;
+ border-spacing : 0;
+
+ margin : 0.2em 0 0.2em 0;
+ padding : 0 0 0 0;
+ }
+
+ table.toc tr {
+ padding : 0 0 0 0;
+ margin : 0 0 0 0;
+ }
+
+ table.toc * td, table.toc * th {
+ border-style : none;
+ margin : 0 0 0 0;
+ vertical-align : top;
+ }
+
+ table.toc * th {
+ font-weight : normal;
+ padding : 0em 0.1em 0em 0;
+ text-align : left;
+ white-space : nowrap;
+ }
+
+ table.toc * table.toc th {
+ padding-left : 1em;
+ }
+
+ table.toc * td {
+ padding : 0em 0 0em 0.7em;
+ text-align : left;
+ }
+</style>
+
+
+</head>
+
+<body>
+<div id="container">
+ <div id="content">
+
+ <div class="noprint">
+
+ <div id="titlepage">
+ <div class="title" id="first-title">C++/Parser Mapping</div>
+ <div class="title" id="second-title">Getting Started Guide</div>
+
+ <p>Copyright &copy; 2005-2009 CODE SYNTHESIS TOOLS CC</p>
+
+ <p>Permission is granted to copy, distribute and/or modify this
+ document under the terms of the
+ <a href="http://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free
+ Documentation License, version 1.2</a>; with no Invariant Sections,
+ no Front-Cover Texts and no Back-Cover Texts.
+ </p>
+
+ <p>This document is available in the following formats:
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/index.xhtml">XHTML</a>,
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.pdf">PDF</a>, and
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/parser/guide/cxx-parser-guide.ps">PostScript</a>.</p>
+
+ </div>
+
+ <h1>Table of Contents</h1>
+
+ <table class="toc">
+ <tr>
+ <th></th><td><a href="#0">Preface</a>
+ <table class="toc">
+ <tr><th></th><td><a href="#0.1">About This Document</a></td></tr>
+ <tr><th></th><td><a href="#0.2">More Information</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>1</th><td><a href="#1">Introduction</a>
+ <table class="toc">
+ <tr><th>1.1</th><td><a href="#1.1">Mapping Overview</a></td></tr>
+ <tr><th>1.2</th><td><a href="#1.2">Benefits</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>2</th><td><a href="#2">Hello World Example</a>
+ <table class="toc">
+ <tr><th>2.1</th><td><a href="#2.1">Writing XML Document and Schema</a></td></tr>
+ <tr><th>2.2</th><td><a href="#2.2">Translating Schema to C++</a></td></tr>
+ <tr><th>2.3</th><td><a href="#2.3">Implementing Application Logic</a></td></tr>
+ <tr><th>2.4</th><td><a href="#2.4">Compiling and Running</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>3</th><td><a href="#3">Parser Skeletons</a>
+ <table class="toc">
+ <tr><th>3.1</th><td><a href="#3.1">Implementing the Gender Parser</a></td></tr>
+ <tr><th>3.2</th><td><a href="#3.2">Implementing the Person Parser</a></td></tr>
+ <tr><th>3.3</th><td><a href="#3.3">Implementing the People Parser</a></td></tr>
+ <tr><th>3.4</th><td><a href="#3.4">Connecting the Parsers Together</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>4</th><td><a href="#4">Type Maps</a>
+ <table class="toc">
+ <tr><th>4.1</th><td><a href="#4.1">Object Model</a></td></tr>
+ <tr><th>4.2</th><td><a href="#4.2">Type Map File Format</a></td></tr>
+ <tr><th>4.3</th><td><a href="#4.3">Parser Implementations</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>5</th><td><a href="#5">Mapping Configuration</a>
+ <table class="toc">
+ <tr><th>5.1</th><td><a href="#5.1">Character Type</a></td></tr>
+ <tr><th>5.2</th><td><a href="#5.2">Underlying XML Parser</a></td></tr>
+ <tr><th>5.3</th><td><a href="#5.3">XML Schema Validation</a></td></tr>
+ <tr><th>5.4</th><td><a href="#5.4">Support for Polymorphism</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>6</th><td><a href="#6">Built-In XML Schema Type Parsers</a>
+ <table class="toc">
+ <tr><th>6.1</th><td><a href="#6.1"><code>QName</code> Parser</a></td></tr>
+ <tr><th>6.2</th><td><a href="#6.2"><code>NMTOKENS</code> and <code>IDREFS</code> Parsers</a></td></tr>
+ <tr><th>6.3</th><td><a href="#6.3"><code>base64Binary</code> and <code>hexBinary</code> Parsers</a></td></tr>
+ <tr><th>6.4</th><td><a href="#6.4">Time Zone Representation</a></td></tr>
+ <tr><th>6.5</th><td><a href="#6.5"><code>date</code> Parser</a></td></tr>
+ <tr><th>6.6</th><td><a href="#6.6"><code>dateTime</code> Parser</a></td></tr>
+ <tr><th>6.7</th><td><a href="#6.7"><code>duration</code> Parser</a></td></tr>
+ <tr><th>6.8</th><td><a href="#6.8"><code>gDay</code> Parser</a></td></tr>
+ <tr><th>6.9</th><td><a href="#6.9"><code>gMonth</code> Parser</a></td></tr>
+ <tr><th>6.10</th><td><a href="#6.10"><code>gMonthDay</code> Parser</a></td></tr>
+ <tr><th>6.11</th><td><a href="#6.11"><code>gYear</code> Parser</a></td></tr>
+ <tr><th>6.12</th><td><a href="#6.12"><code>gYearMonth</code> Parser</a></td></tr>
+ <tr><th>6.13</th><td><a href="#6.13"><code>time</code> Parser</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>7</th><td><a href="#7">Document Parser and Error Handling</a>
+ <table class="toc">
+ <tr><th>7.1</th><td><a href="#7.1">Xerces-C++ Document Parser</a></td></tr>
+ <tr><th>7.2</th><td><a href="#7.2">Expat Document Parser</a></td></tr>
+ <tr><th>7.3</th><td><a href="#7.3">Error Handling</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th></th><td><a href="#A">Appendix A &mdash; Supported XML Schema Constructs</a></td>
+ </tr>
+
+ </table>
+ </div>
+
+ <h1><a name="0">Preface</a></h1>
+
+ <h2><a name="0.1">About This Document</a></h2>
+
+ <p>The goal of this document is to provide you with an understanding of
+ the C++/Parser programming model and allow you to efficiently evaluate
+ XSD against your project's technical requirements. As such, this
+ document is intended for C++ developers and software architects
+ who are looking for an XML processing solution. Prior experience
+ with XML and C++ is required to understand this document. Basic
+ understanding of XML Schema is advantageous but not expected
+ or required.
+ </p>
+
+
+ <h2><a name="0.2">More Information</a></h2>
+
+ <p>Beyond this guide, you may also find the following sources of
+ information useful:</p>
+
+ <ul class="list">
+ <li><a href="http://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD
+ Compiler Command Line Manual</a></li>
+
+ <li>The <code>examples/cxx/parser/</code> directory in the XSD
+ distribution contains a collection of examples and a README
+ file with an overview of each example.</li>
+
+ <li>The <code>README</code> file in the XSD distribution explains
+ how to compile the examples on various platforms.</li>
+
+ <li>The <a href="http://www.codesynthesis.com/mailman/listinfo/xsd-users">xsd-users</a>
+ mailing list is the place to ask technical questions about XSD and the C++/Parser mapping.
+ Furthermore, the <a href="http://www.codesynthesis.com/pipermail/xsd-users/">archives</a>
+ may already have answers to some of your questions.</li>
+
+ </ul>
+
+ <!-- Introduction -->
+
+ <h1><a name="1">1 Introduction</a></h1>
+
+ <p>Welcome to CodeSynthesis XSD and the C++/Parser mapping. XSD is a
+ cross-platform W3C XML Schema to C++ data binding compiler. C++/Parser
+ is a W3C XML Schema to C++ mapping that represents an XML vocabulary
+ as a set of parser skeletons which you can implement to perform XML
+ processing as required by your application logic.
+ </p>
+
+ <h2><a name="1.1">1.1 Mapping Overview</a></h2>
+
+ <p>The C++/Parser mapping provides event-driven, stream-oriented
+ XML parsing, XML Schema validation, and C++ data binding. It was
+ specifically designed and optimized for high performance and
+ small footprint. Based on the static analysis of the schemas, XSD
+ generates compact, highly-optimized hierarchical state machines
+ that combine data extraction, validation, and even dispatching
+ in a single step. As a result, the generated code is typically
+ 2-10 times faster than general-purpose validating XML parsers
+ while maintaining the lowest static and dynamic memory footprints.
+ </p>
+
+ <p>To speed up application development, the C++/Parser mapping
+ can be instructed to generate sample parser implementations
+ and a test driver which can then be filled with the application
+ logic code. The mapping also provides a wide range of
+ mechanisms for controlling and customizing the generated code.</p>
+
+ <p>The next chapter shows how to create a simple application that uses
+ the C++/Parser mapping to parse, validate, and extract data from a
+ simple XML document. The following chapters show how to
+ use the C++/Parser mapping in more detail.</p>
+
+ <h2><a name="1.2">1.2 Benefits</a></h2>
+
+ <p>Traditional XML access APIs such as Document Object Model (DOM)
+ or Simple API for XML (SAX) have a number of drawbacks that
+ make them less suitable for creating robust and maintainable
+ XML processing applications. These drawbacks include:
+ </p>
+
+ <ul class="list">
+ <li>Generic representation of XML in terms of elements, attributes,
+ and text forces an application developer to write a substantial
+ amount of bridging code that identifies and transforms pieces
+ of information encoded in XML to a representation more suitable
+ for consumption by the application logic.</li>
+
+ <li>String-based flow control defers error detection to runtime.
+ It also reduces code readability and maintainability.</li>
+
+ <li>Lack of type safety because the data is represented
+ as text.</li>
+
+ <li>Resulting applications are hard to debug, change, and
+ maintain.</li>
+ </ul>
+
+ <p>In contrast, statically-typed, vocabulary-specific parser
+ skeletons produced by the C++/Parser mapping allow you to
+ operate in your domain terms instead of the generic elements,
+ attributes, and text. Static typing helps catch errors at
+ compile-time rather than at run-time. Automatic code generation
+ frees you for more interesting tasks (such as doing something
+ useful with the information stored in the XML documents) and
+ minimizes the effort needed to adapt your applications to
+ changes in the document structure. To summarize, the C++/Parser
+ mapping has the following key advantages over generic XML
+ access APIs:</p>
+
+ <ul class="list">
+ <li><b>Ease of use.</b> The generated code hides all the complexity
+ associated with recreating the document structure, maintaining the
+ dispatch state, and converting the data from the text representation
+ to data types suitable for manipulation by the application logic.
+ Parser skeletons also provide a convenient mechanism for building
+ custom in-memory representations.</li>
+
+ <li><b>Natural representation.</b> The generated parser skeletons
+ implement parser callbacks as virtual functions with names
+ corresponding to elements and attributes in XML. As a result,
+ you process the XML data using your domain vocabulary instead
+ of generic elements, attributes, and text.
+ </li>
+
+ <li><b>Concise code.</b> With a separate parser skeleton for each
+ XML Schema type, the application implementation is
+ simpler and thus easier to read and understand.</li>
+
+ <li><b>Safety.</b> The XML data is delivered to parser callbacks as
+ statically typed objects. The parser callbacks themselves are virtual
+ functions. This helps catch programming errors at compile-time
+ rather than at runtime.</li>
+
+ <li><b>Maintainability.</b> Automatic code generation minimizes the
+ effort needed to adapt the application to changes in the
+ document structure. With static typing, the C++ compiler
+ can pin-point the places in the application code that need to be
+ changed.</li>
+
+ <li><b>Efficiency.</b> The generated parser skeletons combine
+ data extraction, validation, and even dispatching in a single
+ step. This makes them much more efficient than traditional
+ architectures with separate stages for validation and data
+ extraction/dispatch.</li>
+ </ul>
+
+ <!-- Hello World Parser -->
+
+
+ <h1><a name="2">2 Hello World Example</a></h1>
+
+ <p>In this chapter we will examine how to parse a very simple XML
+ document using the XSD-generated C++/Parser skeletons.
+ The code presented in this chapter is based on the <code>hello</code>
+ example which can be found in the <code>examples/cxx/parser/</code>
+ directory of the XSD distribution.</p>
+
+ <h2><a name="2.1">2.1 Writing XML Document and Schema</a></h2>
+
+ <p>First, we need to get an idea about the structure
+ of the XML documents we are going to process. Our
+ <code>hello.xml</code>, for example, could look like this:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0"?>
+&lt;hello>
+
+ &lt;greeting>Hello&lt;/greeting>
+
+ &lt;name>sun&lt;/name>
+ &lt;name>moon&lt;/name>
+ &lt;name>world&lt;/name>
+
+&lt;/hello>
+ </pre>
+
+ <p>Then we can write a description of the above XML in the
+ XML Schema language and save it into <code>hello.xsd</code>:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0"?>
+&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ &lt;xs:complexType name="hello">
+ &lt;xs:sequence>
+ &lt;xs:element name="greeting" type="xs:string"/>
+ &lt;xs:element name="name" type="xs:string" maxOccurs="unbounded"/>
+ &lt;/xs:sequence>
+ &lt;/xs:complexType>
+
+ &lt;xs:element name="hello" type="hello"/>
+
+&lt;/xs:schema>
+ </pre>
+
+ <p>Even if you are not familiar with XML Schema, it
+ should be easy to connect declarations in <code>hello.xsd</code>
+ to elements in <code>hello.xml</code>. The <code>hello</code> type
+ is defined as a sequence of the nested <code>greeting</code> and
+ <code>name</code> elements. Note that the term sequence in XML
+ Schema means that elements should appear in a particular order
+ as opposed to appearing multiple times. The <code>name</code>
+ element has its <code>maxOccurs</code> property set to
+ <code>unbounded</code> which means it can appear multiple times
+ in an XML document. Finally, the globally-defined <code>hello</code>
+ element prescribes the root element for our vocabulary. For an
+ easily-approachable introduction to XML Schema refer to
+ <a href="http://www.w3.org/TR/xmlschema-0/">XML Schema Part 0:
+ Primer</a>.</p>
+
+ <p>The above schema is a specification of our XML vocabulary; it tells
+ everybody what valid documents of our XML-based language should look
+ like. The next step is to compile this schema to generate
+ the object model and parsing functions.</p>
+
+ <h2><a name="2.2">2.2 Translating Schema to C++</a></h2>
+
+ <p>Now we are ready to translate our <code>hello.xsd</code> to C++ parser
+ skeletons. To do this we invoke the XSD compiler from a terminal
+ (UNIX) or a command prompt (Windows):
+ </p>
+
+ <pre class="terminal">
+$ xsd cxx-parser --xml-parser expat hello.xsd
+ </pre>
+
+ <p>The <code>--xml-parser</code> option indicates that we want to
+ use Expat as the underlying XML parser (see <a href="#5.2">Section
+ 5.2, "Underlying XML Parser"</a>). The XSD compiler produces two
+ C++ files: <code>hello-pskel.hxx</code> and <code>hello-pskel.cxx</code>.
+ The following code fragment is taken from <code>hello-pskel.hxx</code>;
+ it should give you an idea about what gets generated:
+ </p>
+
+ <pre class="c++">
+class hello_pskel
+{
+public:
+ // Parser callbacks. Override them in your implementation.
+ //
+ virtual void
+ pre ();
+
+ virtual void
+ greeting (const std::string&amp;);
+
+ virtual void
+ name (const std::string&amp;);
+
+ virtual void
+ post_hello ();
+
+ // Parser construction API.
+ //
+ void
+ greeting_parser (xml_schema::string_pskel&amp;);
+
+ void
+ name_parser (xml_schema::string_pskel&amp;);
+
+ void
+ parsers (xml_schema::string_pskel&amp; /* greeting */,
+ xml_schema::string_pskel&amp; /* name */);
+
+private:
+ ...
+};
+ </pre>
+
+ <p>The first four member functions shown above are called parser
+ callbacks. You would normally override them in your implementation
+ of the parser to do something useful. Let's go through all of
+ them one by one.</p>
+
+ <p>The <code>pre()</code> function is an initialization callback. It is
+ called when a new element of type <code>hello</code> is about
+ to be parsed. You would normally use this function to allocate a new
+ instance of the resulting type or clear accumulators that are used
+ to gather information during parsing. The default implementation
+ of this function does nothing.</p>
+
+ <p>The <code>post_hello()</code> function is a finalization callback. Its
+ name is constructed by adding the parser skeleton name to the
+ <code>post_</code> prefix. The finalization callback is called when
+ parsing of the element is complete and the result, if any, should
+ be returned. Note that in our case the return type of
+ <code>post_hello()</code> is <code>void</code> which means there
+ is nothing to return. More on parser return types later.
+ </p>
+
+ <p>You may be wondering why the finalization callback is called
+ <code>post_hello()</code> instead of <code>post()</code> just
+ like <code>pre()</code>. The reason for this is that
+ finalization callbacks can have different return types and
+ result in function signature clashes across inheritance
+ hierarchies. To prevent this the signatures of finalization
+ callbacks are made unique by adding the type name to their names.</p>
+
+ <p>The <code>greeting()</code> and <code>name()</code> functions are
+ called when the <code>greeting</code> and <code>name</code> elements
+ have been parsed, respectively. Their arguments are of type
+ <code>std::string</code> and contain the data extracted from XML.</p>
+
+ <p>The last three functions are for connecting parsers to each other.
+ For example, there is a predefined parser for built-in XML Schema type
+ <code>string</code> in the XSD runtime. We will be using
+ it to parse the contents of <code>greeting</code> and
+ <code>name</code> elements, as shown in the next section.</p>
+
+ <h2><a name="2.3">2.3 Implementing Application Logic</a></h2>
+
+ <p>At this point we have all the parts we need to do something useful
+ with the information stored in our XML document. The first step is
+ to implement the parser:
+ </p>
+
+ <pre class="c++">
+#include &lt;iostream>
+#include "hello-pskel.hxx"
+
+class hello_pimpl: public hello_pskel
+{
+public:
+ virtual void
+ greeting (const std::string&amp; g)
+ {
+ greeting_ = g;
+ }
+
+ virtual void
+ name (const std::string&amp; n)
+ {
+ std::cout &lt;&lt; greeting_ &lt;&lt; ", " &lt;&lt; n &lt;&lt; "!" &lt;&lt; std::endl;
+ }
+
+private:
+ std::string greeting_;
+};
+ </pre>
+
+ <p>We left both <code>pre()</code> and <code>post_hello()</code> with the
+ default implementations; we don't have anything to initialize or
+ return. The rest is pretty straightforward: we store the greeting
+ in a member variable and later, when parsing names, use it to
+ say hello.</p>
+
+ <p>An observant reader my ask what happens if the <code>name</code>
+ element comes before <code>greeting</code>? Don't we need to
+ make sure <code>greeting_</code> was initialized and report
+ an error otherwise? The answer is no, we don't have to do
+ any of this. The <code>hello_pskel</code> parser skeleton
+ performs validation of XML according to the schema from which
+ it was generated. As a result, it will check the order
+ of the <code>greeting</code> and <code>name</code> elements
+ and report an error if it is violated.</p>
+
+ <p>Now it is time to put this parser implementation to work:</p>
+
+ <pre class="c++">
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ 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.
+ //
+ 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&amp; e)
+ {
+ cerr &lt;&lt; e &lt;&lt; endl;
+ return 1;
+ }
+}
+ </pre>
+
+ <p>The first part of this code snippet instantiates individual parsers
+ and assembles them into a complete vocabulary parser.
+ <code>xml_schema::string_pimpl</code> is an implementation of a parser
+ for built-in XML Schema type <code>string</code>. It is provided by
+ the XSD runtime along with parsers for other built-in types (for
+ more information on the built-in parsers see <a href="#6">Chapter 6,
+ "Built-In XML Schema Type Parsers"</a>). We use <code>string_pimpl</code>
+ to parse the <code>greeting</code> and <code>name</code> elements as
+ indicated by the calls to <code>greeting_parser()</code> and
+ <code>name_parser()</code>.
+ </p>
+
+ <p>Then we instantiate a document parser (<code>doc_p</code>). The
+ first argument to its constructor is the parser for
+ the root element (<code>hello_p</code> in our case). The
+ second argument is the root element name.
+ </p>
+
+ <p>The final piece is the calls to <code>pre()</code>, <code>parse()</code>,
+ and <code>post_hello()</code>. The call to <code>parse()</code>
+ perform the actual XML parsing while the calls to <code>pre()</code> and
+ <code>post_hello()</code> make sure that the parser for the root
+ element can perform proper initialization and cleanup.</p>
+
+ <p>While our parser implementation and test driver are pretty small and
+ easy to write by hand, for bigger XML vocabularies it can be a
+ substantial effort. To help with this task XSD can automatically
+ generate sample parser implementations and a test driver from your
+ schemas. You can request the generation of a sample implementation with
+ empty function bodies by specifying the <code>--generate-noop-impl</code>
+ option. Or you can generate a sample implementation that prints the
+ data store in XML by using the <code>--generate-print-impl</code>
+ option. To request the generation of a test driver you can use the
+ <code>--generate-test-driver</code> option. For more information
+ on these options refer to the
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD
+ Compiler Command Line Manual</a>. The <code>'generated'</code> example
+ in the XSD distribution shows the sample implementation generation
+ feature in action.</p>
+
+
+ <h2><a name="2.4">2.4 Compiling and Running</a></h2>
+
+ <p>After saving all the parts from the previous section in
+ <code>driver.cxx</code>, we are ready to compile our first
+ application and run it on the test XML document. On a UNIX
+ system this can be done with the following commands:
+ </p>
+
+ <pre class="terminal">
+$ c++ -I.../libxsd -c driver.cxx hello-pskel.cxx
+$ c++ -o driver driver.o hello-pskel.o -lexpat
+$ ./driver hello.xml
+Hello, sun!
+Hello, moon!
+Hello, world!
+ </pre>
+
+ <p>Here <code>.../libxsd</code> represents the path to the
+ <code>libxsd</code> directory in the XSD distribution.
+ We can also test the error handling. To test XML well-formedness
+ checking, we can try to parse <code>hello-pskel.hxx</code>:</p>
+
+ <pre class="terminal">
+$ ./driver hello-pskel.hxx
+hello-pskel.hxx:1:0: not well-formed (invalid token)
+ </pre>
+
+ <p>We can also try to parse a valid XML but not from our
+ vocabulary, for example <code>hello.xsd</code>:</p>
+
+ <pre class="terminal">
+$ ./driver hello.xsd
+hello.xsd:2:0: expected element 'hello' instead of
+'http://www.w3.org/2001/XMLSchema#schema'
+ </pre>
+
+
+ <!-- Chapater 3 -->
+
+
+ <h1><a name="3">3 Parser Skeletons</a></h1>
+
+ <p>As we have seen in the previous chapter, the XSD compiler generates
+ a parser skeleton class for each type defined in XML Schema. In
+ this chapter we will take a closer look at different functions
+ that comprise a parser skeleton as well as the way to connect
+ our implementations of these parser skeletons to create a complete
+ parser.</p>
+
+ <p>In this and subsequent chapters we will use the following schema
+ that describes a collection of person records. We save it in
+ <code>people.xsd</code>:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0"?>
+&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ &lt;xs:simpleType name="gender">
+ &lt;xs:restriction base="xs:string">
+ &lt;xs:enumeration value="male"/>
+ &lt;xs:enumeration value="female"/>
+ &lt;/xs:restriction>
+ &lt;/xs:simpleType>
+
+ &lt;xs:complexType name="person">
+ &lt;xs:sequence>
+ &lt;xs:element name="first-name" type="xs:string"/>
+ &lt;xs:element name="last-name" type="xs:string"/>
+ &lt;xs:element name="gender" type="gender"/>
+ &lt;xs:element name="age" type="xs:short"/>
+ &lt;/xs:sequence>
+ &lt;/xs:complexType>
+
+ &lt;xs:complexType name="people">
+ &lt;xs:sequence>
+ &lt;xs:element name="person" type="person" maxOccurs="unbounded"/>
+ &lt;/xs:sequence>
+ &lt;/xs:complexType>
+
+ &lt;xs:element name="people" type="people"/>
+
+&lt;/xs:schema>
+ </pre>
+
+ <p>A sample XML instance to go along with this schema is saved
+ in <code>people.xml</code>:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0"?>
+&lt;people>
+ &lt;person>
+ &lt;first-name>John&lt;/first-name>
+ &lt;last-name>Doe&lt;/last-name>
+ &lt;gender>male&lt;/gender>
+ &lt;age>32&lt;/age>
+ &lt;/person>
+ &lt;person>
+ &lt;first-name>Jane&lt;/first-name>
+ &lt;last-name>Doe&lt;/last-name>
+ &lt;gender>female&lt;/gender>
+ &lt;age>28&lt;/age>
+ &lt;/person>
+&lt;/people>
+ </pre>
+
+ <p>Compiling <code>people.xsd</code> with the XSD compiler results
+ in three parser skeletons being generated: <code>gender_pskel</code>,
+ <code>person_pskel</code>, and <code>people_pskel</code>. We are going
+ to examine and implement each of them in the subsequent sections.</p>
+
+ <h2><a name="3.1">3.1 Implementing the Gender Parser</a></h2>
+
+ <p>The generated <code>gender_pskel</code> parser skeleton looks like
+ this:</p>
+
+ <pre class="c++">
+class gender_pskel: public virtual xml_schema::string_pskel
+{
+public:
+ // Parser callbacks. Override them in your implementation.
+ //
+ virtual void
+ pre ();
+
+ virtual void
+ post_gender ();
+};
+ </pre>
+
+ <p>Notice that <code>gender_pskel</code> inherits from
+ <code>xml_schema::string_skel</code> which is a parser skeleton
+ for built-in XML Schema type <code>string</code> and is
+ predefined in the XSD runtime library. This is an example
+ of the general rule that parser skeletons follow: if a type
+ in XML Schema inherits from another then there will be an
+ equivalent inheritance between the corresponding parser
+ skeleton classes.</p>
+
+ <p>The <code>pre()</code> and <code>post_gender()</code> callbacks
+ should look familiar from the previous chapter. Let's now
+ implement the parser. Our implementation will simply print
+ the gender to <code>cout</code>:</p>
+
+
+ <pre class="c++">
+class gender_pimpl: public gender_pskel,
+ public xml_schema::string_pimpl
+{
+public:
+ virtual void
+ post_gender ()
+ {
+ std::string s = post_string ();
+ cout &lt;&lt; "gender: " &lt;&lt; s &lt;&lt; endl;
+ }
+};
+ </pre>
+
+ <p>While the code is quite short, there is a lot going on. First,
+ notice that we are inheriting from <code>gender_pskel</code> <em>and</em>
+ from <code>xml_schema::string_pimpl</code>. We've encountered
+ <code>xml_schema::string_pimpl</code> already; it is an
+ implementation of the <code>xml_schema::string_pskel</code> parser
+ skeleton for built-in XML Schema type <code>string</code>.</p>
+
+ <p>This is another common theme in the C++/Parser programming model:
+ reusing implementations of the base parsers in the derived ones with
+ the C++ mixin idiom. In our case, <code>string_pimpl</code> will
+ do all the dirty work of extracting the data and we can just get
+ it at the end with the call to <code>post_string()</code>.</p>
+
+ <p>In case you are curious, here is what
+ <code>xml_schema::string_pskel</code> and
+ <code>xml_schema::string_pimpl</code> look like:</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class string_pskel: public simple_content
+ {
+ public:
+ virtual std::string
+ post_string () = 0;
+ };
+
+ class string_pimpl: public virtual string_pskel
+ {
+ public:
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const xml_schema::ro_string&amp;);
+
+ virtual std::string
+ post_string ();
+
+ protected:
+ std::string str_;
+ };
+}
+ </pre>
+
+ <p>There are three new pieces in this code that we haven't seen yet.
+ They are the <code>simple_content</code> class as well as
+ the <code>_pre()</code> and <code>_characters()</code> functions.
+ The <code>simple_content</code> class is defined in the XSD
+ runtime and is a base class for all parser skeletons that conform
+ to the simple content model in XML Schema. Types with the
+ simple content model cannot have nested elements&mdash;only text
+ and attributes. There is also the <code>complex_content</code>
+ class which corresponds to the complex content mode (types with
+ nested elements, for example, <code>person</code> from
+ <code>people.xsd</code>).</p>
+
+ <p>The <code>_pre()</code> function is a parser callback. Remember we
+ talked about the <code>pre()</code> and <code>post_*()</code> callbacks
+ in the previous chapter? There are actually two more callbacks
+ with similar roles: <code>_pre()</code> and <code>_post ()</code>.
+ As a result, each parser skeleton has four special callbacks:</p>
+
+ <pre class="c++">
+ virtual void
+ pre ();
+
+ virtual void
+ _pre ();
+
+ virtual void
+ _post ();
+
+ virtual void
+ post_name ();
+ </pre>
+
+ <p><code>pre()</code> and <code>_pre()</code> are initialization
+ callbacks. They get called in that order before a new instance of the type
+ is about to be parsed. The difference between <code>pre()</code> and
+ <code>_pre()</code> is conventional: <code>pre()</code> can
+ be completely overridden by a derived parser. The derived
+ parser can also override <code>_pre()</code> but has to always call
+ the original version. This allows you to partition initialization
+ into customizable and required parts.</p>
+
+ <p>Similarly, <code>_post()</code> and <code>post_name()</code> are
+ finalization callbacks with exactly the same semantics:
+ <code>post_name()</code> can be completely overridden by the derived
+ parser while the original <code>_post()</code> should always be called.
+ </p>
+
+ <p>The final bit we need to discuss in this section is the
+ <code>_characters()</code> function. As you might have guessed, it
+ is also a callback. A low-level one that delivers raw character content
+ for the type being parsed. You will seldom need to use this callback
+ directly. Using implementations for the built-in parsers provided by
+ the XSD runtime is usually a simpler and more convenient
+ alternative.</p>
+
+ <p>At this point you might be wondering why some <code>post_*()</code>
+ callbacks, for example <code>post_string()</code>, return some data
+ while others, for example <code>post_gender()</code>, have
+ <code>void</code> as a return type. This is a valid concern
+ and it will be addressed in the next chapter.</p>
+
+ <h2><a name="3.2">3.2 Implementing the Person Parser</a></h2>
+
+ <p>The generated <code>person_pskel</code> parser skeleton looks like
+ this:</p>
+
+ <pre class="c++">
+class person_pskel: public xml_schema::complex_content
+{
+public:
+ // Parser callbacks. Override them in your implementation.
+ //
+ virtual void
+ pre ();
+
+ virtual void
+ first_name (const std::string&amp;);
+
+ virtual void
+ last_name (const std::string&amp;);
+
+ virtual void
+ gender ();
+
+ virtual void
+ age (short);
+
+ virtual void
+ post_person ();
+
+ // Parser construction API.
+ //
+ void
+ first_name_parser (xml_schema::string_pskel&amp;);
+
+ void
+ last_name_parser (xml_schema::string_pskel&amp;);
+
+ void
+ gender_parser (gender_pskel&amp;);
+
+ void
+ age_parser (xml_schema::short_pskel&amp;);
+
+ void
+ parsers (xml_schema::string_pskel&amp; /* first-name */,
+ xml_schema::string_pskel&amp; /* last-name */,
+ gender_pskel&amp; /* gender */,
+ xml_schema::short_pskel&amp; /* age */);
+};
+ </pre>
+
+
+ <p>As you can see, we have a parser callback for each of the nested
+ elements found in the <code>person</code> XML Schema type.
+ The implementation of this parser is straightforward:</p>
+
+ <pre class="c++">
+class person_pimpl: public person_pskel
+{
+public:
+ virtual void
+ first_name (const std::string&amp; n)
+ {
+ cout &lt;&lt; "first: " &lt;&lt; f &lt;&lt; endl;
+ }
+
+ virtual void
+ last_name (const std::string&amp; l)
+ {
+ cout &lt;&lt; "last: " &lt;&lt; l &lt;&lt; endl;
+ }
+
+ virtual void
+ age (short a)
+ {
+ cout &lt;&lt; "age: " &lt;&lt; a &lt;&lt; endl;
+ }
+};
+ </pre>
+
+ <p>Notice that we didn't override the <code>gender()</code> callback
+ because all the printing is done by <code>gender_pimpl</code>.</p>
+
+
+ <h2><a name="3.3">3.3 Implementing the People Parser</a></h2>
+
+ <p>The generated <code>people_pskel</code> parser skeleton looks like
+ this:</p>
+
+ <pre class="c++">
+class people_pskel: public xml_schema::complex_content
+{
+public:
+ // Parser callbacks. Override them in your implementation.
+ //
+ virtual void
+ pre ();
+
+ virtual void
+ person ();
+
+ virtual void
+ post_people ();
+
+ // Parser construction API.
+ //
+ void
+ person_parser (person_pskel&amp;);
+
+ void
+ parsers (person_pskel&amp; /* person */);
+};
+ </pre>
+
+ <p>The <code>person()</code> callback will be called after parsing each
+ <code>person</code> element. While <code>person_pimpl</code> does
+ all the printing, one useful thing we can do in this callback is to
+ print an extra newline after each person record so that our
+ output is more readable:</p>
+
+ <pre class="c++">
+class people_pimpl: public people_pskel
+{
+public:
+ virtual void
+ person ()
+ {
+ cout &lt;&lt; endl;
+ }
+};
+ </pre>
+
+ <p>Now it is time to put everything together.</p>
+
+
+ <h2><a name="3.4">3.4 Connecting the Parsers Together</a></h2>
+
+ <p>At this point we have all the individual parsers implemented
+ and can proceed to assemble them into a complete parser
+ for our XML vocabulary. The first step is to instantiate
+ all the individual parsers that we will need:</p>
+
+ <pre class="c++">
+xml_schema::short_pimpl short_p;
+xml_schema::string_pimpl string_p;
+
+gender_pimpl gender_p;
+person_pimpl person_p;
+people_pimpl people_p;
+ </pre>
+
+ <p>Notice that our schema uses two built-in XML Schema types:
+ <code>string</code> for the <code>first-name</code> and
+ <code>last-name</code> elements as well as <code>short</code>
+ for <code>age</code>. We will use predefined parsers that
+ come with the XSD runtime to handle these types. The next
+ step is to connect all the individual parsers. We do this
+ with the help of functions defined in the parser
+ skeletons and marked with the "Parser Construction API"
+ comment. One way to do it is to connect each individual
+ parser by calling the <code>*_parser()</code> functions:</p>
+
+ <pre class="c++">
+person_p.first_name_parser (string_p);
+person_p.last_name_parser (string_p);
+person_p.gender_parser (gender_p);
+person_p.age_parser (short_p);
+
+people_p.person_parser (person_p);
+ </pre>
+
+ <p>You might be wondering what happens if you do not provide
+ a parser by not calling one of the <code>*_parser()</code> functions.
+ In that case the corresponding XML content will be skipped,
+ including validation. This is an efficient way to ignore parts
+ of the document that you are not interested in.</p>
+
+
+ <p>An alternative, shorter, way to connect the parsers is by using
+ the <code>parsers()</code> functions which connects all the parsers
+ for a given type at once:</p>
+
+ <pre class="c++">
+person_p.parsers (string_p, string_p, gender_p, short_p);
+people_p.parsers (person_p);
+ </pre>
+
+ <p>The following figure illustrates the resulting connections. Notice
+ the correspondence between return types of the <code>post_*()</code>
+ functions and argument types of element callbacks that are connected
+ by the arrows.</p>
+
+ <!-- align=center is needed for html2ps -->
+ <div class="img" align="center"><img src="figure-1.png"/></div>
+
+ <p>The last step is the construction of the document parser and
+ invocation of the complete parser on our sample XML instance:</p>
+
+ <pre class="c++">
+xml_schema::document doc_p (people_p, "people");
+
+people_p.pre ();
+doc_p.parse ("people.xml");
+people_p.post_people ();
+ </pre>
+
+ <p>Let's consider <code>xml_schema::document</code> in
+ more detail. While the exact definition of this class
+ varies depending on the underlying parser selected,
+ here is the common part:</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class document
+ {
+ public:
+ document (xml_schema::parser_base&amp;,
+ const std::string&amp; root_element_name,
+ bool polymorphic = false);
+
+ document (xml_schema::parser_base&amp;,
+ const std::string&amp; root_element_namespace,
+ const std::string&amp; root_element_name,
+ bool polymorphic = false);
+
+ void
+ parse (const std::string&amp; file);
+
+ void
+ parse (std::istream&amp;);
+
+ ...
+
+ };
+}
+ </pre>
+
+ <p><code>xml_schema::document</code> is a root parser for
+ the vocabulary. The first argument to its constructors is the
+ parser for the type of the root element (<code>people_impl</code>
+ in our case). Because a type parser is only concerned with
+ the element's content and not with the element's name, we need
+ to specify the root element's name somewhere. That's
+ what is passed as the second and third arguments to the
+ <code>document</code>'s constructors.</p>
+
+ <p>There are also two overloaded <code>parse()</code> functions
+ defined in the <code>document</code> class (there are actually
+ more but the others are specific to the underlying XML parser).
+ The first version parses a local file identified by a name. The
+ second version reads the data from an input stream. For more
+ information on the <code>xml_schema::document</code> class
+ refer to <a href="#7">Chapter 7, "Document Parser and Error
+ Handling"</a>.</p>
+
+ <p>Let's now consider a step-by-step list of actions that happen
+ as we parse through <code>people.xml</code>. The content of
+ <code>people.xml</code> is repeated below for convenience.</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0"?>
+&lt;people>
+ &lt;person>
+ &lt;first-name>John&lt;/first-name>
+ &lt;last-name>Doe&lt;/last-name>
+ &lt;gender>male&lt;/gender>
+ &lt;age>32&lt;/age>
+ &lt;/person>
+ &lt;person>
+ &lt;first-name>Jane&lt;/first-name>
+ &lt;last-name>Doe&lt;/last-name>
+ &lt;gender>female&lt;/gender>
+ &lt;age>28&lt;/age>
+ &lt;/person>
+&lt;/people>
+ </pre>
+
+
+ <ol class="steps">
+ <li><code>people_p.pre()</code> is called from
+ <code>main()</code>. We did not provide any implementation
+ for this callback so this call is a no-op.</li>
+
+ <li><code>doc_p.parse("people.xml")</code> is called from
+ <code>main()</code>. The parser opens the file and starts
+ parsing its content.</li>
+
+ <li>The parser encounters the root element. <code>doc_p</code>
+ verifies that the root element is correct and calls
+ <code>_pre()</code> on <code>people_p</code> which is also
+ a no-op. Parsing is now delegated to <code>people_p</code>.</li>
+
+ <li>The parser encounters the <code>person</code> element.
+ <code>people_p</code> determines that <code>person_p</code>
+ is responsible for parsing this element. <code>pre()</code>
+ and <code>_pre()</code> callbacks are called on <code>person_p</code>.
+ Parsing is now delegated to <code>person_p</code>.</li>
+
+ <li>The parser encounters the <code>first-name</code> element.
+ <code>person_p</code> determines that <code>string_p</code>
+ is responsible for parsing this element. <code>pre()</code>
+ and <code>_pre()</code> callbacks are called on <code>string_p</code>.
+ Parsing is now delegated to <code>string_p</code>.</li>
+
+ <li>The parser encounters character content consisting of
+ <code>"John"</code>. The <code>_characters()</code> callback is
+ called on <code>string_p</code>.</li>
+
+ <li>The parser encounters the end of <code>first-name</code>
+ element. The <code>_post()</code> and <code>post_string()</code>
+ callbacks are called on <code>string_p</code>. The
+ <code>first_name()</code> callback is called on <code>person_p</code>
+ with the return value of <code>post_string()</code>. The
+ <code>first_name()</code> implementation prints
+ <code>"first: John"</code> to <code>cout</code>.
+ Parsing is now returned to <code>person_p</code>.</li>
+
+ <li>Steps analogous to 5-7 are performed for the <code>last-name</code>,
+ <code>gender</code>, and <code>age</code> elements.</li>
+
+ <li>The parser encounters the end of <code>person</code>
+ element. The <code>_post()</code> and <code>post_person()</code>
+ callbacks are called on <code>person_p</code>. The
+ <code>person()</code> callback is called on <code>people_p</code>.
+ The <code>person()</code> implementation prints a new line
+ to <code>cout</code>. Parsing is now returned to
+ <code>people_p</code>.</li>
+
+ <li>Steps 4-9 are performed for the second <code>person</code>
+ element.</li>
+
+ <li>The parser encounters the end of <code>people</code>
+ element. The <code>_post()</code> callback is called on
+ <code>people_p</code>. The <code>doc_p.parse("people.xml")</code>
+ call returns to <code>main()</code>.</li>
+
+ <li><code>people_p.post_people()</code> is called from
+ <code>main()</code> which is a no-op.</li>
+
+ </ol>
+
+
+ <!-- Chpater 4 -->
+
+
+ <h1><a name="4">4 Type Maps</a></h1>
+
+ <p>There are many useful things you can do inside parser callbacks as they
+ are right now. There are, however, times when you want to propagate
+ some information from one parser to another or to the caller of the
+ parser. One common task that would greatly benefit from such a
+ possibility is building a tree-like in-memory object model of the
+ data stored in XML. During execution, each individual sub-parser
+ would create a sub-tree and return it to its <em>parent</em> parser
+ which can then incorporate this sub-tree into the whole tree.</p>
+
+ <p>In this chapter we will discuss the mechanisms offered by the
+ C++/Parser mapping for returning information from individual
+ parsers and see how to use them to build an object model
+ of our people vocabulary.</p>
+
+ <h2><a name="4.1">4.1 Object Model</a></h2>
+
+ <p>An object model for our person record example could
+ look like this (saved in the <code>people.hxx</code> file):</p>
+
+ <pre class="c++">
+#include &lt;string>
+#include &lt;vector>
+
+enum gender
+{
+ male,
+ female
+};
+
+class person
+{
+public:
+ person (const std::string&amp; first,
+ const std::string&amp; last,
+ ::gender gender,
+ short age)
+ : first_ (first), last_ (last),
+ gender_ (gender), age_ (age)
+ {
+ }
+
+ const std::string&amp;
+ first () const
+ {
+ return first_;
+ }
+
+ const std::string&amp;
+ last () const
+ {
+ return last_;
+ }
+
+ ::gender
+ gender () const
+ {
+ return gender_;
+ }
+
+ short
+ age () const
+ {
+ return age_;
+ }
+
+private:
+ std::string first_;
+ std::string last_;
+ ::gender gender_;
+ short age_;
+};
+
+typedef std::vector&lt;person> people;
+ </pre>
+
+ <p>While it is clear which parser is responsible for which part of
+ the object model, it is not exactly clear how, for
+ example, <code>gender_pimpl</code> will deliver <code>gender</code>
+ to <code>person_pimpl</code>. You might have noticed that
+ <code>string_pimpl</code> manages to deliver its value to the
+ <code>first_name()</code> callback of <code>person_pimpl</code>. Let's
+ see how we can utilize the same mechanism to propagate our
+ own data.</p>
+
+ <p>There is a way to tell the XSD compiler that you want to
+ exchange data between parsers. More precisely, for each
+ type defined in XML Schema, you can tell the compiler two things.
+ First, the return type of the <code>post_*()</code> callback
+ in the parser skeleton generated for this type. And, second,
+ the argument type for callbacks corresponding to elements and
+ attributes of this type. For example, for XML Schema type
+ <code>gender</code> we can specify the return type for
+ <code>post_gender()</code> in the <code>gender_pskel</code>
+ skeleton and the argument type for the <code>gender()</code> callback
+ in the <code>person_pskel</code> skeleton. As you might have guessed,
+ the generated code will then pass the return value from the
+ <code>post_*()</code> callback as an argument to the element or
+ attribute callback.</p>
+
+ <p>The way to tell the XSD compiler about these XML Schema to
+ C++ mappings is with type map files. Here is a simple type
+ map for the <code>gender</code> type from the previous paragraph:</p>
+
+ <pre class="type-map">
+include "people.hxx";
+gender ::gender ::gender;
+ </pre>
+
+ <p>The first line indicates that the generated code must include
+ <code>people.hxx</code> in order to get the definition for the
+ <code>gender</code> type. The second line specifies that both
+ argument and return types for the <code>gender</code>
+ XML Schema type should be the <code>::gender</code> C++ enum
+ (we use fully-qualified C++ names to avoid name clashes).
+ The next section will describe the type map format in detail.
+ We save this type map in <code>people.map</code> and
+ then translate our schemas with the <code>--type-map</code>
+ option to let the XSD compiler know about our type map:</p>
+
+ <pre class="terminal">
+$ xsd cxx-parser --type-map people.map people.xsd
+ </pre>
+
+ <p>If we now look at the generated <code>people-pskel.hxx</code>,
+ we will see the following changes in the <code>gender_pskel</code> and
+ <code>person_pskel</code> skeletons:</p>
+
+ <pre class="c++">
+#include "people.hxx"
+
+class gender_pskel: public virtual xml_schema::string_pskel
+{
+ virtual ::gender
+ post_gender () = 0;
+
+ ...
+};
+
+class person_pskel: public xml_schema::complex_content
+{
+ virtual void
+ gender (::gender);
+
+ ...
+};
+ </pre>
+
+ <p>Notice that <code>#include "people.hxx"</code> was added to
+ the generated header file from the type map to provide the
+ definition for the <code>gender</code> enum.</p>
+
+ <h2><a name="4.2">4.2 Type Map File Format</a></h2>
+
+ <p>Type map files are used to define a mapping between XML Schema
+ and C++ types. The compiler uses this information
+ to determine return types of <code>post_*()</code>
+ callbacks in parser skeletons corresponding to XML Schema
+ types as well as argument types for callbacks corresponding
+ to elements and attributes of these types.</p>
+
+ <p>The compiler has a set of predefined mapping rules that map
+ the built-in XML Schema types to suitable C++ types (discussed
+ below) and all other types to <code>void</code>.
+ By providing your own type maps you can override these predefined
+ rules. The format of the type map file is presented below:
+ </p>
+
+ <pre class="type-map">
+namespace &lt;schema-namespace> [&lt;cxx-namespace>]
+{
+ (include &lt;file-name>;)*
+ ([type] &lt;schema-type> &lt;cxx-ret-type> [&lt;cxx-arg-type>];)*
+}
+ </pre>
+
+ <p>Both <code><i>&lt;schema-namespace></i></code> and
+ <code><i>&lt;schema-type></i></code> are regex patterns while
+ <code><i>&lt;cxx-namespace></i></code>,
+ <code><i>&lt;cxx-ret-type></i></code>, and
+ <code><i>&lt;cxx-arg-type></i></code> are regex pattern
+ substitutions. All names can be optionally enclosed in
+ <code>" "</code>, for example, to include white-spaces.</p>
+
+ <p><code><i>&lt;schema-namespace></i></code> determines XML
+ Schema namespace. Optional <code><i>&lt;cxx-namespace></i></code>
+ is prefixed to every C++ type name in this namespace declaration.
+ <code><i>&lt;cxx-ret-type></i></code> is a C++ type name that is
+ used as a return type for the <code>post_*()</code> callback.
+ Optional <code><i>&lt;cxx-arg-type></i></code> is an argument
+ type for callbacks corresponding to elements and attributes
+ of this type. If <code><i>&lt;cxx-arg-type></i></code> is not
+ specified, it defaults to <code><i>&lt;cxx-ret-type></i></code>
+ if <code><i>&lt;cxx-ret-type></i></code> ends with <code>*</code> or
+ <code>&amp;</code> (that is, it is a pointer or a reference) and
+ <code>const&nbsp;<i>&lt;cxx-ret-type></i>&amp;</code>
+ otherwise.
+ <code><i>&lt;file-name></i></code> is a file name either in the
+ <code>" "</code> or <code>&lt; ></code> format
+ and is added with the <code>#include</code> directive to
+ the generated code.</p>
+
+ <p>The <code><b>#</b></code> character starts a comment that ends
+ with a new line or end of file. To specify a name that contains
+ <code><b>#</b></code> enclose it in <code><b>" "</b></code>.
+ For example:</p>
+
+ <pre>
+namespace http://www.example.com/xmlns/my my
+{
+ include "my.hxx";
+
+ # Pass apples by value.
+ #
+ apple apple;
+
+ # Pass oranges as pointers.
+ #
+ orange orange_t*;
+}
+ </pre>
+
+ <p>In the example above, for the
+ <code>http://www.example.com/xmlns/my#orange</code>
+ XML Schema type, the <code>my::orange_t*</code> C++ type will
+ be used as both return and argument types.</p>
+
+ <p>Several namespace declarations can be specified in a single
+ file. The namespace declaration can also be completely
+ omitted to map types in a schema without a namespace. For
+ instance:</p>
+
+ <pre class="type-map">
+include "my.hxx";
+apple apple;
+
+namespace http://www.example.com/xmlns/my
+{
+ orange "const orange_t*";
+}
+ </pre>
+
+ <p>The compiler has a number of predefined mapping rules for
+ the built-in XML Schema types which can be presented as the
+ following map files. The string-based XML Schema types are
+ mapped to either <code>std::string</code> or
+ <code>std::wstring</code> depending on the character type
+ selected (see <a href="#5.1"> Section 5.1, "Character Type"</a> for
+ more information).</p>
+
+ <pre class="type-map">
+namespace http://www.w3.org/2001/XMLSchema
+{
+ boolean bool bool;
+
+ byte "signed char" "signed char";
+ unsignedByte "unsigned char" "unsigned char";
+
+ short short short;
+ unsignedShort "unsigned short" "unsigned short";
+
+ int int int;
+ unsignedInt "unsigned int" "unsigned int";
+
+ long "long long" "long long";
+ unsignedLong "unsigned long long" "unsigned long long";
+
+ integer "long long" "long long";
+
+ negativeInteger "long long" "long long";
+ nonPositiveInteger "long long" "long long";
+
+ positiveInteger "unsigned long long" "unsigned long long";
+ nonNegativeInteger "unsigned long long" "unsigned long long";
+
+ float float float;
+ double double double;
+ decimal double double;
+
+ string std::string;
+ normalizedString std::string;
+ token std::string;
+ Name std::string;
+ NMTOKEN std::string;
+ NCName std::string;
+ ID std::string;
+ IDREF std::string;
+ language std::string;
+ anyURI std::string;
+
+ NMTOKENS xml_schema::string_sequence;
+ IDREFS xml_schema::string_sequence;
+
+ QName xml_schema::qname;
+
+ base64Binary std::auto_ptr&lt;xml_schema::buffer>
+ std::auto_ptr&lt;xml_schema::buffer>;
+ hexBinary std::auto_ptr&lt;xml_schema::buffer>
+ std::auto_ptr&lt;xml_schema::buffer>;
+
+ date xml_schema::date;
+ dateTime xml_schema::date_time;
+ duration xml_schema::duration;
+ gDay xml_schema::gday;
+ gMonth xml_schema::gmonth;
+ gMonthDay xml_schema::gmonth_day;
+ gYear xml_schema::gyear;
+ gYearMonth xml_schema::gyear_month;
+ time xml_schema::time;
+}
+ </pre>
+
+ <p>For more information about the mapping of the built-in XML Schema types
+ to C++ types refer to <a href="#6">Chapter 6, "Built-In XML Schema Type
+ Parsers"</a>. The last predefined rule maps anything that wasn't
+ mapped by previous rules to <code>void</code>:</p>
+
+ <pre class="type-map">
+namespace .*
+{
+ .* void void;
+}
+ </pre>
+
+
+ <p>When you provide your own type maps with the
+ <code>--type-map</code> option, they are evaluated first. This
+ allows you to selectively override any of the predefined rules.
+ Note also that if you change the mapping
+ of a built-in XML Schema type then it becomes your responsibility
+ to provide the corresponding parser skeleton and implementation
+ in the <code>xml_schema</code> namespace. You can include the
+ custom definitions into the generated header file using the
+ <code>--hxx-prologue-*</code> options.</p>
+
+ <h2><a name="4.3">4.3 Parser Implementations</a></h2>
+
+ <p>With the knowledge from the previous section, we can proceed
+ with creating a type map that maps types in the <code>people.xsd</code>
+ schema to our object model classes in
+ <code>people.hxx</code>. In fact, we already have the beginning
+ of our type map file in <code>people.map</code>. Let's extend
+ it with the rest of the types:</p>
+
+ <pre class="type-map">
+include "people.hxx";
+
+gender ::gender ::gender;
+person ::person;
+people ::people;
+ </pre>
+
+ <p>There are a few things to note about this type map. We did not
+ provide the argument types for <code>person</code> and
+ <code>people</code> because the default constant reference is
+ exactly what we need. We also did not provide any mappings
+ for built-in XML Schema types <code>string</code> and
+ <code>short</code> because they are handled by the predefined
+ rules and we are happy with the result. Note also that
+ all C++ types are fully qualified. This is done to avoid
+ potential name conflicts in the generated code. Now we can
+ recompile our schema and move on to implementing the parsers:</p>
+
+ <pre class="terminal">
+$ xsd cxx-parser --xml-parser expat --type-map people.map people.xsd
+ </pre>
+
+ <p>Here is the implementation of our three parsers in full. One
+ way to save typing when implementing your own parsers is
+ to open the generated code and copy the signatures of parser
+ callbacks into your code. Or you could always auto generate the
+ sample implementations and fill them with your code.</p>
+
+
+ <pre class="c++">
+#include "people-pskel.hxx"
+
+class gender_pimpl: public gender_pskel,
+ public xml_schema::string_pimpl
+{
+public:
+ virtual ::gender
+ post_gender ()
+ {
+ return post_string () == "male" ? male : female;
+ }
+};
+
+class person_pimpl: public person_pskel
+{
+public:
+ virtual void
+ first_name (const std::string&amp; f)
+ {
+ first_ = f;
+ }
+
+ virtual void
+ last_name (const std::string&amp; l)
+ {
+ last_ = l;
+ }
+
+ virtual void
+ gender (::gender g)
+ {
+ gender_ = g;
+ }
+
+ virtual void
+ age (short a)
+ {
+ age_ = a;
+ }
+
+ virtual ::person
+ post_person ()
+ {
+ return ::person (first_, last_, gender_, age_);
+ }
+
+private:
+ std::string first_;
+ std::string last_;
+ ::gender gender_;
+ short age_;
+};
+
+class people_pimpl: public people_pskel
+{
+public:
+ virtual void
+ person (const ::person&amp; p)
+ {
+ people_.push_back (p);
+ }
+
+ virtual ::people
+ post_people ()
+ {
+ ::people r;
+ r.swap (people_);
+ return r;
+ }
+
+private:
+ ::people people_;
+};
+ </pre>
+
+ <p>This code fragment should look familiar by now. Just note that
+ all the <code>post_*()</code> callbacks now have return types instead
+ of <code>void</code>. Here is the implementation of the test
+ driver for this example:</p>
+
+ <pre class="c++">
+#include &lt;iostream>
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ // Construct the parser.
+ //
+ xml_schema::short_pimpl short_p;
+ xml_schema::string_pimpl string_p;
+
+ gender_pimpl gender_p;
+ person_pimpl person_p;
+ people_pimpl people_p;
+
+ person_p.parsers (string_p, string_p, gender_p, short_p);
+ people_p.parsers (person_p);
+
+ // Parse the document to obtain the object model.
+ //
+ xml_schema::document doc_p (people_p, "people");
+
+ people_p.pre ();
+ doc_p.parse (argv[1]);
+ people ppl = people_p.post_people ();
+
+ // Print the object model.
+ //
+ for (people::iterator i (ppl.begin ()); i != ppl.end (); ++i)
+ {
+ cout &lt;&lt; "first: " &lt;&lt; i->first () &lt;&lt; endl
+ &lt;&lt; "last: " &lt;&lt; i->last () &lt;&lt; endl
+ &lt;&lt; "gender: " &lt;&lt; (i->gender () == male ? "male" : "female") &lt;&lt; endl
+ &lt;&lt; "age: " &lt;&lt; i->age () &lt;&lt; endl
+ &lt;&lt; endl;
+ }
+}
+ </pre>
+
+ <p>The parser creation and assembly part is exactly the same as in
+ the previous chapter. The parsing part is a bit different:
+ <code>post_people()</code> now has a return value which is the
+ complete object model. We store it in the
+ <code>ppl</code> variable. The last bit of the code simply iterates
+ over the <code>people</code> vector and prints the information
+ for each person. We save the last two code fragments to
+ <code>driver.cxx</code> and proceed to compile and test
+ our new application:</p>
+
+
+ <pre class="terminal">
+$ c++ -I.../libxsd -c driver.cxx people-pskel.cxx
+$ c++ -o driver driver.o people-pskel.o -lexpat
+$ ./driver people.xml
+first: John
+last: Doe
+gender: male
+age: 32
+
+first: Jane
+last: Doe
+gender: female
+age: 28
+ </pre>
+
+
+ <!-- Mapping Configuration -->
+
+
+ <h1><a name="5">5 Mapping Configuration</a></h1>
+
+ <p>The C++/Parser mapping has a number of configuration parameters that
+ determine the overall properties and behavior of the generated code.
+ Configuration parameters are specified with the XSD command line
+ options and include the character type that is used by the generated
+ code, the underlying XML parser, whether the XML Schema validation
+ is performed in the generated code, and support for XML Schema
+ polymorphism. This chapter describes these configuration
+ parameters in more detail. For more ways to configure the generated
+ code refer to the
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD
+ Compiler Command Line Manual</a>.
+ </p>
+
+ <h2><a name="5.1">5.1 Character Type</a></h2>
+
+ <p>The C++/Parser mapping has built-in support for two character types:
+ <code>char</code> and <code>wchar_t</code>. You can select the
+ character type with the <code>--char-type</code> command line
+ option. The default character type is <code>char</code>. The
+ string-based built-in XML Schema types are returned as either
+ <code>std::string</code> or <code>std::wstring</code> depending
+ on the character type selected.</p>
+
+ <p>Another aspect of the mapping that depends on the character type
+ is character encoding. For the <code>char</code> character type
+ the encoding is UTF-8. For the <code>wchar_t</code> character type
+ the encoding is automatically selected between UTF-16 and
+ UTF-32/UCS-4 depending on the size of the <code>wchar_t</code> type.
+ On some platforms (for example, Windows with Visual C++ and AIX with IBM XL
+ C++) <code>wchar_t</code> is 2 bytes long. For these platforms the
+ encoding is UTF-16. On other platforms <code>wchar_t</code> is 4 bytes
+ long and UTF-32/UCS-4 is used.
+ </p>
+
+
+ <h2><a name="5.2">5.2 Underlying XML Parser</a></h2>
+
+ <p>The C++/Parser mapping can be used with either Xerces-C++ or Expat
+ as the underlying XML parser. You can select the XML parser with
+ the <code>--xml-parser</code> command line option. Valid values
+ for this option are <code>xerces</code> and <code>expat</code>.
+ The default XML parser is Xerces-C++.</p>
+
+ <p>The generated code is identical for both parsers except for the
+ <code>xml_schema::document</code> class in which some of the
+ <code>parse()</code> functions are parser-specific as described
+ in <a href="#7">Chapter 7, "Document Parser and Error Handling"</a>.</p>
+
+
+ <h2><a name="5.3">5.3 XML Schema Validation</a></h2>
+
+ <p>The C++/Parser mapping provides support for validating a
+ commonly-used subset of W3C XML Schema in the generated code.
+ For the list of supported XML Schema constructs refer to
+ <a href="#A">Appendix A, "Supported XML Schema Constructs"</a>.</p>
+
+ <p>By default validation in the generated code is disabled if
+ the underlying XML parser is validating (Xerces-C++) and
+ enabled otherwise (Expat). See <a href="#5.2">Section 5.2,
+ "Underlying XML Parser"</a> for more information about
+ the underlying XML parser. You can override the default
+ behavior with the <code>--generate-validation</code>
+ and <code>--suppress-validation</code> command line options.</p>
+
+
+ <h2><a name="5.4">5.4 Support for Polymorphism</a></h2>
+
+ <p>By default the XSD compiler generates non-polymorphic code. If your
+ vocabulary uses XML Schema polymorphism in the form of <code>xsi:type</code>
+ and/or substitution groups, then you will need to compile your schemas
+ with the <code>--generate-polymorphic</code> option to produce
+ polymorphism-aware code as well as pass <code>true</code> as the last
+ argument to the <code>xml_schema::document</code>'s constructors.</p>
+
+ <p>When using the polymorphism-aware generated code, you can specify
+ several parsers for a single element by passing a parser map
+ instead of an individual parser to the parser connection function
+ for the element. One of the parsers will then be looked up and used
+ depending on the <code>xsi:type</code> attribute value or an element
+ name from a substitution group. Consider the following schema as an
+ example:</p>
+
+ <pre class="xml">
+&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ &lt;xs:complexType name="person">
+ &lt;xs:sequence>
+ &lt;xs:element name="name" type="xs:string"/>
+ &lt;/xs:sequence>
+ &lt;/xs:complexType>
+
+ &lt;!-- substitution group root -->
+ &lt;xs:element name="person" type="person"/>
+
+ &lt;xs:complexType name="superman">
+ &lt;xs:complexContent>
+ &lt;xs:extension base="person">
+ &lt;xs:attribute name="can-fly" type="xs:boolean"/>
+ &lt;/xs:extension>
+ &lt;/xs:complexContent>
+ &lt;/xs:complexType>
+
+ &lt;xs:element name="superman"
+ type="superman"
+ substitutionGroup="person"/>
+
+ &lt;xs:complexType name="batman">
+ &lt;xs:complexContent>
+ &lt;xs:extension base="superman">
+ &lt;xs:attribute name="wing-span" type="xs:unsignedInt"/>
+ &lt;/xs:extension>
+ &lt;/xs:complexContent>
+ &lt;/xs:complexType>
+
+ &lt;xs:element name="batman"
+ type="batman"
+ substitutionGroup="superman"/>
+
+ &lt;xs:complexType name="supermen">
+ &lt;xs:sequence>
+ &lt;xs:element ref="person" maxOccurs="unbounded"/>
+ &lt;/xs:sequence>
+ &lt;/xs:complexType>
+
+ &lt;xs:element name="supermen" type="supermen"/>
+
+&lt;/xs:schema>
+ </pre>
+
+ <p>Conforming XML documents can use the <code>superman</code>
+ and <code>batman</code> types in place of the <code>person</code>
+ type either by specifying the type with the <code>xsi:type</code>
+ attributes or by using the elements from the substitution
+ group, for instance:</p>
+
+
+ <pre class="xml">
+&lt;supermen xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+
+ &lt;person>
+ &lt;name>John Doe&lt;/name>
+ &lt;/person>
+
+ &lt;superman can-fly="false">
+ &lt;name>James "007" Bond&lt;/name>
+ &lt;/superman>
+
+ &lt;superman can-fly="true" wing-span="10" xsi:type="batman">
+ &lt;name>Bruce Wayne&lt;/name>
+ &lt;/superman>
+
+&lt;/supermen>
+ </pre>
+
+ <p>To print the data stored in such XML documents we can implement
+ the parsers as follows:</p>
+
+ <pre class="c++">
+class person_pimpl: public virtual person_pskel
+{
+public:
+ virtual void
+ pre ()
+ {
+ cout &lt;&lt; "starting to parse person" &lt;&lt; endl;
+ }
+
+ virtual void
+ name (const std::string&amp; v)
+ {
+ cout &lt;&lt; "name: " &lt;&lt; v &lt;&lt; endl;
+ }
+
+ virtual void
+ post_person ()
+ {
+ cout &lt;&lt; "finished parsing person" &lt;&lt; endl;
+ }
+};
+
+class superman_pimpl: public virtual superman_pskel,
+ public person_pimpl
+{
+public:
+ virtual void
+ pre ()
+ {
+ cout &lt;&lt; "starting to parse superman" &lt;&lt; endl;
+ }
+
+ virtual void
+ can_fly (bool v)
+ {
+ cout &lt;&lt; "can-fly: " &lt;&lt; v &lt;&lt; endl;
+ }
+
+ virtual void
+ post_person ()
+ {
+ post_superman ();
+ }
+
+ virtual void
+ post_superman ()
+ {
+ cout &lt;&lt; "finished parsing superman" &lt;&lt; endl
+ }
+};
+
+class batman_pimpl: public virtual batman_pskel,
+ public superman_pimpl
+{
+public:
+ virtual void
+ pre ()
+ {
+ cout &lt;&lt; "starting to parse batman" &lt;&lt; endl;
+ }
+
+ virtual void
+ wing_span (unsigned int v)
+ {
+ cout &lt;&lt; "wing-span: " &lt;&lt; v &lt;&lt; endl;
+ }
+
+ virtual void
+ post_superman ()
+ {
+ post_batman ();
+ }
+
+ virtual void
+ post_batman ()
+ {
+ cout &lt;&lt; "finished parsing batman" &lt;&lt; endl;
+ }
+};
+ </pre>
+
+ <p>Note that because the derived type parsers (<code>superman_pskel</code>
+ and <code>batman_pskel</code>) are called via the <code>person_pskel</code>
+ interface, we have to override the <code>post_person()</code>
+ virtual function in <code>superman_pimpl</code> to call
+ <code>post_superman()</code> and the <code>post_superman()</code>
+ virtual function in <code>batman_pimpl</code> to call
+ <code>post_batman()</code>.</p>
+
+ <p>The following code fragment shows how to connect the parsers together.
+ Notice that for the <code>person</code> element in the <code>supermen_p</code>
+ parser we specify a parser map instead of a specific parser and we pass
+ <code>true</code> as the last argument to the document parser constructor
+ to indicate that we are parsing potentially-polymorphic XML documents:</p>
+
+ <pre class="c++">
+int
+main (int argc, char* argv[])
+{
+ // 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 ();
+}
+ </pre>
+
+ <p>When polymorphism-aware code is generated, each element's
+ <code>*_parser()</code> function is overloaded to also accept
+ an object of the <code>xml_schema::parser_map</code> type.
+ For example, the <code>supermen_pskel</code> class from the
+ above example looks like this:</p>
+
+ <pre class="c++">
+class supermen_pskel: public xml_schema::parser_complex_content
+{
+public:
+
+ ...
+
+ // Parser construction API.
+ //
+ void
+ parsers (person_pskel&amp;);
+
+ // Individual element parsers.
+ //
+ void
+ person_parser (person_pskel&amp;);
+
+ void
+ person_parser (const xml_schema::parser_map&amp;);
+
+ ...
+};
+ </pre>
+
+ <p>Note that you can specify both the individual (static) parser and
+ the parser map. The individual parser will be used when the static
+ element type and the dynamic type of the object being parsed are
+ the same. This is the case, for example, when there is no
+ <code>xsi:type</code> attribute and the element hasn't been
+ substituted. Because the individual parser for an element is
+ cached and no map lookup is necessary, it makes sense to specify
+ both the individual parser and the parser map when most of the
+ objects being parsed are of the static type and optimal
+ performance is important. The following code fragment shows
+ how to change the above example to set both the individual
+ parser and the parser map:</p>
+
+ <pre class="c++">
+int
+main (int argc, char* argv[])
+{
+ ...
+
+ person_map.insert (superman_p);
+ person_map.insert (batman_p);
+
+ supermen_p.person_parser (person_p);
+ supermen_p.person_parser (person_map);
+
+ ...
+}
+ </pre>
+
+
+ <p>The <code>xml_schema::parser_map</code> interface and the
+ <code>xml_schema::parser_map_impl</code> default implementation
+ are presented below:</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class parser_map
+ {
+ public:
+ virtual parser_base*
+ find (const ro_string* type) const = 0;
+ };
+
+ class parser_map_impl: public parser_map
+ {
+ public:
+ void
+ insert (parser_base&amp;);
+
+ virtual parser_base*
+ find (const ro_string* type) const;
+
+ private:
+ parser_map_impl (const parser_map_impl&amp;);
+
+ parser_map_impl&amp;
+ operator= (const parser_map_impl&amp;);
+
+ ...
+ };
+}
+ </pre>
+
+ <p>The <code>type</code> argument in the <code>find()</code> virtual
+ function is the type name and namespace from the xsi:type attribute
+ (the namespace prefix is resolved to the actual XML namespace)
+ or the type of an element from the substitution group in the form
+ <code>"&lt;name>&nbsp;&lt;namespace>"</code> with the space and the
+ namespace part absent if the type does not have a namespace.
+ You can obtain a parser's dynamic type in the same format
+ using the <code>_dynamic_type()</code> function. The static
+ type can be obtained by calling the static <code>_static_type()</code>
+ function, for example <code>person_pskel::_static_type()</code>.
+ Both functions return a C string (<code>const char*</code> or
+ <code>const wchar_t*</code>, depending on the character type
+ used) which is valid for as long as the application is running.
+ The following example shows how we can implement our own parser
+ map using <code>std::map</code>:</p>
+
+
+ <pre class="c++">
+#include &lt;map>
+#include &lt;string>
+
+class parser_map: public xml_schema::parser_map
+{
+public:
+ void
+ insert (xml_schema::parser_base&amp; p)
+ {
+ map_[p._dynamic_type ()] = &amp;p;
+ }
+
+ virtual xml_schema::parser_base*
+ find (const xml_schema::ro_string* type) const
+ {
+ map::const_iterator i = map_.find (type);
+ return i != map_.end () ? i->second : 0;
+ }
+
+private:
+ typedef std::map&lt;std::string, xml_schema::parser_base*> map;
+ map map_;
+};
+ </pre>
+
+ <p>Most of code presented in this section is taken from the
+ <code>polymorphism</code> example which can be found in the
+ <code>examples/cxx/parser/</code> directory of the XSD distribution.
+ Handling of <code>xsi:type</code> and substitution groups when used
+ on root elements requires a number of special actions as shown in
+ the <code>polyroot</code> example.</p>
+
+
+ <!-- Built-in XML Schema Type Parsers -->
+
+
+ <h1><a name="6">6 Built-In XML Schema Type Parsers</a></h1>
+
+ <p>The XSD runtime provides parser implementations for all built-in
+ XML Schema types as summarized in the following table. Declarations
+ for these types are automatically included into each generated
+ header file. As a result you don't need to include any headers
+ to gain access to these parser implementations. Note that some
+ parsers return either <code>std::string</code> or
+ <code>std::wstring</code> depending on the character type selected.</p>
+
+ <!-- border="1" is necessary for html2ps -->
+ <table id="builtin" border="1">
+ <tr>
+ <th>XML Schema type</th>
+ <th>Parser implementation in the <code>xml_schema</code> namespace</th>
+ <th>Parser return type</th>
+ </tr>
+
+ <tr>
+ <th colspan="3">anyType and anySimpleType types</th>
+ </tr>
+ <tr>
+ <td><code>anyType</code></td>
+ <td><code>any_type_pimpl</code></td>
+ <td><code>void</code></td>
+ </tr>
+ <tr>
+ <td><code>anySimpleType</code></td>
+ <td><code>any_simple_type_pimpl</code></td>
+ <td><code>void</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">fixed-length integral types</th>
+ </tr>
+ <!-- 8-bit -->
+ <tr>
+ <td><code>byte</code></td>
+ <td><code>byte_pimpl</code></td>
+ <td><code>signed&nbsp;char</code></td>
+ </tr>
+ <tr>
+ <td><code>unsignedByte</code></td>
+ <td><code>unsigned_byte_pimpl</code></td>
+ <td><code>unsigned&nbsp;char</code></td>
+ </tr>
+
+ <!-- 16-bit -->
+ <tr>
+ <td><code>short</code></td>
+ <td><code>short_pimpl</code></td>
+ <td><code>short</code></td>
+ </tr>
+ <tr>
+ <td><code>unsignedShort</code></td>
+ <td><code>unsigned_short_pimpl</code></td>
+ <td><code>unsigned&nbsp;short</code></td>
+ </tr>
+
+ <!-- 32-bit -->
+ <tr>
+ <td><code>int</code></td>
+ <td><code>int_pimpl</code></td>
+ <td><code>int</code></td>
+ </tr>
+ <tr>
+ <td><code>unsignedInt</code></td>
+ <td><code>unsigned_int_pimpl</code></td>
+ <td><code>unsigned&nbsp;int</code></td>
+ </tr>
+
+ <!-- 64-bit -->
+ <tr>
+ <td><code>long</code></td>
+ <td><code>long_pimpl</code></td>
+ <td><code>long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>unsignedLong</code></td>
+ <td><code>unsigned_long_pimpl</code></td>
+ <td><code>unsigned&nbsp;long&nbsp;long</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">arbitrary-length integral types</th>
+ </tr>
+ <tr>
+ <td><code>integer</code></td>
+ <td><code>integer_pimpl</code></td>
+ <td><code>long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>nonPositiveInteger</code></td>
+ <td><code>non_positive_integer_pimpl</code></td>
+ <td><code>long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>nonNegativeInteger</code></td>
+ <td><code>non_negative_integer_pimpl</code></td>
+ <td><code>unsigned long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>positiveInteger</code></td>
+ <td><code>positive_integer_pimpl</code></td>
+ <td><code>unsigned long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>negativeInteger</code></td>
+ <td><code>negative_integer_pimpl</code></td>
+ <td><code>long&nbsp;long</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">boolean types</th>
+ </tr>
+ <tr>
+ <td><code>boolean</code></td>
+ <td><code>boolean_pimpl</code></td>
+ <td><code>bool</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">fixed-precision floating-point types</th>
+ </tr>
+ <tr>
+ <td><code>float</code></td>
+ <td><code>float_pimpl</code></td>
+ <td><code>float</code></td>
+ </tr>
+ <tr>
+ <td><code>double</code></td>
+ <td><code>double_pimpl</code></td>
+ <td><code>double</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">arbitrary-precision floating-point types</th>
+ </tr>
+ <tr>
+ <td><code>decimal</code></td>
+ <td><code>decimal_pimpl</code></td>
+ <td><code>double</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">string-based types</th>
+ </tr>
+ <tr>
+ <td><code>string</code></td>
+ <td><code>string_pimpl</code></td>
+ <td><code>std::string</code> or <code>std::wstring</code></td>
+ </tr>
+ <tr>
+ <td><code>normalizedString</code></td>
+ <td><code>normalized_string_pimpl</code></td>
+ <td><code>std::string</code> or <code>std::wstring</code></td>
+ </tr>
+ <tr>
+ <td><code>token</code></td>
+ <td><code>token_pimpl</code></td>
+ <td><code>std::string</code> or <code>std::wstring</code></td>
+ </tr>
+ <tr>
+ <td><code>Name</code></td>
+ <td><code>name_pimpl</code></td>
+ <td><code>std::string</code> or <code>std::wstring</code></td>
+ </tr>
+ <tr>
+ <td><code>NMTOKEN</code></td>
+ <td><code>nmtoken_pimpl</code></td>
+ <td><code>std::string</code> or <code>std::wstring</code></td>
+ </tr>
+ <tr>
+ <td><code>NCName</code></td>
+ <td><code>ncname_pimpl</code></td>
+ <td><code>std::string</code> or <code>std::wstring</code></td>
+ </tr>
+
+ <tr>
+ <td><code>language</code></td>
+ <td><code>language_pimpl</code></td>
+ <td><code>std::string</code> or <code>std::wstring</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">qualified name</th>
+ </tr>
+ <tr>
+ <td><code>QName</code></td>
+ <td><code>qname_pimpl</code></td>
+ <td><code>xml_schema::qname</code><br/><a href="#6.1">Section 6.1,
+ "<code>QName</code> Parser"</a></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">ID/IDREF types</th>
+ </tr>
+ <tr>
+ <td><code>ID</code></td>
+ <td><code>id_pimpl</code></td>
+ <td><code>std::string</code> or <code>std::wstring</code></td>
+ </tr>
+ <tr>
+ <td><code>IDREF</code></td>
+ <td><code>idref_pimpl</code></td>
+ <td><code>std::string</code> or <code>std::wstring</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">list types</th>
+ </tr>
+ <tr>
+ <td><code>NMTOKENS</code></td>
+ <td><code>nmtokens_pimpl</code></td>
+ <td><code>xml_schema::string_sequence</code><br/><a href="#6.2">Section
+ 6.2, "<code>NMTOKENS</code> and <code>IDREFS</code> Parsers"</a></td>
+ </tr>
+ <tr>
+ <td><code>IDREFS</code></td>
+ <td><code>idrefs_pimpl</code></td>
+ <td><code>xml_schema::string_sequence</code><br/><a href="#6.2">Section
+ 6.2, "<code>NMTOKENS</code> and <code>IDREFS</code> Parsers"</a></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">URI types</th>
+ </tr>
+ <tr>
+ <td><code>anyURI</code></td>
+ <td><code>uri_pimpl</code></td>
+ <td><code>std::string</code> or <code>std::wstring</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">binary types</th>
+ </tr>
+ <tr>
+ <td><code>base64Binary</code></td>
+ <td><code>base64_binary_pimpl</code></td>
+ <td><code>std::auto_ptr&lt;xml_schema::buffer></code><br/>
+ <a href="#6.3">Section 6.3, "<code>base64Binary</code> and
+ <code>hexBinary</code> Parsers"</a></td>
+ </tr>
+ <tr>
+ <td><code>hexBinary</code></td>
+ <td><code>hex_binary_pimpl</code></td>
+ <td><code>std::auto_ptr&lt;xml_schema::buffer></code><br/>
+ <a href="#6.3">Section 6.3, "<code>base64Binary</code> and
+ <code>hexBinary</code> Parsers"</a></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">date/time types</th>
+ </tr>
+ <tr>
+ <td><code>date</code></td>
+ <td><code>date_pimpl</code></td>
+ <td><code>xml_schema::date</code><br/><a href="#6.5">Section 6.5,
+ "<code>date</code> Parser"</a></td>
+ </tr>
+ <tr>
+ <td><code>dateTime</code></td>
+ <td><code>date_time_pimpl</code></td>
+ <td><code>xml_schema::date_time</code><br/><a href="#6.6">Section 6.6,
+ "<code>dateTime</code> Parser"</a></td>
+ </tr>
+ <tr>
+ <td><code>duration</code></td>
+ <td><code>duration_pimpl</code></td>
+ <td><code>xml_schema::duration</code><br/><a href="#6.7">Section 6.7,
+ "<code>duration</code> Parser"</a></td>
+ </tr>
+ <tr>
+ <td><code>gDay</code></td>
+ <td><code>gday_pimpl</code></td>
+ <td><code>xml_schema::gday</code><br/><a href="#6.8">Section 6.8,
+ "<code>gDay</code> Parser"</a></td>
+ </tr>
+ <tr>
+ <td><code>gMonth</code></td>
+ <td><code>gmonth_pimpl</code></td>
+ <td><code>xml_schema::gmonth</code><br/><a href="#6.9">Section 6.9,
+ "<code>gMonth</code> Parser"</a></td>
+ </tr>
+ <tr>
+ <td><code>gMonthDay</code></td>
+ <td><code>gmonth_day_pimpl</code></td>
+ <td><code>xml_schema::gmonth_day</code><br/><a href="#6.10">Section 6.10,
+ "<code>gMonthDay</code> Parser"</a></td>
+ </tr>
+ <tr>
+ <td><code>gYear</code></td>
+ <td><code>gyear_pimpl</code></td>
+ <td><code>xml_schema::gyear</code><br/><a href="#6.11">Section 6.11,
+ "<code>gYear</code> Parser"</a></td>
+ </tr>
+ <tr>
+ <td><code>gYearMonth</code></td>
+ <td><code>gyear_month_pimpl</code></td>
+ <td><code>xml_schema::gyear_month</code><br/><a href="#6.12">Section
+ 6.12, "<code>gYearMonth</code> Parser"</a></td>
+ </tr>
+ <tr>
+ <td><code>time</code></td>
+ <td><code>time_pimpl</code></td>
+ <td><code>xml_schema::time</code><br/><a href="#6.13">Section 6.13,
+ "<code>time</code> Parser"</a></td>
+ </tr>
+
+ </table>
+
+ <h2><a name="6.1">6.1 <code>QName</code> Parser</a></h2>
+
+ <p>The return type of the <code>qname_pimpl</code> parser implementation
+ is <code>xml_schema::qname</code> which represents an XML qualified
+ name. Its interface is presented below.
+ Note that the <code>std::string</code> type in the interface becomes
+ <code>std::wstring</code> if the selected character type is
+ <code>wchar_t</code>.</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class qname
+ {
+ public:
+ explicit
+ qname (const std::string&amp; name);
+ qname (const std::string&amp; prefix, const std::string&amp; name);
+
+ const std::string&amp;
+ prefix () const;
+
+ void
+ prefix (const std::string&amp;);
+
+ const std::string&amp;
+ name () const;
+
+ void
+ name (const std::string&amp;);
+ };
+
+ bool
+ operator== (const qname&amp;, const qname&amp;);
+
+ bool
+ operator!= (const qname&amp;, const qname&amp;);
+}
+ </pre>
+
+
+ <h2><a name="6.2">6.2 <code>NMTOKENS</code> and <code>IDREFS</code> Parsers</a></h2>
+
+ <p>The return type of the <code>nmtokens_pimpl</code> and
+ <code>idrefs_pimpl</code> parser implementations is
+ <code>xml_schema::string_sequence</code> which represents a
+ sequence of strings. Its interface is presented below.
+ Note that the <code>std::string</code> type in the interface becomes
+ <code>std::wstring</code> if the selected character type is
+ <code>wchar_t</code>.</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class string_sequence: public std::vector&lt;std::string>
+ {
+ public:
+ string_sequence ();
+
+ explicit
+ string_sequence (std::vector&lt;std::string>::size_type n,
+ const std::string&amp; x = std::string ());
+
+ template &lt;typename I>
+ string_sequence (const I&amp; begin, const I&amp; end);
+ };
+
+ bool
+ operator== (const string_sequence&amp;, const string_sequence&amp;);
+
+ bool
+ operator!= (const string_sequence&amp;, const string_sequence&amp;);
+}
+ </pre>
+
+
+ <h2><a name="6.3">6.3 <code>base64Binary</code> and <code>hexBinary</code> Parsers</a></h2>
+
+ <p>The return type of the <code>base64_binary_pimpl</code> and
+ <code>hex_binary_pimpl</code> parser implementations is
+ <code>std::auto_ptr&lt;xml_schema::buffer></code>. The
+ <code>xml_schema::buffer</code> type represents a binary buffer
+ and its interface is presented below.</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class buffer
+ {
+ public:
+ typedef std::size_t size_t;
+
+ class bounds {}; // Out of bounds exception.
+
+ public:
+ explicit
+ buffer (size_t size = 0);
+ buffer (size_t size, size_t capacity);
+ buffer (const void* data, size_t size);
+ buffer (const void* data, size_t size, size_t capacity);
+ buffer (void* data,
+ size_t size,
+ size_t capacity,
+ bool assume_ownership);
+
+ public:
+ buffer (const buffer&amp;);
+
+ buffer&amp;
+ operator= (const buffer&amp;);
+
+ void
+ swap (buffer&amp;);
+
+ public:
+ size_t
+ capacity () const;
+
+ bool
+ capacity (size_t);
+
+ public:
+ size_t
+ size () const;
+
+ bool
+ size (size_t);
+
+ public:
+ const char*
+ data () const;
+
+ char*
+ data ();
+
+ const char*
+ begin () const;
+
+ char*
+ begin ();
+
+ const char*
+ end () const;
+
+ char*
+ end ();
+ };
+
+ bool
+ operator== (const buffer&amp;, const buffer&amp;);
+
+ bool
+ operator!= (const buffer&amp;, const buffer&amp;);
+}
+ </pre>
+
+ <p>If the <code>assume_ownership</code> argument to the constructor
+ is <code>true</code>, the instance assumes the ownership of the
+ memory block pointed to by the <code>data</code> argument and will
+ eventually release it by calling <code>operator delete()</code>. The
+ <code>capacity()</code> and <code>size()</code> modifier functions
+ return <code>true</code> if the underlying buffer has moved.
+ </p>
+
+ <p>The <code>bounds</code> exception is thrown if the constructor
+ arguments violate the <code>(size&nbsp;&lt;=&nbsp;capacity)</code>
+ constraint.</p>
+
+
+ <h2><a name="6.4">6.4 Time Zone Representation</a></h2>
+
+ <p>The <code>date</code>, <code>dateTime</code>, <code>gDay</code>,
+ <code>gMonth</code>, <code>gMonthDay</code>, <code>gYear</code>,
+ <code>gYearMonth</code>, and <code>time</code> XML Schema built-in
+ types all include an optional time zone component. The following
+ <code>xml_schema::time_zone</code> base class is used to represent
+ this information:</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class time_zone
+ {
+ public:
+ time_zone ();
+ time_zone (short hours, short minutes);
+
+ bool
+ zone_present () const;
+
+ void
+ zone_reset ();
+
+ short
+ zone_hours () const;
+
+ void
+ zone_hours (short);
+
+ short
+ zone_minutes () const;
+
+ void
+ zone_minutes (short);
+ };
+
+ bool
+ operator== (const time_zone&amp;, const time_zone&amp;);
+
+ bool
+ operator!= (const time_zone&amp;, const time_zone&amp;);
+}
+ </pre>
+
+ <p>The <code>zone_present()</code> accessor function returns <code>true</code>
+ if the time zone is specified. The <code>zone_reset()</code> modifier
+ function resets the time zone object to the <em>not specified</em>
+ state. If the time zone offset is negative then both hours and
+ minutes components are represented as negative integers.</p>
+
+
+ <h2><a name="6.5">6.5 <code>date</code> Parser</a></h2>
+
+ <p>The return type of the <code>date_pimpl</code> parser implementation
+ is <code>xml_schema::date</code> which represents a year, a day, and a month
+ with an optional time zone. Its interface is presented below.
+ For more information on the base <code>xml_schema::time_zone</code>
+ class refer to <a href="#6.4">Section 6.4, "Time Zone
+ Representation"</a>.</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class date
+ {
+ public:
+ date (int year, unsigned short month, unsigned short day);
+ date (int year, unsigned short month, unsigned short day,
+ short zone_hours, short zone_minutes);
+
+ int
+ year () const;
+
+ void
+ year (int);
+
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+
+ unsigned short
+ day () const;
+
+ void
+ day (unsigned short);
+ };
+
+ bool
+ operator== (const date&amp;, const date&amp;);
+
+ bool
+ operator!= (const date&amp;, const date&amp;);
+}
+ </pre>
+
+ <h2><a name="6.6">6.6 <code>dateTime</code> Parser</a></h2>
+
+ <p>The return type of the <code>date_time_pimpl</code> parser implementation
+ is <code>xml_schema::date_time</code> which represents a year, a month, a day,
+ hours, minutes, and seconds with an optional time zone. Its interface
+ is presented below.
+ For more information on the base <code>xml_schema::time_zone</code>
+ class refer to <a href="#6.4">Section 6.4, "Time Zone
+ Representation"</a>.</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class date_time
+ {
+ public:
+ date_time (int year, unsigned short month, unsigned short day,
+ unsigned short hours, unsigned short minutes,
+ double seconds);
+
+ date_time (int year, unsigned short month, unsigned short day,
+ unsigned short hours, unsigned short minutes,
+ double seconds, short zone_hours, short zone_minutes);
+
+ int
+ year () const;
+
+ void
+ year (int);
+
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+
+ unsigned short
+ day () const;
+
+ void
+ day (unsigned short);
+
+ unsigned short
+ hours () const;
+
+ void
+ hours (unsigned short);
+
+ unsigned short
+ minutes () const;
+
+ void
+ minutes (unsigned short);
+
+ double
+ seconds () const;
+
+ void
+ seconds (double);
+ };
+
+ bool
+ operator== (const date_time&amp;, const date_time&amp;);
+
+ bool
+ operator!= (const date_time&amp;, const date_time&amp;);
+}
+ </pre>
+
+ <h2><a name="6.7">6.7 <code>duration</code> Parser</a></h2>
+
+ <p>The return type of the <code>duration_pimpl</code> parser implementation
+ is <code>xml_schema::duration</code> which represents a potentially
+ negative duration in the form of years, months, days, hours, minutes,
+ and seconds. Its interface is presented below.</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class duration
+ {
+ public:
+ duration (bool negative,
+ unsigned int years, unsigned int months, unsigned int days,
+ unsigned int hours, unsigned int minutes, double seconds);
+
+ bool
+ negative () const;
+
+ void
+ negative (bool);
+
+ unsigned int
+ years () const;
+
+ void
+ years (unsigned int);
+
+ unsigned int
+ months () const;
+
+ void
+ months (unsigned int);
+
+ unsigned int
+ days () const;
+
+ void
+ days (unsigned int);
+
+ unsigned int
+ hours () const;
+
+ void
+ hours (unsigned int);
+
+ unsigned int
+ minutes () const;
+
+ void
+ minutes (unsigned int);
+
+ double
+ seconds () const;
+
+ void
+ seconds (double);
+ };
+
+ bool
+ operator== (const duration&amp;, const duration&amp;);
+
+ bool
+ operator!= (const duration&amp;, const duration&amp;);
+}
+ </pre>
+
+
+ <h2><a name="6.8">6.8 <code>gDay</code> Parser</a></h2>
+
+ <p>The return type of the <code>gday_pimpl</code> parser implementation
+ is <code>xml_schema::gday</code> which represents a day of the month with
+ an optional time zone. Its interface is presented below.
+ For more information on the base <code>xml_schema::time_zone</code>
+ class refer to <a href="#6.4">Section 6.4, "Time Zone
+ Representation"</a>.</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class gday
+ {
+ public:
+ explicit
+ gday (unsigned short day);
+ gday (unsigned short day, short zone_hours, short zone_minutes);
+
+ unsigned short
+ day () const;
+
+ void
+ day (unsigned short);
+ };
+
+ bool
+ operator== (const gday&amp;, const gday&amp;);
+
+ bool
+ operator!= (const gday&amp;, const gday&amp;);
+}
+ </pre>
+
+ <h2><a name="6.9">6.9 <code>gMonth</code> Parser</a></h2>
+
+ <p>The return type of the <code>gmonth_pimpl</code> parser implementation
+ is <code>xml_schema::gmonth</code> which represents a month of the year
+ with an optional time zone. Its interface is presented below.
+ For more information on the base <code>xml_schema::time_zone</code>
+ class refer to <a href="#6.4">Section 6.4, "Time Zone
+ Representation"</a>.</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class gmonth
+ {
+ public:
+ explicit
+ gmonth (unsigned short month);
+ gmonth (unsigned short month, short zone_hours, short zone_minutes);
+
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+ };
+
+ bool
+ operator== (const gmonth&amp;, const gmonth&amp;);
+
+ bool
+ operator!= (const gmonth&amp;, const gmonth&amp;);
+}
+ </pre>
+
+ <h2><a name="6.10">6.10 <code>gMonthDay</code> Parser</a></h2>
+
+ <p>The return type of the <code>gmonth_day_pimpl</code> parser implementation
+ is <code>xml_schema::gmonth_day</code> which represents a day and a month
+ of the year with an optional time zone. Its interface is presented below.
+ For more information on the base <code>xml_schema::time_zone</code>
+ class refer to <a href="#6.4">Section 6.4, "Time Zone
+ Representation"</a>.</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class gmonth_day
+ {
+ public:
+ gmonth_day (unsigned short month, unsigned short day);
+ gmonth_day (unsigned short month, unsigned short day,
+ short zone_hours, short zone_minutes);
+
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+
+ unsigned short
+ day () const;
+
+ void
+ day (unsigned short);
+ };
+
+ bool
+ operator== (const gmonth_day&amp;, const gmonth_day&amp;);
+
+ bool
+ operator!= (const gmonth_day&amp;, const gmonth_day&amp;);
+}
+ </pre>
+
+ <h2><a name="6.11">6.11 <code>gYear</code> Parser</a></h2>
+
+ <p>The return type of the <code>gyear_pimpl</code> parser implementation
+ is <code>xml_schema::gyear</code> which represents a year with
+ an optional time zone. Its interface is presented below.
+ For more information on the base <code>xml_schema::time_zone</code>
+ class refer to <a href="#6.4">Section 6.4, "Time Zone
+ Representation"</a>.</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class gyear
+ {
+ public:
+ explicit
+ gyear (int year);
+ gyear (int year, short zone_hours, short zone_minutes);
+
+ int
+ year () const;
+
+ void
+ year (int);
+ };
+
+ bool
+ operator== (const gyear&amp;, const gyear&amp;);
+
+ bool
+ operator!= (const gyear&amp;, const gyear&amp;);
+}
+ </pre>
+
+ <h2><a name="6.12">6.12 <code>gYearMonth</code> Parser</a></h2>
+
+ <p>The return type of the <code>gyear_month_pimpl</code> parser implementation
+ is <code>xml_schema::gyear_month</code> which represents a year and a month
+ with an optional time zone. Its interface is presented below.
+ For more information on the base <code>xml_schema::time_zone</code>
+ class refer to <a href="#6.4">Section 6.4, "Time Zone
+ Representation"</a>.</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class gyear_month
+ {
+ public:
+ gyear_month (int year, unsigned short month);
+ gyear_month (int year, unsigned short month,
+ short zone_hours, short zone_minutes);
+
+ int
+ year () const;
+
+ void
+ year (int);
+
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+ };
+
+ bool
+ operator== (const gyear_month&amp;, const gyear_month&amp;);
+
+ bool
+ operator!= (const gyear_month&amp;, const gyear_month&amp;);
+}
+ </pre>
+
+
+ <h2><a name="6.13">6.13 <code>time</code> Parser</a></h2>
+
+ <p>The return type of the <code>time_pimpl</code> parser implementation
+ is <code>xml_schema::time</code> which represents hours, minutes,
+ and seconds with an optional time zone. Its interface is presented below.
+ For more information on the base <code>xml_schema::time_zone</code>
+ class refer to <a href="#6.4">Section 6.4, "Time Zone
+ Representation"</a>.</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class time
+ {
+ public:
+ time (unsigned short hours, unsigned short minutes, double seconds);
+ time (unsigned short hours, unsigned short minutes, double seconds,
+ short zone_hours, short zone_minutes);
+
+ unsigned short
+ hours () const;
+
+ void
+ hours (unsigned short);
+
+ unsigned short
+ minutes () const;
+
+ void
+ minutes (unsigned short);
+
+ double
+ seconds () const;
+
+ void
+ seconds (double);
+ };
+
+ bool
+ operator== (const time&amp;, const time&amp;);
+
+ bool
+ operator!= (const time&amp;, const time&amp;);
+}
+ </pre>
+
+
+ <!-- Error Handling -->
+
+
+ <h1><a name="7">7 Document Parser and Error Handling</a></h1>
+
+ <p>In this chapter we will discuss the <code>xml_schema::document</code>
+ type as well as the error handling mechanisms provided by the mapping
+ in more detail. As mentioned in <a href="#3.4">Section 3.4,
+ "Connecting the Parsers Together"</a>, the interface of
+ <code>xml_schema::document</code> depends on the underlying XML
+ parser selected (<a href="#5.2">Section 5.2, "Underlying XML
+ Parser"</a>). The following sections describe the
+ <code>document</code> type interface for Xerces-C++ and
+ Expat as underlying parsers.</p>
+
+ <h2><a name="7.1">7.1 Xerces-C++ Document Parser</a></h2>
+
+ <p>When Xerces-C++ is used as the underlying XML parser, the
+ <code>document</code> type has the following interface. Note that
+ if the character type is <code>wchar_t</code>, then the string type
+ in the interface becomes <code>std::wstring</code>
+ (see <a href="#5.1">Section 5.1, "Character Type"</a>).</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class parser_base;
+ class error_handler;
+
+ class flags
+ {
+ public:
+ // Do not validate XML documents with the Xerces-C++ validator.
+ //
+ static const unsigned long dont_validate;
+
+ // Do not initialize the Xerces-C++ runtime.
+ //
+ static const unsigned long dont_initialize;
+ };
+
+ class properties
+ {
+ public:
+ // Add a location for a schema with a target namespace.
+ //
+ void
+ schema_location (const std::string&amp; namespace_,
+ const std::string&amp; location);
+
+ // Add a location for a schema without a target namespace.
+ //
+ void
+ no_namespace_schema_location (const std::string&amp; location);
+ };
+
+ class document
+ {
+ public:
+ document (parser_base&amp; root,
+ const std::string&amp; root_element_name,
+ bool polymorphic = false);
+
+ document (parser_base&amp; root,
+ const std::string&amp; root_element_namespace,
+ const std::string&amp; root_element_name,
+ bool polymorphic = false);
+
+ public:
+ // Parse URI or a local file.
+ //
+ void
+ parse (const std::string&amp; uri,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse URI or a local file with a user-provided error_handler
+ // object.
+ //
+ void
+ parse (const std::string&amp; uri,
+ error_handler&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse URI or a local file with a user-provided ErrorHandler
+ // object. Note that you must initialize the Xerces-C++ runtime
+ // before calling this function.
+ //
+ void
+ parse (const std::string&amp; uri,
+ xercesc::ErrorHandler&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse URI or a local file using a user-provided SAX2XMLReader
+ // object. Note that you must initialize the Xerces-C++ runtime
+ // before calling this function.
+ //
+ void
+ parse (const std::string&amp; uri,
+ xercesc::SAX2XMLReader&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ public:
+ // Parse std::istream.
+ //
+ void
+ parse (std::istream&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse std::istream with a user-provided error_handler object.
+ //
+ void
+ parse (std::istream&amp;,
+ error_handler&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse std::istream with a user-provided ErrorHandler object.
+ // Note that you must initialize the Xerces-C++ runtime before
+ // calling this function.
+ //
+ void
+ parse (std::istream&amp;,
+ xercesc::ErrorHandler&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse std::istream using a user-provided SAX2XMLReader object.
+ // Note that you must initialize the Xerces-C++ runtime before
+ // calling this function.
+ //
+ void
+ parse (std::istream&amp;,
+ xercesc::SAX2XMLReader&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ public:
+ // Parse std::istream with a system id.
+ //
+ void
+ parse (std::istream&amp;,
+ const std::string&amp; system_id,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse std::istream with a system id and a user-provided
+ // error_handler object.
+ //
+ void
+ parse (std::istream&amp;,
+ const std::string&amp; system_id,
+ error_handler&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse std::istream with a system id and a user-provided
+ // ErrorHandler object. Note that you must initialize the
+ // Xerces-C++ runtime before calling this function.
+ //
+ void
+ parse (std::istream&amp;,
+ const std::string&amp; system_id,
+ xercesc::ErrorHandler&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse std::istream with a system id using a user-provided
+ // SAX2XMLReader object. Note that you must initialize the
+ // Xerces-C++ runtime before calling this function.
+ //
+ void
+ parse (std::istream&amp;,
+ const std::string&amp; system_id,
+ xercesc::SAX2XMLReader&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ public:
+ // Parse std::istream with system and public ids.
+ //
+ void
+ parse (std::istream&amp;,
+ const std::string&amp; system_id,
+ const std::string&amp; public_id,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse std::istream with system and public ids and a user-provided
+ // error_handler object.
+ //
+ void
+ parse (std::istream&amp;,
+ const std::string&amp; system_id,
+ const std::string&amp; public_id,
+ error_handler&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse std::istream with system and public ids and a user-provided
+ // ErrorHandler object. Note that you must initialize the Xerces-C++
+ // runtime before calling this function.
+ //
+ void
+ parse (std::istream&amp;,
+ const std::string&amp; system_id,
+ const std::string&amp; public_id,
+ xercesc::ErrorHandler&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse std::istream with system and public ids using a user-
+ // provided SAX2XMLReader object. Note that you must initialize
+ // the Xerces-C++ runtime before calling this function.
+ //
+ void
+ parse (std::istream&amp;,
+ const std::string&amp; system_id,
+ const std::string&amp; public_id,
+ xercesc::SAX2XMLReader&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ public:
+ // Parse InputSource. Note that you must initialize the Xerces-C++
+ // runtime before calling this function.
+ //
+ void
+ parse (const xercesc::InputSource&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse InputSource with a user-provided error_handler object.
+ // Note that you must initialize the Xerces-C++ runtime before
+ // calling this function.
+ //
+ void
+ parse (const xercesc::InputSource&amp;,
+ error_handler&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse InputSource with a user-provided ErrorHandler object.
+ // Note that you must initialize the Xerces-C++ runtime before
+ // calling this function.
+ //
+ void
+ parse (const xercesc::InputSource&amp;,
+ xercesc::ErrorHandler&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+
+ // Parse InputSource using a user-provided SAX2XMLReader object.
+ // Note that you must initialize the Xerces-C++ runtime before
+ // calling this function.
+ //
+ void
+ parse (const xercesc::InputSource&amp;,
+ xercesc::SAX2XMLReader&amp;,
+ flags = 0,
+ const properties&amp; = properties ());
+ };
+}
+ </pre>
+
+ <p>The <code>document</code> class is a root parser for
+ the vocabulary. The first argument to its constructors is the
+ parser for the type of the root element. The <code>parser_base</code>
+ class is the base type for all parser skeletons. The second and
+ third arguments to the <code>document</code>'s constructors are
+ the root element's name and namespace. The last argument,
+ <code>polymorphic</code>, specifies whether the XML documents
+ being parsed use polymorphism. For more information on support
+ for XML Schema polymorphism in the C++/Parser mapping refer
+ to <a href="#5.4">Section 5.4, "Support for Polymorphism"</a>.</p>
+
+ <p>The rest of the <code>document</code> interface consists of overloaded
+ <code>parse()</code> functions. The last two arguments in each of these
+ functions are <code>flags</code> and <code>properties</code>. The
+ <code>flags</code> argument allows you to modify the default behavior
+ of the parsing functions. The <code>properties</code> argument allows
+ you to override the schema location attributes specified in XML
+ documents. Note that the schema location paths are relative to an
+ XML document unless they are complete URIs. For example if you want
+ to use a local schema file then you will need to use a URI in the
+ form <code>file:///absolute/path/to/your/schema</code>.</p>
+
+ <p>A number of overloaded <code>parse()</code> functions have the
+ <code>system_id</code> and <code>public_id</code> arguments. The
+ system id is a <em>system</em> identifier of the resources being
+ parsed (for example, URI or a full file path). The public id is a
+ <em>public</em> identifier of the resource (for example, an
+ application-specific name or a relative file path). The system id
+ is used to resolve relative paths (for example, schema paths). In
+ diagnostics messages the public id is used if it is available.
+ Otherwise the system id is used.</p>
+
+ <p>The error handling mechanisms employed by the <code>document</code>
+ parser are described in <a href="#7.3">Section 7.3, "Error
+ Handling"</a>.</p>
+
+ <h2><a name="7.2">7.2 Expat Document Parser</a></h2>
+
+ <p>When Expat is used as the underlying XML parser, the
+ <code>document</code> type has the following interface. Note that
+ if the character type is <code>wchar_t</code>, then the string type
+ in the interface becomes <code>std::wstring</code>
+ (see <a href="#5.1">Section 5.1, "Character Type"</a>).</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class parser_base;
+ class error_handler;
+
+ class document
+ {
+ public:
+ document (parser_base&amp;,
+ const std::string&amp; root_element_name,
+ bool polymorphic = false);
+
+ document (parser_base&amp;,
+ const std::string&amp; root_element_namespace,
+ const std::string&amp; root_element_name,
+ bool polymorphic = false);
+
+ public:
+ // Parse a local file. The file is accessed with std::ifstream
+ // in binary mode. The std::ios_base::failure exception is used
+ // to report io errors (badbit and failbit).
+ void
+ parse (const std::string&amp; file);
+
+ // Parse a local file with a user-provided error_handler
+ // object. The file is accessed with std::ifstream in binary
+ // mode. The std::ios_base::failure exception is used to report
+ // io errors (badbit and failbit).
+ //
+ void
+ parse (const std::string&amp; file, error_handler&amp;);
+
+ public:
+ // Parse std::istream.
+ //
+ void
+ parse (std::istream&amp;);
+
+ // Parse std::istream with a user-provided error_handler object.
+ //
+ void
+ parse (std::istream&amp;, error_handler&amp;);
+
+ // Parse std::istream with a system id.
+ //
+ void
+ parse (std::istream&amp;, const std::string&amp; system_id);
+
+ // Parse std::istream with a system id and a user-provided
+ // error_handler object.
+ //
+ void
+ parse (std::istream&amp;,
+ const std::string&amp; system_id,
+ error_handler&amp;);
+
+ // Parse std::istream with system and public ids.
+ //
+ void
+ parse (std::istream&amp;,
+ const std::string&amp; system_id,
+ const std::string&amp; public_id);
+
+ // Parse std::istream with system and public ids and a user-provided
+ // error_handler object.
+ //
+ void
+ parse (std::istream&amp;,
+ const std::string&amp; system_id,
+ const std::string&amp; public_id,
+ error_handler&amp;);
+
+ public:
+ // Parse a chunk of input. You can call these functions multiple
+ // times with the last call having the last argument true.
+ //
+ void
+ parse (const void* data, std::size_t size, bool last);
+
+ void
+ parse (const void* data, std::size_t size, bool last,
+ error_handler&amp;);
+
+ void
+ parse (const void* data, std::size_t size, bool last,
+ const std::string&amp; system_id);
+
+ void
+ parse (const void* data, std::size_t size, bool last,
+ const std::string&amp; system_id,
+ error_handler&amp;);
+
+ void
+ parse (const void* data, std::size_t size, bool last,
+ const std::string&amp; system_id,
+ const std::string&amp; public_id);
+
+ void
+ parse (const void* data, std::size_t size, bool last,
+ const std::string&amp; system_id,
+ const std::string&amp; public_id,
+ error_handler&amp;);
+
+ public:
+ // Low-level Expat-specific parsing API.
+ //
+ void
+ parse_begin (XML_Parser);
+
+ void
+ parse_begin (XML_Parser, const std::string&amp; public_id);
+
+ void
+ parse_begin (XML_Parser, error_handler&amp;);
+
+ void
+ parse_begin (XML_Parser,
+ const std::string&amp; public_id,
+ error_handler&amp;);
+ void
+ parse_end ();
+ };
+}
+ </pre>
+
+ <p>The <code>document</code> class is a root parser for
+ the vocabulary. The first argument to its constructors is the
+ parser for the type of the root element. The <code>parser_base</code>
+ class is the base type for all parser skeletons. The second and
+ third arguments to the <code>document</code>'s constructors are
+ the root element's name and namespace. The last argument,
+ <code>polymorphic</code>, specifies whether the XML documents
+ being parsed use polymorphism. For more information on support
+ for XML Schema polymorphism in the C++/Parser mapping refer
+ to <a href="#5.4">Section 5.4, "Support for Polymorphism"</a>.</p>
+
+ <p>A number of overloaded <code>parse()</code> functions have the
+ <code>system_id</code> and <code>public_id</code> arguments. The
+ system id is a <em>system</em> identifier of the resources being
+ parsed (for example, URI or a full file path). The public id is a
+ <em>public</em> identifier of the resource (for example, an
+ application-specific name or a relative file path). The system id
+ is used to resolve relative paths. In diagnostics messages the
+ public id is used if it is available. Otherwise the system id
+ is used.</p>
+
+ <p>The <code>parse_begin()</code> and <code>parse_end()</code> functions
+ present a low-level, Expat-specific parsing API for maximum control.
+ A typical use-case would look like this (pseudo-code):</p>
+
+ <pre class="c++">
+xxx_pimpl root_p;
+document doc_p (root_p, "root");
+
+root_p.pre ();
+doc_p.parse_begin (xml_parser, "file.xml");
+
+while (more_data_to_parse)
+{
+ // Call XML_Parse or XML_ParseBuffer.
+
+ if (status == XML_STATUS_ERROR)
+ break;
+}
+
+// Call parse_end even in case of an error to translate
+// XML and Schema errors to exceptions or error_handler
+// calls.
+//
+doc.parse_end ();
+result_type result (root_p.post_xxx ());
+ </pre>
+
+ <p>Note that if your vocabulary uses XML namespaces, the
+ <code>XML_ParserCreateNS()</code> functions should be used to create
+ the XML parser. Space (<code>XML_Char (' ')</code>) should be used
+ as a separator (the second argument to <code>XML_ParserCreateNS()</code>).
+ </p>
+
+ <p>The error handling mechanisms employed by the <code>document</code>
+ parser are described in <a href="#7.3">Section 7.3, "Error
+ Handling"</a>.</p>
+
+
+ <h2><a name="7.3">7.3 Error Handling</a></h2>
+
+ <p>There are three categories of errors that can result from running
+ a parser on an XML document: System, XML, and Application.
+ The System category contains memory allocation and file/stream
+ operation errors. The XML category covers XML parsing and
+ well-formedness checking as well as XML Schema validation errors.
+ Finally, the Application category is for application logic errors
+ that you may want to propagate from parser implementations to the
+ caller of the parser.
+ </p>
+
+ <p>The System errors are mapped to the standard exceptions. The
+ out of memory condition is indicated by throwing an instance
+ of <code>std::bad_alloc</code>. The stream operation errors
+ are reported either by throwing an instance of
+ <code>std::ios_base::failure</code> if exceptions are enabled
+ or by setting the stream state.</p>
+
+ <p>Note that if you are parsing <code>std::istream</code> on
+ which exceptions are not enabled, then you will need to
+ check the stream state before calling the <code>post()</code>
+ callback, as shown in the following example:</p>
+
+ <pre class="c++">
+int
+main (int argc, char* argv[])
+{
+ ...
+
+ std::ifstream ifs (argv[1]);
+
+ if (ifs.fail ())
+ {
+ cerr &lt;&lt; argv[1] &lt;&lt; ": unable to open" &lt;&lt; endl;
+ return 1;
+ }
+
+ root_p.pre ();
+ doc_p.parse (ifs);
+
+ if (ifs.fail ())
+ {
+ cerr &lt;&lt; argv[1] &lt;&lt; ": io failure" &lt;&lt; endl;
+ return 1;
+ }
+
+ result_type result (root_p.post_xxx ());
+}
+ </pre>
+
+ <p>The above example can be rewritten to use exceptions
+ as shown below:</p>
+
+ <pre class="c++">
+int
+main (int argc, char* argv[])
+{
+ try
+ {
+ ...
+
+ std::ifstream ifs;
+ ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit);
+ ifs.open (argv[1]);
+
+ root_p.pre ();
+ doc_p.parse (ifs);
+ result_type result (root_p.post_xxx ());
+ }
+ catch (const std::ifstream::failure&amp;)
+ {
+ cerr &lt;&lt; argv[1] &lt;&lt; ": unable to open or io failure" &lt;&lt; endl;
+ return 1;
+ }
+}
+ </pre>
+
+
+ <p>For reporting application errors from parsing callbacks, you
+ can throw any exceptions of your choice. They are propagated to
+ the caller of the parser without any alterations.</p>
+
+ <p>The XML errors can be reported either by throwing the
+ <code>xml_schema::parsing</code> exception or by a callback
+ to the <code>xml_schema::error_handler</code> object (and
+ <code>xercesc::ErrorHandler</code> object in case of Xerces-C++).</p>
+
+ <p>The <code>xml_schema::parsing</code> exception contains
+ a list of warnings and errors that were accumulated during
+ parsing. Note that this exception is thrown only if there
+ was an error. This makes it impossible to obtain warnings
+ from an otherwise successful parsing using this mechanism.
+ The following listing shows the definition of
+ <code>xml_schema::parsing</code> exception. Note that if the
+ character type is <code>wchar_t</code>, then the string type
+ and output stream type in the definition become
+ <code>std::wstring</code> and <code>std::wostream</code>,
+ respectively (see <a href="#5.1">Section 5.1, "Character Type"</a>).</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class exception: public std::exception
+ {
+ protected:
+ virtual void
+ print (std::ostream&amp;) const = 0;
+ };
+
+ inline std::ostream&amp;
+ operator&lt;&lt; (std::ostream&amp; os, const exception&amp; e)
+ {
+ e.print (os);
+ return os;
+ }
+
+
+ class severity
+ {
+ public:
+ enum value
+ {
+ warning,
+ error
+ };
+ };
+
+
+ class error
+ {
+ public:
+ error (xml_schema::severity,
+ const std::string&amp; id,
+ unsigned long line,
+ unsigned long column,
+ const std::string&amp; message);
+
+ xml_schema::severity
+ severity () const;
+
+ const std::string&amp;
+ id () const;
+
+ unsigned long
+ line () const;
+
+ unsigned long
+ column () const;
+
+ const std::string&amp;
+ message () const;
+ };
+
+ std::ostream&amp;
+ operator&lt;&lt; (std::ostream&amp;, const error&amp;);
+
+
+ class diagnostics: public std::vector&lt;error>
+ {
+ };
+
+ std::ostream&amp;
+ operator&lt;&lt; (std::ostream&amp;, const diagnostics&amp;);
+
+
+ class parsing: public exception
+ {
+ public:
+ parsing ();
+ parsing (const xml_schema::diagnostics&amp;);
+
+ const xml_schema::diagnostics&amp;
+ diagnostics () const;
+
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ virtual void
+ print (std::ostream&amp;) const;
+ };
+}
+ </pre>
+
+ <p>The following example shows how we can catch and print this
+ exception. The code will print diagnostics messages one per line
+ in case of an error.</p>
+
+ <pre class="c++">
+int
+main (int argc, char* argv[])
+{
+ try
+ {
+ // Parse.
+ }
+ catch (const xml_schema::parsing&amp; e)
+ {
+ cerr &lt;&lt; e &lt;&lt; endl;
+ return 1;
+ }
+}
+ </pre>
+
+ <p>With the <code>error_handler</code> approach the diagnostics
+ messages are delivered as parsing progresses. The following
+ listing presents the definition of the <code>error_handler</code>
+ interface. Note that if the character type is <code>wchar_t</code>,
+ then the string type in the interface becomes <code>std::wstring</code>
+ (see <a href="#5.1">Section 5.1, "Character Type"</a>).</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class error_handler
+ {
+ public:
+ class severity
+ {
+ public:
+ enum value
+ {
+ warning,
+ error,
+ fatal
+ };
+ };
+
+ virtual bool
+ handle (const std::string&amp; id,
+ unsigned long line,
+ unsigned long column,
+ severity,
+ const std::string&amp; message) = 0;
+ };
+}
+ </pre>
+
+ <p>The return value of the <code>handle()</code> function indicates whether
+ parsing should continue if possible. The error with the fatal severity
+ level terminates the parsing process regardless of the returned value.
+ At the end of the parsing process with an error that was reported via
+ the <code>error_handler</code> object, an empty
+ <code>xml_schema::parsing</code> exception is thrown to indicate
+ the failure to the caller. You can alter this behavior by throwing
+ your own exception from the <code>handle()</code> function.</p>
+
+
+ <!-- Appendix A -->
+
+
+ <h1><a name="A">Appendix A &mdash; Supported XML Schema Constructs</a></h1>
+
+ <p>The C++/Parser mapping supports validation of the following W3C XML
+ Schema constructs in the generated code.</p>
+
+ <!-- border="1" is necessary for html2ps -->
+ <table id="features" border="1">
+ <tr><th>Construct</th><th>Notes</th></tr>
+ <tr><th colspan="2">Structure</th></tr>
+
+ <tr><td>element</td><td></td></tr>
+ <tr><td>attribute</td><td></td></tr>
+
+ <tr><td>any</td><td></td></tr>
+ <tr><td>anyAttribute</td><td></td></tr>
+
+ <tr><td>all</td><td></td></tr>
+ <tr><td>sequence</td><td></td></tr>
+ <tr><td>choice</td><td></td></tr>
+
+ <tr><td>complex type, empty content</td><td></td></tr>
+ <tr><td>complex type, mixed content</td><td></td></tr>
+ <tr><td>complex type, simple content extension</td><td></td></tr>
+ <tr><td>complex type, simple content restriction</td>
+ <td>Simple type facets are not validated.</td></tr>
+ <tr><td>complex type, complex content extension</td><td></td></tr>
+ <tr><td>complex type, complex content restriction</td><td></td></tr>
+
+ <tr><td>list</td><td></td></tr>
+
+ <tr><th colspan="2">Datatypes</th></tr>
+
+ <tr><td>byte</td><td></td></tr>
+ <tr><td>unsignedByte</td><td></td></tr>
+ <tr><td>short</td><td></td></tr>
+ <tr><td>unsignedShort</td><td></td></tr>
+ <tr><td>int</td><td></td></tr>
+ <tr><td>unsignedInt</td><td></td></tr>
+ <tr><td>long</td><td></td></tr>
+ <tr><td>unsignedLong</td><td></td></tr>
+ <tr><td>integer</td><td></td></tr>
+ <tr><td>nonPositiveInteger</td><td></td></tr>
+ <tr><td>nonNegativeInteger</td><td></td></tr>
+ <tr><td>positiveInteger</td><td></td></tr>
+ <tr><td>negativeInteger</td><td></td></tr>
+
+ <tr><td>boolean</td><td></td></tr>
+
+ <tr><td>float</td><td></td></tr>
+ <tr><td>double</td><td></td></tr>
+ <tr><td>decimal</td><td></td></tr>
+
+ <tr><td>string</td><td></td></tr>
+ <tr><td>normalizedString</td><td></td></tr>
+ <tr><td>token</td><td></td></tr>
+ <tr><td>Name</td><td></td></tr>
+ <tr><td>NMTOKEN</td><td></td></tr>
+ <tr><td>NCName</td><td></td></tr>
+ <tr><td>language</td><td></td></tr>
+ <tr><td>anyURI</td><td></td></tr>
+
+ <tr><td>ID</td><td>Identity constraint is not enforced.</td></tr>
+ <tr><td>IDREF</td><td>Identity constraint is not enforced.</td></tr>
+
+ <tr><td>NMTOKENS</td><td></td></tr>
+ <tr><td>IDREFS</td><td>Identity constraint is not enforced.</td></tr>
+
+ <tr><td>QName</td><td></td></tr>
+
+ <tr><td>base64Binary</td><td></td></tr>
+ <tr><td>hexBinary</td><td></td></tr>
+
+ <tr><td>date</td><td></td></tr>
+ <tr><td>dateTime</td><td></td></tr>
+ <tr><td>duration</td><td></td></tr>
+ <tr><td>gDay</td><td></td></tr>
+ <tr><td>gMonth</td><td></td></tr>
+ <tr><td>gMonthDay</td><td></td></tr>
+ <tr><td>gYear</td><td></td></tr>
+ <tr><td>gYearMonth</td><td></td></tr>
+ <tr><td>time</td><td></td></tr>
+ </table>
+
+
+ </div>
+</div>
+
+</body>
+</html>
diff --git a/documentation/cxx/parser/guide/makefile b/documentation/cxx/parser/guide/makefile
new file mode 100644
index 0000000..ca76286
--- /dev/null
+++ b/documentation/cxx/parser/guide/makefile
@@ -0,0 +1,12 @@
+.PHONY: all
+all: cxx-parser-guide.ps cxx-parser-guide.pdf
+
+cxx-parser-guide.pdf: cxx-parser-guide.ps
+ ps2pdf14 $<
+
+cxx-parser-guide.ps: index.xhtml guide.html2ps
+ html2ps -f guide.html2ps -o $@ $<
+
+.PHONY: clean
+clean:
+ rm -f cxx-parser-guide.ps cxx-parser-guide.pdf
diff --git a/documentation/cxx/tree/dbxml/driver.cxx b/documentation/cxx/tree/dbxml/driver.cxx
new file mode 120000
index 0000000..54d4313
--- /dev/null
+++ b/documentation/cxx/tree/dbxml/driver.cxx
@@ -0,0 +1 @@
+../../../../examples/cxx/tree/dbxml/driver.cxx \ No newline at end of file
diff --git a/documentation/cxx/tree/dbxml/index.xhtml b/documentation/cxx/tree/dbxml/index.xhtml
new file mode 100644
index 0000000..e4e01e6
--- /dev/null
+++ b/documentation/cxx/tree/dbxml/index.xhtml
@@ -0,0 +1,350 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+
+<head>
+ <title>C++/Tree Mapping and Berkeley DB XML Integration Guide</title>
+
+ <meta name="copyright" content="&copy; 2006-2009 Code Synthesis Tools CC"/>
+ <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,berkeley,db,dbxml"/>
+ <meta name="description" content="C++/Tree Mapping and Berkeley DB XML Integration Guide"/>
+
+ <link rel="stylesheet" type="text/css" href="../../../default.css" />
+
+<style type="text/css">
+ pre {
+ background : #cde8f6;
+
+ padding : 0 0 0 1em;
+ margin : 2em 0em 2em 0;
+
+ }
+
+ h1 {padding-top: 1em;}
+
+</style>
+</head>
+
+<body>
+<div id="container">
+ <div id="content">
+
+ <h1>Introduction</h1>
+
+ <p>This guide shows how to integrate the
+ <a href="http://www.codesynthesis.com/products/xsd/c++/tree/">C++/Tree</a>
+ mapping generated by
+ <a href="http://www.codesynthesis.com/products/xsd/">CodeSynthesis XSD</a>
+ with
+ <a href="http://www.oracle.com/database/berkeley-db/xml/index.html">Berkeley DB XML</a>.
+
+ Berkeley DB XML is an embedded XML database which allows efficient
+ storage and query of XML instance documents.
+
+ CodeSynthesis XSD is a W3C XML Schema to C++ data binding compiler.
+
+ The C++/Tree mapping allows you to manipulate the data stored in XML
+ using objects that semantically correspond to your application
+ domain rather than dealing with direct representations of XML.
+
+ For an introduction to
+ the Berkeley DB XML refer to the
+ <a href="http://www.oracle.com/database/berkeley-db/xml/index.html">Berkeley DB XML
+ Getting Started Guide</a>.
+ For an introduction to the C++/Tree mapping refer to
+ the <a href="../guide/">C++/Tree Mapping Getting Started Guide</a>.
+ </p>
+
+
+ <p>This guide describes the following four operations:</p>
+
+ <ul>
+ <li>Create a new document in DB from an object model</li>
+ <li>Create an object model from a document in DB</li>
+ <li>Create an object model from a document fragment in DB</li>
+ <li>Update a document fragment in DB from an object model</li>
+ </ul>
+
+ <p>Our examples will be based on simple XML for book library. The XML
+ Schema definition for the library is in
+ <a href="./library.xsd">library.xsd</a> and is compiled by XSD
+ to obtain <a href="./library.hxx">library.hxx</a> and
+ <a href="./library.cxx">library.cxx</a>. A sample XML document
+ is presented below:</p>
+
+ <pre>
+&lt;lib:catalog xmlns:lib="http://www.codesynthesis.com/library">
+ &lt;book available="true" id="ES">
+ &lt;isbn>20530902&lt;/isbn>
+ &lt;title>The Elements of Style&lt;/title>
+ &lt;genre>reference&lt;/genre>
+
+ &lt;author>
+ &lt;name>William Strunk, Jr.&lt;/name>
+ &lt;born>1869-07-01&lt;/born>
+ &lt;died>1946-09-26&lt;/died>
+ &lt;/author>
+
+ &lt;author>
+ &lt;name>E.B. White&lt;/name>
+ &lt;born>1899-07-11&lt;/born>
+ &lt;died>1985-10-01&lt;/died>
+ &lt;/author>
+ &lt;/book>
+&lt;/lib:catalog>
+ </pre>
+
+ <p>All C++ code fragments that are presented in this guide are available
+ as a single program in <a href="./driver.cxx">driver.cxx</a>.
+ The complete example is available in the
+ <code>examples/cxx/tree/dbxml</code> directory of the XSD distribution.
+ </p>
+
+ <p>Note that due to the incomplete DOM API implementation provided by DB
+ XML (as of version 2.3.10), the generated code and your application
+ should be compiled with the <code>DBXML_DOM</code> macro defined in
+ order to avoid using unsupported parts of the API.
+ </p>
+
+ <h1>Create Document from Object Model</h1>
+
+ <p>In this step, we will programmatically create a book catalog
+ with one book, save it into an <code>XmlDocument</code> object
+ using one of the serialization functions generated by XSD (
+ <code>catalog_</code> in our case), and store the
+ <code>XmlDocument</code> object as a new document in the
+ DB container:</p>
+
+ <pre>
+XmlManager manager;
+XmlContainer container (manager.createContainer ("new.bdbxml"));
+XmlUpdateContext update_context (manager.createUpdateContext ());
+XmlQueryContext context (manager.createQueryContext ());
+context.setNamespace ("lib", "http://www.codesynthesis.com/library");
+
+// Create a new catalog with one book.
+//
+catalog c;
+
+book b (20530902, // ISBN
+ title ("The Elements of Style"), // Title
+ genre::reference, // Genre
+ "ES"); // ID
+
+author strunk ("William Strunk, Jr.", date (1869, 7, 1));
+strunk.died (date (1946, 9, 26));
+
+b.author ().push_back (strunk);
+c.book ().push_back (b);
+
+// Create a new XML document.
+//
+XmlDocument doc (manager.createDocument ());
+doc.setName ("new.xml");
+
+// Obtain its DOM representation and add the root element.
+//
+xercesc::DOMDocument&amp; dom_doc (*doc.getContentAsDOM ());
+
+dom_doc.appendChild (
+ dom_doc.createElementNS (
+ xml::string ("http://www.codesynthesis.com/library").c_str (),
+ xml::string ("lib:catalog").c_str ()));
+
+// Serialize the object model to the XML document. Also avoid
+// re-initializing the Xerces-C++ runtime since XmlManager has
+// it initialized.
+//
+catalog_ (dom_doc, c, xml_schema::flags::dont_initialize);
+
+// Place the document into the container.
+//
+container.putDocument (doc, update_context);
+ </pre>
+
+ <p>If we now resolve the <code>new.xml</code> in the container and
+ print its content, we will get:</p>
+
+ <pre>
+&lt;lib:catalog xmlns:lib="http://www.codesynthesis.com/library">
+ &lt;book available="true" id="ES">
+ &lt;isbn>20530902&lt;/isbn>
+ &lt;title>The Elements of Style&lt;/title>
+ &lt;genre>reference&lt;/genre>
+ &lt;author>
+ &lt;name>William Strunk, Jr.&lt;/name>
+ &lt;born>1869-07-01&lt;/born>
+ &lt;died>1946-09-26&lt;/died>
+ &lt;/author>
+ &lt;/book>
+&lt;/lib:catalog>
+ </pre>
+
+ <h1>Create Object Model from Document</h1>
+
+ <p>Creating an object model from a document is a matter
+ of obtaining <code>XmlDocument</code> object and passing its DOM
+ representation to one of the parsing functions generated by XSD
+ (<code>catalog_</code> in our case):
+ </p>
+
+ <pre>
+// Resolve the document in the container.
+//
+XmlDocument doc (container.getDocument ("new.xml"));
+
+// Create the object model from the document's DOM. Also avoid
+// re-initializing the Xerces-C++ runtime since XmlManager has
+// it initialized.
+//
+auto_ptr&lt;catalog> c (catalog_ (*doc.getContentAsDOM (),
+ xml_schema::flags::dont_initialize));
+
+cerr &lt;&lt; *c &lt;&lt; endl;
+ </pre>
+
+ <p>This code fragment prints:</p>
+
+ <pre>
+book:
+isbn: 20530902
+title: The Elements of Style
+genre: reference
+author:
+name: William Strunk, Jr.
+born: 1869-07-01
+died: 1946-09-26
+available: 1
+id: ES
+ </pre>
+
+ <h1>Create Object Model from Document Fragment</h1>
+
+ <p>The following code fragment looks up the book with id <code>"ES"</code>
+ using XQuery. It then creates a <code>book</code> object from the
+ resulting <code>XmlValue</code>:</p>
+
+ <pre>
+string query ("collection('new.bdbxml')/lib:catalog/book[@id='ES']");
+
+// Find "The Elements of Style".
+//
+XmlValue v;
+XmlResults results (manager.query (query, context));
+
+if (results.next (v))
+{
+ // Create an object model from the document fragment.
+ //
+ auto_ptr&lt;book> b (
+ new book (
+ *static_cast&lt;xercesc::DOMElement*> (v.asNode ())));
+
+ cerr &lt;&lt; *b &lt;&lt; endl;
+}
+ </pre>
+
+<p>This code fragment prints:</p>
+
+ <pre>
+isbn: 20530902
+title: The Elements of Style
+genre: reference
+author:
+name: William Strunk, Jr.
+born: 1869-07-01
+died: 1946-09-26
+available: 1
+id: ES
+ </pre>
+
+ <p>Note that we had to perform a <code>static_cast</code> from
+ <code>xercesc::DOMNode</code>
+ returned by the <code>XmlValue::asNode</code> member function to
+ <code>xercesc::DOMElement</code>. This is safe since we know
+ that in our schema books are represented as XML elements.</p>
+
+ <h1>Update Document Fragment from Object Model</h1>
+
+ <p>Analogous to the create case, the following code fragment looks
+ up the book with id <code>"ES"</code> using XQuery. It then creates
+ a <code>book</code> object from the resulting <code>XmlValue</code>,
+ adds another author, changes the availability status, and saves
+ the changes back to the <code>XmlValue</code> object:
+ </p>
+
+ <pre>
+string query ("collection('new.bdbxml')/lib:catalog/book[@id='ES']");
+
+// Find "The Elements of Style".
+//
+XmlValue v;
+XmlResults results (manager.query (query, context));
+
+if (results.next (v))
+{
+ // Create an object model from the document fragment.
+ //
+ auto_ptr&lt;book> b (
+ new book (
+ *static_cast&lt;xercesc::DOMElement*> (v.asNode ())));
+
+ // Add another author, change the availability status.
+ //
+ author white ("E.B. White", date (1899, 7, 11));
+ white.died (date (1985, 10, 1));
+
+ b->author ().push_back (white);
+ b->available (false);
+
+ // Update the document fragment from the object model.
+ //
+ *static_cast&lt;xercesc::DOMElement*> (v.asNode ()) &lt;&lt; *b;
+
+ // Update the document in the container.
+ //
+ XmlDocument doc (v.asDocument ());
+ container.updateDocument (doc, update_context);
+}
+ </pre>
+
+ <p>If we now resolve the <code>new.xml</code> in the container and
+ print its content, we will get:</p>
+
+ <pre>
+&lt;lib:catalog xmlns:lib="http://www.codesynthesis.com/library">
+ &lt;book available="false" id="ES">
+ &lt;isbn>20530902&lt;/isbn>
+ &lt;title>The Elements of Style&lt;/title>
+ &lt;genre>reference&lt;/genre>
+ &lt;author>
+ &lt;name>William Strunk, Jr.&lt;/name>
+ &lt;born>1869-07-01&lt;/born>
+ &lt;died>1946-09-26&lt;/died>
+ &lt;/author>
+ &lt;author>
+ &lt;name>E.B. White&lt;/name>
+ &lt;born>1899-07-11&lt;/born>
+ &lt;died>1985-10-01&lt;/died>
+ &lt;/author>
+ &lt;/book>
+&lt;/lib:catalog>
+ </pre>
+
+ </div>
+ <div id="footer">
+ &copy;2006-2009 <a href="http://www.codesynthesis.com">CODE SYNTHESIS TOOLS CC</a>
+
+ <div id="terms">
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the
+ <a href="http://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free
+ Documentation License, version 1.2</a>; with no Invariant Sections,
+ no Front-Cover Texts and no Back-Cover Texts.
+ </div>
+ </div>
+
+</div>
+
+</body>
+</html>
diff --git a/documentation/cxx/tree/dbxml/library.xsd b/documentation/cxx/tree/dbxml/library.xsd
new file mode 120000
index 0000000..636c490
--- /dev/null
+++ b/documentation/cxx/tree/dbxml/library.xsd
@@ -0,0 +1 @@
+../../../../examples/cxx/tree/dbxml/library.xsd \ No newline at end of file
diff --git a/documentation/cxx/tree/guide/guide.html2ps b/documentation/cxx/tree/guide/guide.html2ps
new file mode 100644
index 0000000..727b82d
--- /dev/null
+++ b/documentation/cxx/tree/guide/guide.html2ps
@@ -0,0 +1,65 @@
+@html2ps {
+ option {
+ toc: hb;
+ colour: 1;
+ hyphenate: 1;
+ titlepage: 1;
+ }
+
+ datefmt: "%B %Y";
+
+ titlepage {
+ content: "
+<div align=center>
+ <h1><big>C++/Tree Mapping</big></h1>
+ <h1><big>Getting Started Guide</big></h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+</div>
+ <p>Copyright &copy; 2005-2009 CODE SYNTHESIS TOOLS CC</p>
+
+ <p>Permission is granted to copy, distribute and/or modify this
+ document under the terms of the
+ <a href='http://www.codesynthesis.com/licenses/fdl-1.2.txt'>GNU Free
+ Documentation License, version 1.2</a>; with no Invariant Sections,
+ no Front-Cover Texts and no Back-Cover Texts.
+ </p>
+
+ <p>This document is available in the following formats:
+ <a href='http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/index.xhtml'>XHTML</a>,
+ <a href='http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-parser-guide.pdf'>PDF</a>, and
+ <a href='http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-parser-guide.ps'>PostScript</a>.</p>";
+ }
+
+ toc {
+ indent: 2em;
+ }
+
+ header {
+ odd-right: $H;
+ even-left: $H;
+ }
+
+ footer {
+ odd-left: $D;
+ odd-center: $T;
+ odd-right: $N;
+
+ even-left: $N;
+ even-center: $T;
+ even-right: $D;
+ }
+}
+
+body {
+ font-size: 12pt;
+ text-align: justify;
+}
+
+pre {
+ font-size: 10pt;
+}
diff --git a/documentation/cxx/tree/guide/index.xhtml b/documentation/cxx/tree/guide/index.xhtml
new file mode 100644
index 0000000..787610a
--- /dev/null
+++ b/documentation/cxx/tree/guide/index.xhtml
@@ -0,0 +1,2678 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+
+<head>
+ <title>C++/Tree Mapping Getting Started Guide</title>
+
+ <meta name="copyright" content="&copy; 2005-2009 Code Synthesis Tools CC"/>
+ <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,parsing,serialization,validation"/>
+ <meta name="description" content="C++/Tree Mapping Getting Started Guide"/>
+
+ <link rel="stylesheet" type="text/css" href="../../../default.css" />
+
+<style type="text/css">
+ pre {
+ padding : 0 0 0 0em;
+ margin : 0em 0em 0em 0;
+
+ font-size : 102%
+ }
+
+ body {
+ min-width: 48em;
+ }
+
+ h1 {
+ font-weight: bold;
+ font-size: 200%;
+ line-height: 1.2em;
+ }
+
+ h2 {
+ font-weight : bold;
+ font-size : 150%;
+
+ padding-top : 0.8em;
+ }
+
+ h3 {
+ font-size : 140%;
+ padding-top : 0.8em;
+ }
+
+ /* Adjust indentation for three levels. */
+ #container {
+ max-width: 48em;
+ }
+
+ #content {
+ padding: 0 0.1em 0 4em;
+ /*background-color: red;*/
+ }
+
+ #content h1 {
+ margin-left: -2.06em;
+ }
+
+ #content h2 {
+ margin-left: -1.33em;
+ }
+
+ /* Title page */
+
+ #titlepage {
+ padding: 2em 0 1em 0;
+ border-bottom: 1px solid black;
+ }
+
+ #titlepage .title {
+ font-weight: bold;
+ font-size: 200%;
+ text-align: center;
+ }
+
+ #titlepage #first-title {
+ padding: 1em 0 0.4em 0;
+ }
+
+ #titlepage #second-title {
+ padding: 0.4em 0 2em 0;
+ }
+
+ /* Lists */
+ ul.list li {
+ padding-top : 0.3em;
+ padding-bottom : 0.3em;
+ }
+
+ div.img {
+ text-align: center;
+ padding: 2em 0 2em 0;
+ }
+
+ /* */
+ dl dt {
+ padding : 0.8em 0 0 0;
+ }
+
+ /* Built-in table */
+ #builtin {
+ margin: 2em 0 2em 0;
+
+ border-collapse : collapse;
+ border : 1px solid;
+ border-color : #000000;
+
+ font-size : 11px;
+ line-height : 14px;
+ }
+
+ #builtin th, #builtin td {
+ border: 1px solid;
+ padding : 0.9em 0.9em 0.7em 0.9em;
+ }
+
+ #builtin th {
+ background : #cde8f6;
+ }
+
+ #builtin td {
+ text-align: left;
+ }
+
+ /* TOC */
+ table.toc {
+ border-style : none;
+ border-collapse : separate;
+ border-spacing : 0;
+
+ margin : 0.2em 0 0.2em 0;
+ padding : 0 0 0 0;
+ }
+
+ table.toc tr {
+ padding : 0 0 0 0;
+ margin : 0 0 0 0;
+ }
+
+ table.toc * td, table.toc * th {
+ border-style : none;
+ margin : 0 0 0 0;
+ vertical-align : top;
+ }
+
+ table.toc * th {
+ font-weight : normal;
+ padding : 0em 0.1em 0em 0;
+ text-align : left;
+ white-space : nowrap;
+ }
+
+ table.toc * table.toc th {
+ padding-left : 1em;
+ }
+
+ table.toc * td {
+ padding : 0em 0 0em 0.7em;
+ text-align : left;
+ }
+</style>
+
+
+</head>
+
+<body>
+<div id="container">
+ <div id="content">
+
+ <div class="noprint">
+
+ <div id="titlepage">
+ <div class="title" id="first-title">C++/Tree Mapping</div>
+ <div class="title" id="second-title">Getting Started Guide</div>
+
+ <p>Copyright &copy; 2005-2009 CODE SYNTHESIS TOOLS CC</p>
+
+ <p>Permission is granted to copy, distribute and/or modify this
+ document under the terms of the
+ <a href="http://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free
+ Documentation License, version 1.2</a>; with no Invariant Sections,
+ no Front-Cover Texts and no Back-Cover Texts.
+ </p>
+
+ <p>This document is available in the following formats:
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/index.xhtml">XHTML</a>,
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-tree-guide.pdf">PDF</a>, and
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/cxx-tree-guide.ps">PostScript</a>.</p>
+
+ </div>
+
+ <h1>Table of Contents</h1>
+
+ <table class="toc">
+ <tr>
+ <th></th><td><a href="#0">Preface</a>
+ <table class="toc">
+ <tr><th></th><td><a href="#0.1">About This Document</a></td></tr>
+ <tr><th></th><td><a href="#0.2">More Information</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>1</th><td><a href="#1">Introduction</a>
+ <table class="toc">
+ <tr><th>1.1</th><td><a href="#1.1">Mapping Overview</a></td></tr>
+ <tr><th>1.2</th><td><a href="#1.2">Benefits</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>2</th><td><a href="#2">Hello World Example</a>
+ <table class="toc">
+ <tr><th>2.1</th><td><a href="#2.1">Writing XML Document and Schema</a></td></tr>
+ <tr><th>2.2</th><td><a href="#2.2">Translating Schema to C++</a></td></tr>
+ <tr><th>2.3</th><td><a href="#2.3">Implementing Application Logic</a></td></tr>
+ <tr><th>2.4</th><td><a href="#2.4">Compiling and Running</a></td></tr>
+ <tr><th>2.5</th><td><a href="#2.5">Adding Serialization</a></td></tr>
+ <tr><th>2.6</th><td><a href="#2.6">Selecting Naming Convention</a></td></tr>
+ <tr><th>2.7</th><td><a href="#2.7">Generating Documentation</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>3</th><td><a href="#3">Overall Mapping Configuration</a>
+ <table class="toc">
+ <tr><th>3.1</th><td><a href="#3.1">Character Type</a></td></tr>
+ <tr><th>3.2</th><td><a href="#3.2">Support for Polymorphism </a></td></tr>
+ <tr><th>3.3</th><td><a href="#3.3">Namespace Mapping</a></td></tr>
+ <tr><th>3.4</th><td><a href="#3.4">Thread Safety</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>4</th><td><a href="#4">Working with Object Models</a>
+ <table class="toc">
+ <tr><th>4.1</th><td><a href="#4.1">Attribute and Element Cardinalities</a></td></tr>
+ <tr><th>4.2</th><td><a href="#4.2">Accessing the Object Model</a></td></tr>
+ <tr><th>4.3</th><td><a href="#4.3">Modifying the Object Model</a></td></tr>
+ <tr><th>4.4</th><td><a href="#4.4">Creating the Object Model from Scratch</a></td></tr>
+ <tr><th>4.5</th><td><a href="#4.5">Mapping for the Built-in XML Schema Types</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>5</th><td><a href="#5">Parsing</a>
+ <table class="toc">
+ <tr><th>5.1</th><td><a href="#5.1">XML Schema Validation and Searching</a></td></tr>
+ <tr><th>5.2</th><td><a href="#5.2">Error Handling</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>6</th><td><a href="#6">Serialization</a>
+ <table class="toc">
+ <tr><th>6.1</th><td><a href="#6.1">Namespace and Schema Information</a></td></tr>
+ <tr><th>6.2</th><td><a href="#6.2">Error Handling</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ </table>
+ </div>
+
+ <h1><a name="0">Preface</a></h1>
+
+ <h2><a name="0.1">About This Document</a></h2>
+
+ <p>The goal of this document is to provide you with an understanding of
+ the C++/Tree programming model and allow you to efficiently evaluate
+ XSD against your project's technical requirements. As such, this
+ document is intended for C++ developers and software architects
+ who are looking for an XML processing solution. For a more in-depth
+ description of the C++/Tree mapping refer to the
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/">C++/Tree
+ Mapping User Manual</a>.</p>
+
+ <p>Prior experience with XML and C++ is required to understand this
+ document. Basic understanding of XML Schema is advantageous but
+ not expected or required.
+ </p>
+
+
+ <h2><a name="0.2">More Information</a></h2>
+
+ <p>Beyond this guide, you may also find the following sources of
+ information useful:</p>
+
+ <ul class="list">
+ <li><a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/">C++/Tree
+ Mapping User Manual</a></li>
+
+ <li><a href="http://wiki.codesynthesis.com/Tree/Customization_guide">C++/Tree
+ Mapping Customization Guide</a></li>
+
+ <li><a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/dbxml/">C++/Tree
+ Mapping and Berkeley DB XML Integration Guide</a></li>
+
+ <li><a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree
+ Mapping Frequently Asked Questions (FAQ)</a></li>
+
+ <li><a href="http://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD
+ Compiler Command Line Manual</a></li>
+
+ <li>The <code>examples/cxx/tree/</code> directory in the XSD
+ distribution contains a collection of examples and a README
+ file with an overview of each example.</li>
+
+ <li>The <code>README</code> file in the XSD distribution explains
+ how to compile the examples on various platforms.</li>
+
+ <li>The <a href="http://www.codesynthesis.com/mailman/listinfo/xsd-users">xsd-users</a>
+ mailing list is the place to ask technical questions about XSD and the C++/Parser mapping.
+ Furthermore, the <a href="http://www.codesynthesis.com/pipermail/xsd-users/">archives</a>
+ may already have answers to some of your questions.</li>
+
+ </ul>
+
+ <!-- Introduction -->
+
+ <h1><a name="1">1 Introduction</a></h1>
+
+ <p>Welcome to CodeSynthesis XSD and the C++/Tree mapping. XSD is a
+ cross-platform W3C XML Schema to C++ data binding compiler. C++/Tree
+ is a W3C XML Schema to C++ mapping that represents the data stored
+ in XML as a statically-typed, vocabulary-specific object model.
+ </p>
+
+ <h2><a name="1.1">1.1 Mapping Overview</a></h2>
+
+ <p>Based on a formal description of an XML vocabulary (schema), the
+ C++/Tree mapping produces a tree-like data structure suitable for
+ in-memory processing. The core of the mapping consists of C++
+ classes that constitute the object model and are derived from
+ types defined in XML Schema as well as XML parsing and
+ serialization code.</p>
+
+ <p>Besides the core features, C++/Tree provide a number of additional
+ mapping elements that can be useful in some applications. These
+ include serialization and extraction to/from formats others than
+ XML, such as unstructured text (useful for debugging) and binary
+ representations such as XDR and CDR for high-speed data processing,
+ integration with XML databases such as Berkeley DB XML, and automatic
+ documentation generation. The C++/Tree mapping also provides a wide
+ range of mechanisms for controlling and customizing the generated
+ code.</p>
+
+ <p>A typical application that uses C++/Tree for XML processing usually
+ performs the following three steps: it first reads (parses) an XML
+ document to an in-memory object model, it then performs some useful
+ computations on that object model which may involve modification
+ of the model, and finally it may write (serialize) the modified
+ object model back to XML.</p>
+
+ <p>The next chapter presents a simple application that performs these
+ three steps. The following chapters show how to use the C++/Tree
+ mapping in more detail.</p>
+
+ <h2><a name="1.2">1.2 Benefits</a></h2>
+
+ <p>Traditional XML access APIs such as Document Object Model (DOM)
+ or Simple API for XML (SAX) have a number of drawbacks that
+ make them less suitable for creating robust and maintainable
+ XML processing applications. These drawbacks include:
+ </p>
+
+ <ul class="list">
+ <li>Generic representation of XML in terms of elements, attributes,
+ and text forces an application developer to write a substantial
+ amount of bridging code that identifies and transforms pieces
+ of information encoded in XML to a representation more suitable
+ for consumption by the application logic.</li>
+
+ <li>String-based flow control defers error detection to runtime.
+ It also reduces code readability and maintainability.</li>
+
+ <li>Lack of type safety because the data is represented as text.</li>
+
+ <li>Resulting applications are hard to debug, change, and
+ maintain.</li>
+ </ul>
+
+ <p>In contrast, statically-typed, vocabulary-specific object model
+ produced by the C++/Tree mapping allows you to operate in your
+ domain terms instead of the generic elements, attributes, and
+ text. Static typing helps catch errors at compile-time rather
+ than at run-time. Automatic code generation frees you for more
+ interesting tasks (such as doing something useful with the
+ information stored in the XML documents) and minimizes the
+ effort needed to adapt your applications to changes in the
+ document structure. To summarize, the C++/Tree object model has
+ the following key advantages over generic XML access APIs:</p>
+
+ <ul class="list">
+ <li><b>Ease of use.</b> The generated code hides all the complexity
+ associated with parsing and serializing XML. This includes navigating
+ the structure and converting between the text representation and
+ data types suitable for manipulation by the application
+ logic.</li>
+
+ <li><b>Natural representation.</b> The object representation allows
+ you to access the XML data using your domain vocabulary instead
+ of generic elements, attributes, and text.</li>
+
+ <li><b>Concise code.</b> With the object representation the
+ application implementation is simpler and thus easier
+ to read and understand.</li>
+
+ <li><b>Safety.</b> The generated object model is statically
+ typed and uses functions instead of strings to access the
+ information. This helps catch programming errors at compile-time
+ rather than at runtime.</li>
+
+ <li><b>Maintainability.</b> Automatic code generation minimizes the
+ effort needed to adapt the application to changes in the
+ document structure. With static typing, the C++ compiler
+ can pin-point the places in the client code that need to be
+ changed.</li>
+
+ <li><b>Compatibility.</b> Sequences of elements are represented in
+ the object model as containers conforming to the standard C++
+ sequence requirements. This makes it possible to use standard
+ C++ algorithms on the object representation and frees you from
+ learning yet another container interface, as is the case with
+ DOM.</li>
+
+ <li><b>Efficiency.</b> If the application makes repetitive use
+ of the data extracted from XML, then the C++/Tree object model
+ is more efficient because the navigation is performed using
+ function calls rather than string comparisons and the XML
+ data is extracted only once. Furthermore, the runtime memory
+ usage is reduced due to more efficient data storage
+ (for instance, storing numeric data as integers instead of
+ strings) as well as the static knowledge of cardinality
+ constraints.</li>
+ </ul>
+
+
+ <!-- Hello World Parser -->
+
+
+ <h1><a name="2">2 Hello World Example</a></h1>
+
+ <p>In this chapter we will examine how to parse, access, modify, and
+ serialize a very simple XML document using the XSD-generated
+ C++/Tree object model. The code presented in this chapter is
+ based on the <code>hello</code> example which can be found in
+ the <code>examples/cxx/tree/</code> directory of the XSD
+ distribution.</p>
+
+ <h2><a name="2.1">2.1 Writing XML Document and Schema</a></h2>
+
+ <p>First, we need to get an idea about the structure
+ of the XML documents we are going to process. Our
+ <code>hello.xml</code>, for example, could look like this:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0"?>
+&lt;hello>
+
+ &lt;greeting>Hello&lt;/greeting>
+
+ &lt;name>sun&lt;/name>
+ &lt;name>moon&lt;/name>
+ &lt;name>world&lt;/name>
+
+&lt;/hello>
+ </pre>
+
+ <p>Then we can write a description of the above XML in the
+ XML Schema language and save it into <code>hello.xsd</code>:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0"?>
+&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ &lt;xs:complexType name="hello_t">
+ &lt;xs:sequence>
+ &lt;xs:element name="greeting" type="xs:string"/>
+ &lt;xs:element name="name" type="xs:string" maxOccurs="unbounded"/>
+ &lt;/xs:sequence>
+ &lt;/xs:complexType>
+
+ &lt;xs:element name="hello" type="hello_t"/>
+
+&lt;/xs:schema>
+ </pre>
+
+ <p>Even if you are not familiar with XML Schema, it
+ should be easy to connect declarations in <code>hello.xsd</code>
+ to elements in <code>hello.xml</code>. The <code>hello_t</code> type
+ is defined as a sequence of the nested <code>greeting</code> and
+ <code>name</code> elements. Note that the term sequence in XML
+ Schema means that elements should appear in a particular order
+ as opposed to appearing multiple times. The <code>name</code>
+ element has its <code>maxOccurs</code> property set to
+ <code>unbounded</code> which means it can appear multiple times
+ in an XML document. Finally, the globally-defined <code>hello</code>
+ element prescribes the root element for our vocabulary. For an
+ easily-approachable introduction to XML Schema refer to
+ <a href="http://www.w3.org/TR/xmlschema-0/">XML Schema Part 0:
+ Primer</a>.</p>
+
+ <p>The above schema is a specification of our XML vocabulary; it tells
+ everybody what valid documents of our XML-based language should look
+ like. We can also update our <code>hello.xml</code> to include the
+ information about the schema so that XML parsers can validate
+ our document:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0"?>
+&lt;hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="hello.xsd">
+
+ &lt;greeting>Hello&lt;/greeting>
+
+ &lt;name>sun&lt;/name>
+ &lt;name>moon&lt;/name>
+ &lt;name>world&lt;/name>
+
+&lt;/hello>
+ </pre>
+
+
+ <p>The next step is to compile the schema to generate the object
+ model and parsing functions.</p>
+
+ <h2><a name="2.2">2.2 Translating Schema to C++</a></h2>
+
+ <p>Now we are ready to translate our <code>hello.xsd</code> to C++.
+ To do this we invoke the XSD compiler from a terminal (UNIX) or
+ a command prompt (Windows):
+ </p>
+
+ <pre class="terminal">
+$ xsd cxx-tree hello.xsd
+ </pre>
+
+ <p>The XSD compiler produces two C++ files: <code>hello.hxx</code> and
+ <code>hello.cxx</code>. The following code fragment is taken from
+ <code>hello.hxx</code>; it should give you an idea about what gets
+ generated:
+ </p>
+
+ <pre class="c++">
+class hello_t
+{
+public:
+ // greeting
+ //
+ typedef xml_schema::string greeting_type;
+
+ const greeting_type&amp;
+ greeting () const;
+
+ greeting_type&amp;
+ greeting ();
+
+ void
+ greeting (const greeting_type&amp; x);
+
+ // name
+ //
+ typedef xml_schema::string name_type;
+ typedef xsd::sequence&lt;name_type> name_sequence;
+ typedef name_sequence::iterator name_iterator;
+ typedef name_sequence::const_iterator name_const_iterator;
+
+ const name_sequence&amp;
+ name () const;
+
+ name_sequence&amp;
+ name ();
+
+ void
+ name (const name_sequence&amp; s);
+
+ // Constructor.
+ //
+ hello_t (const greeting_type&amp;);
+
+ ...
+
+};
+
+std::auto_ptr&lt;hello_t>
+hello (const std::string&amp; uri);
+
+std::auto_ptr&lt;hello_t>
+hello (std::istream&amp;);
+ </pre>
+
+ <p>The <code>hello_t</code> C++ class corresponds to the
+ <code>hello_t</code> XML Schema type. For each element
+ in this type a set of C++ type definitions as well as
+ accessor and modifier functions are generated inside the
+ <code>hello_t</code> class. Note that the type definitions
+ and member functions for the <code>greeting</code> and
+ <code>name</code> elements are different because of the
+ cardinality differences between these two elements
+ (<code>greeting</code> is a required single element and
+ <code>name</code> is a sequence of elements).</p>
+
+ <p>The <code>xml_schema::string</code> type used in the type
+ definitions is a C++ class provided by the XSD runtime
+ that corresponds to built-in XML Schema type
+ <code>string</code>. The <code>xml_schema::string</code>
+ is based on <code>std::string</code> and can be used as
+ such. Similarly, the <code>sequence</code> class template
+ that is used in the <code>name_sequence</code> type
+ definition is based on and has the same interface as
+ <code>std::vector</code>. The mapping between the built-in
+ XML Schema types and C++ types is described in more detail in
+ <a href="#4.5">Section 4.5, "Mapping for the Built-in XML Schema
+ Types"</a>. The <code>hello_t</code> class also includes a
+ constructor with an initializer for the required
+ <code>greeting</code> element as its argument.</p>
+
+ <p>The <code>hello</code> overloaded global functions correspond
+ to the <code>hello</code> global element in XML Schema. A
+ global element in XML Schema is a valid document root.
+ By default XSD generated a set of parsing functions for each
+ global element defined in XML Schema (this can be overridden
+ with the <code>--root-element-*</code> options). For more
+ information on parsing functions see <a href="#5">Chapter 5,
+ "Parsing"</a>.</p>
+
+ <h2><a name="2.3">2.3 Implementing Application Logic</a></h2>
+
+ <p>At this point we have all the parts we need to do something useful
+ with the information stored in our XML document:
+ </p>
+
+ <pre class="c++">
+#include &lt;iostream>
+#include "hello.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ try
+ {
+ auto_ptr&lt;hello_t> h (hello (argv[1]));
+
+ for (hello_t::name_const_iterator i (h->name ().begin ());
+ i != h->name ().end ();
+ ++i)
+ {
+ cerr &lt;&lt; h->greeting () &lt;&lt; ", " &lt;&lt; *i &lt;&lt; "!" &lt;&lt; endl;
+ }
+ }
+ catch (const xml_schema::exception&amp; e)
+ {
+ cerr &lt;&lt; e &lt;&lt; endl;
+ return 1;
+ }
+}
+ </pre>
+
+ <p>The first part of our application calls one of the parsing
+ functions to parser an XML file specified in the command line.
+ We then use the returned object model to iterate over names
+ and print a greeting line for each of them. Finally, we
+ catch and print the <code>xml_schema::exception</code>
+ exception in case something goes wrong. This exception
+ is the root of the exception hierarchy used by the
+ XSD-generated code.
+ </p>
+
+
+ <h2><a name="2.4">2.4 Compiling and Running</a></h2>
+
+ <p>After saving our application from the previous section in
+ <code>driver.cxx</code>, we are ready to compile our first
+ program and run it on the test XML document. On a UNIX
+ system this can be done with the following commands:
+ </p>
+
+ <pre class="terminal">
+$ c++ -I.../libxsd -c driver.cxx hello.cxx
+$ c++ -o driver driver.o hello.o -lxerces-c
+$ ./driver hello.xml
+Hello, sun!
+Hello, moon!
+Hello, world!
+ </pre>
+
+ <p>Here <code>.../libxsd</code> represents the path to the
+ <code>libxsd</code> directory in the XSD distribution.
+ Note also that we are required to link our application
+ with the Xerces-C++ library because the generated code
+ uses it as the underlying XML parser.</p>
+
+ <h2><a name="2.5">2.5 Adding Serialization</a></h2>
+
+ <p>While parsing and accessing the XML data may be everything
+ you need, there are applications that require creating new
+ or modifying existing XML documents. By default XSD does
+ not produce serialization code. We will need to request
+ it with the <code>--generate-serialization</code> options:</p>
+
+ <pre class="terminal">
+$ xsd cxx-tree --generate-serialization hello.xsd
+ </pre>
+
+ <p>If we now examine the generated <code>hello.hxx</code> file,
+ we will find a set of overloaded serialization functions,
+ including the following version:</p>
+
+ <pre class="c++">
+void
+hello (std::ostream&amp;,
+ const hello_t&amp;,
+ const xml_schema::namespace_infomap&amp; =
+ xml_schema::namespace_infomap ());
+
+ </pre>
+
+ <p>Just like with parsing functions, XSD generates serialization
+ functions for each global element unless instructed otherwise
+ with one of the <code>--root-element-*</code> options. For more
+ information on serialization functions see <a href="#6">Chapter 6,
+ "Serialization"</a>.</p>
+
+ <p>We first examine an application that modifies an existing
+ object model and serializes it back to XML:</p>
+
+ <pre class="c++">
+#include &lt;iostream>
+#include "hello.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ try
+ {
+ auto_ptr&lt;hello_t> h (hello (argv[1]));
+
+ // Change the greeting phrase.
+ //
+ h->greeting ("Hi");
+
+ // Add another entry to the name sequence.
+ //
+ h->name ().push_back ("mars");
+
+ // Serialize the modified object model to XML.
+ //
+ xml_schema::namespace_infomap map;
+ map[""].name = "";
+ map[""].schema = "hello.xsd";
+
+ hello (cout, *h, map);
+ }
+ catch (const xml_schema::exception&amp; e)
+ {
+ cerr &lt;&lt; e &lt;&lt; endl;
+ return 1;
+ }
+}
+ </pre>
+
+ <p>First, our application parses an XML document and obtains its
+ object model as in the previous example. Then it changes the
+ greeting string and adds another entry to the list of names.
+ Finally, it serializes the object model back to XML by calling
+ the serialization function.</p>
+
+ <p>The first argument we pass to the serialization function is
+ <code>cout</code> which results in the XML being written to
+ the standard output for us to inspect. We could have also
+ written the result to a file or memory buffer by creating an
+ instance of <code>std::ofstream</code> or <code>std::ostringstream</code>
+ and passing it instead of <code>cout</code>. The second argument is the
+ object model we want to serialize. The final argument is an optional
+ namespace information map for our vocabulary. It captures information
+ such as namespaces, namespace prefixes to which they should be mapped,
+ and schemas associated with these namespaces. If we don't provide
+ this argument then generic namespace prefixes (<code>p1</code>,
+ <code>p2</code>, etc.) will be automatically assigned to XML namespaces
+ and no schema information will be added to the resulting document
+ (see <a href="#6">Chapter 6, "Serialization"</a> for details).
+ In our case, the prefix (map key) and namespace name are empty
+ because our vocabulary does not use XML namespaces.</p>
+
+ <p>If we now compile and run this application we will see the
+ output as shown in the following listing:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0"?>
+&lt;hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="hello.xsd">
+
+ &lt;greeting>Hi&lt;/greeting>
+
+ &lt;name>sun&lt;/name>
+ &lt;name>moon&lt;/name>
+ &lt;name>world&lt;/name>
+ &lt;name>mars&lt;/name>
+
+&lt;/hello>
+ </pre>
+
+ <p>We can also create and serialize an object model from scratch
+ as shown in the following example:</p>
+
+ <pre class="c++">
+#include &lt;iostream>
+#include &lt;fstream>
+#include "hello.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ try
+ {
+ hello_t h ("Hi");
+
+ hello_t::name_sequence&amp; ns (h.name ());
+
+ ns.push_back ("Jane");
+ ns.push_back ("John");
+
+ // Serialize the object model to XML.
+ //
+ xml_schema::namespace_infomap map;
+ map[""].name = "";
+ map[""].schema = "hello.xsd";
+
+ std::ofstream ofs (argv[1]);
+ hello (ofs, h, map);
+ }
+ catch (const xml_schema::exception&amp; e)
+ {
+ cerr &lt;&lt; e &lt;&lt; endl;
+ return 1;
+ }
+}
+ </pre>
+
+ <p>In this example we used the generated constructor to create
+ an instance of type <code>hello_t</code>. To reduce typing,
+ we obtained a reference to the name sequence which we then
+ used to add a few names. The serialization part is identical
+ to the previous example except this time we are writing to
+ a file. If we compile and run this program, it produces the
+ following XML file:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0"?>
+&lt;hello xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="hello.xsd">
+
+ &lt;greeting>Hi&lt;/greeting>
+
+ &lt;name>Jane&lt;/name>
+ &lt;name>John&lt;/name>
+
+&lt;/hello>
+ </pre>
+
+ <h2><a name="2.6">2.6 Selecting Naming Convention</a></h2>
+
+ <p>By default XSD uses the so-called K&amp;R (Kernighan and Ritchie)
+ identifier naming convention in the generated code. In this
+ convention both type and function names are in lower case and
+ words are separated by underscores. If your application code or
+ schemas use a different notation, you may want to change the
+ naming convention used in the generated code for consistency.
+ XSD supports a set of widely-used naming conventions
+ that you can select with the <code>--type-naming</code> and
+ <code>--function-naming</code> options. You can also further
+ refine one of the predefined conventions or create a completely
+ custom naming scheme by using the <code>--*-regex</code> options.</p>
+
+ <p>As an example, let's assume that our "Hello World" application
+ uses the so-called upper-camel-case naming convention for types
+ (that is, each word in a type name is capitalized) and the K&amp;R
+ convention for function names. Since K&amp;R is the default
+ convention for both type and function names, we only need to
+ change the type naming scheme:</p>
+
+ <pre class="terminal">
+$ xsd cxx-tree --type-naming ucc hello.xsd
+ </pre>
+
+ <p>The <code>ucc</code> argument to the <code>--type-naming</code>
+ options stands for upper-camel-case. If we now examine the
+ generated <code>hello.hxx</code>, we will see the following
+ changes compared to the declarations shown in the previous
+ sections:</p>
+
+ <pre class="c++">
+class Hello_t
+{
+public:
+ // greeting
+ //
+ typedef xml_schema::String GreetingType;
+
+ const GreetingType&amp;
+ greeting () const;
+
+ GreetingType&amp;
+ greeting ();
+
+ void
+ greeting (const GreetingType&amp; x);
+
+ // name
+ //
+ typedef xml_schema::String NameType;
+ typedef xsd::sequence&lt;NameType> NameSequence;
+ typedef NameSequence::iterator NameIterator;
+ typedef NameSequence::const_iterator NameConstIterator;
+
+ const NameSequence&amp;
+ name () const;
+
+ NameSequence&amp;
+ name ();
+
+ void
+ name (const NameSequence&amp; s);
+
+ // Constructor.
+ //
+ Hello_t (const GreetingType&amp;);
+
+ ...
+
+};
+
+std::auto_ptr&lt;Hello_t>
+hello (const std::string&amp; uri);
+
+std::auto_ptr&lt;Hello_t>
+hello (std::istream&amp;);
+ </pre>
+
+ <p>Notice that the type names in the <code>xml_schema</code> namespace,
+ for example <code>xml_schema::String</code>, now also use the
+ upper-camel-case naming convention. The only thing that we may
+ be unhappy about in the above code is the <code>_t</code>
+ suffix in <code>Hello_t</code>. If we are not in a position
+ to change the schema, we can <em>touch-up</em> the <code>ucc</code>
+ convention with a custom translation rule using the
+ <code>--type-regex</code> option:</p>
+
+ <pre class="terminal">
+$ xsd cxx-tree --type-naming ucc --type-regex '/ (.+)_t/\u$1/' hello.xsd
+ </pre>
+
+ <p>This results in the following changes to the generated code:</p>
+
+ <pre class="c++">
+class Hello
+{
+public:
+ // greeting
+ //
+ typedef xml_schema::String GreetingType;
+
+ const GreetingType&amp;
+ greeting () const;
+
+ GreetingType&amp;
+ greeting ();
+
+ void
+ greeting (const GreetingType&amp; x);
+
+ // name
+ //
+ typedef xml_schema::String NameType;
+ typedef xsd::sequence&lt;NameType> NameSequence;
+ typedef NameSequence::iterator NameIterator;
+ typedef NameSequence::const_iterator NameConstIterator;
+
+ const NameSequence&amp;
+ name () const;
+
+ NameSequence&amp;
+ name ();
+
+ void
+ name (const NameSequence&amp; s);
+
+ // Constructor.
+ //
+ Hello (const GreetingType&amp;);
+
+ ...
+
+};
+
+std::auto_ptr&lt;Hello>
+hello (const std::string&amp; uri);
+
+std::auto_ptr&lt;Hello>
+hello (std::istream&amp;);
+ </pre>
+
+ <p>For more detailed information on the <code>--type-naming</code>,
+ <code>--function-naming</code>, <code>--type-regex</code>, and
+ other <code>--*-regex</code> options refer to the NAMING
+ CONVENTION section in the <a href="http://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD
+ Compiler Command Line Manual</a>.</p>
+
+ <h2><a name="2.7">2.7 Generating Documentation</a></h2>
+
+ <p>While our object model is quite simple, real-world vocabularies
+ can be quite complex with hundreds of types, elements, and
+ attributes. For such vocabularies figuring out which types
+ provide which member functions by studying the generated
+ source code or schemas can be a daunting task. To provide
+ application developers with a more accessible way of
+ understanding the generated object models, the XSD compiler
+ can be instructed to produce source code with documentation
+ comments in the Doxygen format. Then the source code can be
+ processed with the <a href="http://www.doxygen.org">Doxygen</a>
+ documentation system to extract this information and produce
+ documentation in various formats.
+ </p>
+
+ <p>In this section we will see how to generate documentation
+ for our "Hello World" vocabulary. To showcase the full power
+ of the XSD documentation facilities, we will first document
+ our schema. The XSD compiler will then transfer
+ this information from the schema to the generated code and
+ then to the object model documentation. Note that the
+ documentation in the schema is not required for XSD to
+ generate useful documentation. Below you will find
+ our <code>hello.xsd</code> with added documentation:</p>
+
+ <pre class="xml">
+&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ &lt;xs:complexType name="hello_t">
+
+ &lt;xs:annotation>
+ &lt;xs:documentation>
+ The hello_t type consists of a greeting phrase and a
+ collection of names to which this greeting applies.
+ &lt;/xs:documentation>
+ &lt;/xs:annotation>
+
+ &lt;xs:sequence>
+
+ &lt;xs:element name="greeting" type="xs:string">
+ &lt;xs:annotation>
+ &lt;xs:documentation>
+ The greeting element contains the greeting phrase
+ for this hello object.
+ &lt;/xs:documentation>
+ &lt;/xs:annotation>
+ &lt;/xs:element>
+
+ &lt;xs:element name="name" type="xs:string" maxOccurs="unbounded">
+ &lt;xs:annotation>
+ &lt;xs:documentation>
+ The name elements contains names to be greeted.
+ &lt;/xs:documentation>
+ &lt;/xs:annotation>
+ &lt;/xs:element>
+
+ &lt;/xs:sequence>
+ &lt;/xs:complexType>
+
+ &lt;xs:element name="hello" type="hello_t">
+ &lt;xs:annotation>
+ &lt;xs:documentation>
+ The hello element is a root of the Hello XML vocabulary.
+ Every conforming document should start with this element.
+ &lt;/xs:documentation>
+ &lt;/xs:annotation>
+ &lt;/xs:element>
+
+&lt;/xs:schema>
+ </pre>
+
+ <p>The first step in obtaining the documentation is to recompile
+ our schema with the <code>--generate-doxygen</code> option:</p>
+
+ <pre class="terminal">
+$ xsd cxx-tree --generate-serialization --generate-doxygen hello.xsd
+ </pre>
+
+ <p>Now the generated <code>hello.hxx</code> file contains comments
+ in the Doxygen format. The next step is to process this file
+ with the Doxygen documentation system. If your project does
+ not use Doxygen then you first need to create a configuration
+ file for your project:</p>
+
+ <pre class="terminal">
+$ doxygen -g hello.doxygen
+ </pre>
+
+ <p>You only need to perform this step once. Now we can generate
+ the documentation by executing the following command in the
+ directory with the generated source code:</p>
+
+ <pre class="terminal">
+$ doxygen hello.doxygen
+ </pre>
+
+ <p>While the generated documentation can be useful as is, we can
+ go one step further and link (using the Doxygen tags mechanism)
+ the documentation for our object model with the documentation
+ for the XSD runtime library which defines C++ classes for the
+ built-in XML Schema types. This way we can seamlessly browse
+ between documentation for the <code>hello_t</code> class which
+ is generated by the XSD compiler and the <code>xml_schema::string</code>
+ class which is defined in the XSD runtime library. The Doxygen
+ configuration file for the XSD runtime is provided with the XSD
+ distribution.</p>
+
+ <p>You can view the result of the steps described in this section
+ on the <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/hello/html/annotated.html">Hello
+ Example Documentation</a> page.</p>
+
+ <!-- Chapater 3 -->
+
+
+ <h1><a name="3">3 Overall Mapping Configuration</a></h1>
+
+ <p>The C++/Tree mapping has a number of configuration parameters that
+ determine the overall properties and behavior of the generated code.
+ Configuration parameters are specified with the XSD command line
+ options. This chapter describes configuration aspects that are most
+ commonly encountered by application developers. These include:
+ the character type that is used by the generated code, handling of
+ vocabularies that use XML Schema polymorphism, XML Schema to C++
+ namespace mapping, and thread safety. For more ways to configure
+ the generated code refer to the
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD
+ Compiler Command Line Manual</a>.
+ </p>
+
+ <h2><a name="3.1">3.1 Character Type</a></h2>
+
+ <p>The C++/Tree mapping has built-in support for two character types:
+ <code>char</code> and <code>wchar_t</code>. You can select the
+ character type with the <code>--char-type</code> command line
+ option. The default character type is <code>char</code>. The
+ character type affects all string and string-based types that
+ are used in the mapping. These include the string-based built-in
+ XML Schema types, exception types, stream types, etc.</p>
+
+ <p>Another aspect of the mapping that depends on the character type
+ is character encoding. For the <code>char</code> character type
+ the encoding is UTF-8. For the <code>wchar_t</code> character type
+ the encoding is automatically selected between UTF-16 and
+ UTF-32/UCS-4 depending on the size of the <code>wchar_t</code> type.
+ On some platforms (for example, Windows with Visual C++ and AIX with IBM XL
+ C++) <code>wchar_t</code> is 2 bytes long. For these platforms the
+ encoding is UTF-16. On other platforms <code>wchar_t</code> is 4 bytes
+ long and UTF-32/UCS-4 is used.</p>
+
+ <h2><a name="3.2">3.2 Support for Polymorphism</a></h2>
+
+ <p>By default XSD generates non-polymorphic code. If your vocabulary
+ uses XML Schema polymorphism in the form of <code>xsi:type</code>
+ and/or substitution groups, then you will need to compile
+ your schemas with the <code>--generate-polymorphic</code> option
+ to produce polymorphism-aware code. For more information on
+ working with polymorphic object models, refer to
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.11">Section 2.11,
+ "Mapping for <code>xsi:type</code> and Substitution Groups"</a> in
+ the C++/Tree Mapping User Manual.</p>
+
+ <h2><a name="3.3">3.3 Namespace Mapping</a></h2>
+
+ <p>XSD maps XML namespaces specified in the <code>targetNamespace</code>
+ attribute in XML Schema to one or more nested C++ namespaces. By
+ default, a namespace URI is mapped to a sequence of C++ namespace
+ names by removing the protocol and host parts and splitting the
+ rest into a sequence of names with <code>'/'</code> as the name
+ separator.</p>
+
+ <p>The default mapping of namespace URIs to C++ namespaces
+ can be altered using the <code>--namespace-map</code> and
+ <code>--namespace-regex</code> compiler options. For example,
+ to map namespace URI <code>http://www.codesynthesis.com/my</code> to
+ C++ namespace <code>cs::my</code>, we can use the following option:</p>
+
+ <pre class="terminal">
+--namespace-map http://www.codesynthesis.com/my=cs::my
+ </pre>
+
+ <p>A vocabulary without a namespace is mapped to the global scope. This
+ also can be altered with the above options by using an empty name
+ for the XML namespace:</p>
+
+ <pre class="terminal">
+--namespace-map =cs
+ </pre>
+
+ <h2><a name="3.4">3.4 Thread Safety</a></h2>
+
+ <p>XSD-generated code is thread-safe in the sense that you can
+ use different instantiations of the object model in several
+ threads concurrently. This is possible due to the generated
+ code not relying on any writable global variables. If you need
+ to share the same object between several threads then you will
+ need to provide some form of synchronization. One approach would
+ be to use the generated code customization mechanisms to embed
+ synchronization primitives into the generated C++ classes. For more
+ information on generated code customization refer to the
+ <a href="http://wiki.codesynthesis.com/Tree/Customization_guide">C++/Tree
+ Mapping Customization Guide</a>.</p>
+
+ <p>If you also would like to call parsing and/or serialization
+ functions from several threads potentially concurrently, then
+ you will need to make sure the Xerces-C++ runtime is initialized
+ and terminated only once. The easiest way to do this is to
+ initialize/terminate Xerces-C++ from <code>main()</code> when
+ there are no threads yet/anymore:</p>
+
+ <pre class="c++">
+#include &lt;xercesc/util/PlatformUtils.hpp>
+
+int
+main ()
+{
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ {
+ // Start/terminate threads and parse/serialize here.
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+}
+ </pre>
+
+ <p>Because you initialize the Xerces-C++ runtime yourself you should
+ also pass the <code>xml_schema::flags::dont_initialize</code> flag
+ to parsing and serialization functions. See <a href="#5">Chapter 5,
+ "Parsing"</a> and <a href="#6">Chapter 6, "Serialization"</a> for
+ more information.</p>
+
+
+ <!-- Chapater 4 -->
+
+
+ <h1><a name="4">4 Working with Object Models</a></h1>
+
+ <p>As we have seen in the previous chapters, the XSD compiler generates
+ a C++ class for each type defined in XML Schema. Together these classes
+ constitute an object model for an XML vocabulary. In this chapter we
+ will take a closer look at different elements that comprise an
+ object model class as well as how to create, access, and modify
+ object models.</p>
+
+ <p>In this and subsequent chapters we will use the following schema
+ that describes a collection of person records. We save it in
+ <code>people.xsd</code>:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0"?>
+&lt;xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ &lt;xs:simpleType name="gender_t">
+ &lt;xs:restriction base="xs:string">
+ &lt;xs:enumeration value="male"/>
+ &lt;xs:enumeration value="female"/>
+ &lt;/xs:restriction>
+ &lt;/xs:simpleType>
+
+ &lt;xs:complexType name="person_t">
+ &lt;xs:sequence>
+ &lt;xs:element name="first-name" type="xs:string"/>
+ &lt;xs:element name="middle-name" type="xs:string" minOccurs="0"/>
+ &lt;xs:element name="last-name" type="xs:string"/>
+ &lt;xs:element name="gender" type="gender_t"/>
+ &lt;xs:element name="age" type="xs:short"/>
+ &lt;/xs:sequence>
+ &lt;xs:attribute name="id" type="xs:unsignedInt" use="required"/>
+ &lt;/xs:complexType>
+
+ &lt;xs:complexType name="people_t">
+ &lt;xs:sequence>
+ &lt;xs:element name="person" type="person_t" maxOccurs="unbounded"/>
+ &lt;/xs:sequence>
+ &lt;/xs:complexType>
+
+ &lt;xs:element name="people" type="people_t"/>
+
+&lt;/xs:schema>
+ </pre>
+
+ <p>A sample XML instance to go along with this schema is saved
+ in <code>people.xml</code>:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0"?>
+&lt;people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="people.xsd">
+
+ &lt;person id="1">
+ &lt;first-name>John&lt;/first-name>
+ &lt;last-name>Doe&lt;/last-name>
+ &lt;gender>male&lt;/gender>
+ &lt;age>32&lt;/age>
+ &lt;/person>
+
+ &lt;person id="2">
+ &lt;first-name>Jane&lt;/first-name>
+ &lt;middle-name>Mary&lt;/middle-name>
+ &lt;last-name>Doe&lt;/last-name>
+ &lt;gender>female&lt;/gender>
+ &lt;age>28&lt;/age>
+ &lt;/person>
+
+&lt;/people>
+ </pre>
+
+ <p>Compiling <code>people.xsd</code> with the XSD compiler results
+ in three generated C++ classes: <code>gender_t</code>,
+ <code>person_t</code>, and <code>people_t</code>.
+ The <code>gender_t</code> class is modelled after the C++
+ <code>enum</code> type. Its definition is presented below:</p>
+
+ <pre class="c++">
+class gender_t: public xml_schema::string
+{
+public:
+ enum value
+ {
+ male,
+ female
+ };
+
+ gender_t (value);
+ gender_t (const xml_schema::string&amp;);
+
+ gender_t&amp;
+ operator= (value);
+
+ operator value () const;
+};
+ </pre>
+
+ <p>The following listing shows how we can use this type:</p>
+
+ <pre class="c++">
+gender_t m (gender_t::male);
+gender_t f ("female");
+
+if (m == "female" || f == gender_t::male)
+{
+ ...
+}
+
+switch (m)
+{
+case gender_t::male:
+ {
+ ...
+ }
+case gender_t::female:
+ {
+ ...
+ }
+}
+ </pre>
+
+ <p>The other two classes will be examined in detail in the subsequent
+ sections.</p>
+
+ <h2><a name="4.1">4.1 Attribute and Element Cardinalities</a></h2>
+
+ <p>As we have seen in the previous chapters, XSD generates a different
+ set of type definitions and member functions for elements with
+ different cardinalities. The C++/Tree mapping divides all the possible
+ element and attribute cardinalities into three cardinality classes:
+ <em>one</em>, <em>optional</em>, and <em>sequence</em>.</p>
+
+ <p>The <em>one</em> cardinality class covers all elements that should
+ occur exactly once as well as required attributes. In our
+ example, the <code>first-name</code>, <code>last-name</code>,
+ <code>gender</code>, and <code>age</code> elements as well as
+ the <code>id</code> attribute belong to this cardinality class.
+ The following code fragment shows type definitions as well as the
+ accessor and modifier functions that are generated for the
+ <code>gender</code> element in the <code>person_t</code> class:</p>
+
+ <pre class="c++">
+class person_t
+{
+ // gender
+ //
+ typedef gender_t gender_type;
+
+ const gender_type&amp;
+ gender () const;
+
+ gender_type&amp;
+ gender ();
+
+ void
+ gender (const gender_type&amp;);
+};
+ </pre>
+
+ <p>The <code>gender_type</code> type is an alias for the element's type.
+ The first two accessor functions return read-only (constant) and
+ read-write references to the element's value, respectively. The
+ modifier function sets the new value for the element.</p>
+
+ <p>The <em>optional</em> cardinality class covers all elements that
+ can occur zero or one time as well as optional attributes. In our
+ example, the <code>middle-name</code> element belongs to this
+ cardinality class. The following code fragment shows the type
+ definitions as well as the accessor and modifier functions that
+ are generated for this element in the <code>person_t</code> class:</p>
+
+ <pre class="c++">
+class person_t
+{
+ // middle-name
+ //
+ typedef xml_schema::string middle_name_type;
+ typedef xsd::optional&lt;middle_name_type> middle_name_optional;
+
+ const middle_name_optional&amp;
+ middle_name () const;
+
+ middle_name_optional&amp;
+ middle_name ();
+
+ void
+ middle_name (const middle_name_type&amp;);
+
+ void
+ middle_name (const middle_name_optional&amp;);
+};
+ </pre>
+
+ <p>As with the <code>gender</code> element, <code>middle_name_type</code>
+ is an alias for the element's type. The <code>middle_name_optional</code>
+ type is a container for the element's optional value. It can be queried
+ for the presence of the value using the <code>present()</code> function.
+ The value itself can be retrieved using the <code>get()</code>
+ accessor and set using the <code>set()</code> modifier. The container
+ can be reverted to the value not present state with the call to the
+ <code>reset()</code> function. The following example shows how we
+ can use this container:</p>
+
+ <pre class="c++">
+person_t::middle_name_optional n ("John");
+
+if (n.preset ())
+{
+ cout &lt;&lt; n.get () &lt;&lt; endl;
+}
+
+n.set ("Jane");
+n.reset ();
+ </pre>
+
+
+ <p>Unlike the <em>one</em> cardinality class, the accessor functions
+ for the <em>optional</em> class return read-only (constant) and
+ read-write references to the container instead of the element's
+ value directly. The modifier functions set the new value for the
+ element.</p>
+
+ <p>Finally, the <em>sequence</em> cardinality class covers all elements
+ that can occur more than once. In our example, the
+ <code>person</code> element in the <code>people_t</code> type
+ belongs to this cardinality class. The following code fragment shows
+ the type definitions as well as the accessor and modifier functions
+ that are generated for this element in the <code>people_t</code>
+ class:</p>
+
+ <pre class="c++">
+class people_t
+{
+ // person
+ //
+ typedef person_t person_type;
+ typedef xsd::sequence&lt;person_type> person_sequence;
+ typedef person_sequence::iterator person_iterator;
+ typedef person_sequence::const_iterator person_const_iterator;
+
+ const person_sequence&amp;
+ person () const;
+
+ person_sequence&amp;
+ person ();
+
+ void
+ person (const person_sequence&amp;);
+};
+ </pre>
+
+ <p>Identical to the other cardinality classes, <code>person_type</code>
+ is an alias for the element's type. The <code>person_sequence</code>
+ type is a sequence container for the element's values. It is based
+ on and has the same interface as <code>std::vector</code> and
+ therefore can be used in similar ways. The <code>person_iterator</code>
+ and <code>person_const_iterator</code> types are read-only
+ (constant) and read-write iterators for the <code>person_sequence</code>
+ container.</p>
+
+ <p>Similar to the <em>optional</em> cardinality class, the
+ accessor functions for the <em>sequence</em> class return
+ read-only (constant) and read-write references to the sequence
+ container. The modifier functions copies the entries from
+ the passed sequence.</p>
+
+ <p>For complex schemas with many levels of nested compositors
+ (<code>xs:choice</code> and <code>xs:sequence</code>) it can
+ be hard to deduce the cardinality class of a particular element.
+ The generated Doxygen documentation can greatly help with
+ this task. For each element and attribute the documentation
+ clearly identifies its cardinality class. Alternatively, you
+ can study the generated header files to find out the cardinality
+ class of a particular attribute or element. In the next sections
+ we will examine how to access and modify information stored in
+ an object model using accessor and modifier functions described
+ in this section.</p>
+
+
+ <h2><a name="4.2">4.2 Accessing the Object Model</a></h2>
+
+ <p>In this section we will learn how to get to the information
+ stored in the object model for our person records vocabulary.
+ The following application accesses and prints the contents
+ of the <code>people.xml</code> file:</p>
+
+ <pre class="c++">
+#include &lt;iostream>
+#include "people.hxx"
+
+using namespace std;
+
+int
+main ()
+{
+ auto_ptr&lt;people_t> ppl (people ("people.xml"));
+
+ // Iterate over individual person records.
+ //
+ people_t::person_sequence&amp; ps (ppl->person ());
+
+ for (people_t::person_iterator i (ps.begin ()); i != ps.end (); ++i)
+ {
+ person_t&amp; p (*i);
+
+ // Print names: first-name and last-name are required elements,
+ // middle-name is optional.
+ //
+ cout &lt;&lt; "name: " &lt;&lt; p.first_name () &lt;&lt; " ";
+
+ if (p.middle_name ().present ())
+ cout &lt;&lt; p.middle_name ().get () &lt;&lt; " ";
+
+ cout &lt;&lt; p.last_name () &lt;&lt; endl;
+
+ // Print gender, age, and id which are all required.
+ //
+ cout &lt;&lt; "gender: " &lt;&lt; p.gender () &lt;&lt; endl
+ &lt;&lt; "age: " &lt;&lt; p.age () &lt;&lt; endl
+ &lt;&lt; "id: " &lt;&lt; p.id () &lt;&lt; endl
+ &lt;&lt; endl;
+ }
+}
+ </pre>
+
+ <p>This code shows common patterns of accessing elements and attributes
+ with different cardinality classes. For the sequence element
+ (<code>person</code> in <code>people_t</code>) we first obtain a
+ reference to the container and then iterate over individual
+ records. The values of elements and attributes with the
+ <em>one</em> cardinality class (<code>first-name</code>,
+ <code>last-name</code>, <code>gender</code>, <code>age</code>,
+ and <code>id</code>) can be obtained directly by calling the
+ corresponding accessor functions. For the optional element
+ <code>middle-name</code> we first check if the value is present
+ and only then call <code>get()</code> to retrieve it.</p>
+
+ <p>Note that when we want to reduce typing by creating a variable
+ representing a fragment of the object model that we are currently
+ working with (<code>ps</code> and <code>p</code> above), we obtain
+ a reference to that fragment instead of making a potentially
+ expensive copy. This is generally a good rule to follow when
+ creating high-performance applications.</p>
+
+ <p>If we run the above application on our sample
+ <code>people.xml</code>, the output looks as follows:</p>
+
+ <pre class="terminal">
+name: John Doe
+gender: male
+age: 32
+id: 1
+
+name: Jane Mary Doe
+gender: female
+age: 28
+id: 2
+ </pre>
+
+
+ <h2><a name="4.3">4.3 Modifying the Object Model</a></h2>
+
+ <p>In this section we will learn how to modify the information
+ stored in the object model for our person records vocabulary.
+ The following application changes the contents of the
+ <code>people.xml</code> file:</p>
+
+ <pre class="c++">
+#include &lt;iostream>
+#include "people.hxx"
+
+using namespace std;
+
+int
+main ()
+{
+ auto_ptr&lt;people_t> ppl (people ("people.xml"));
+
+ // Iterate over individual person records and increment
+ // the age.
+ //
+ people_t::person_sequence&amp; ps (ppl->person ());
+
+ for (people_t::person_iterator i (ps.begin ()); i != ps.end (); ++i)
+ {
+ // Alternative way: i->age ()++;
+ //
+ i->age (i->age () + 1);
+ }
+
+ // Add middle-name to the first record and remove it from
+ // the second.
+ //
+ person_t&amp; john (ps[0]);
+ person_t&amp; jane (ps[1]);
+
+ john.middle_name ("Mary");
+ jane.middle_name ().reset ();
+
+ // Add another John record.
+ //
+ ps.push_back (john);
+
+ // Serialize the modified object model to XML.
+ //
+ xml_schema::namespace_infomap map;
+ map[""].name = "";
+ map[""].schema = "people.xsd";
+
+ people (cout, *ppl, map);
+}
+ </pre>
+
+ <p>The first modification the above application performs is iterating
+ over person records and incrementing the age value. This code
+ fragment shows how to modify the value of a required attribute
+ or element. The next modification shows how to set a new value
+ for the optional <code>middle-name</code> element as well
+ as clear its value. Finally the example adds a copy of the
+ John Doe record to the <code>person</code> element sequence.</p>
+
+ <p>Note that in this case using references for the <code>ps</code>,
+ <code>john</code>, and <code>jane</code> variables is no longer
+ a performance improvement but a requirement for the application
+ to function correctly. If we hadn't used references, all our changes
+ would have been made on copies without affecting the object model.</p>
+
+ <p>If we run the above application on our sample <code>people.xml</code>,
+ the output looks as follows:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0"?>
+&lt;people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="people.xsd">
+
+ &lt;person id="1">
+ &lt;first-name>John&lt;/first-name>
+ &lt;middle-name>Mary&lt;/middle-name>
+ &lt;last-name>Doe&lt;/last-name>
+ &lt;gender>male&lt;/gender>
+ &lt;age>33&lt;/age>
+ &lt;/person>
+
+ &lt;person id="2">
+ &lt;first-name>Jane&lt;/first-name>
+ &lt;last-name>Doe&lt;/last-name>
+ &lt;gender>female&lt;/gender>
+ &lt;age>29&lt;/age>
+ &lt;/person>
+
+ &lt;person id="1">
+ &lt;first-name>John&lt;/first-name>
+ &lt;middle-name>Mary&lt;/middle-name>
+ &lt;last-name>Doe&lt;/last-name>
+ &lt;gender>male&lt;/gender>
+ &lt;age>33&lt;/age>
+ &lt;/person>
+
+&lt;/people>
+ </pre>
+
+
+ <h2><a name="4.4">4.4 Creating the Object Model from Scratch</a></h2>
+
+ <p>In this section we will learn how to create a new object model
+ for our person records vocabulary. The following application
+ recreates the content of the original <code>people.xml</code>
+ file:</p>
+
+ <pre class="c++">
+#include &lt;iostream>
+#include "people.hxx"
+
+using namespace std;
+
+int
+main ()
+{
+ people_t ppl;
+ people_t::person_sequence&amp; ps (ppl.person ());
+
+ // Add the John Doe record.
+ //
+ ps.push_back (
+ person_t ("John", // first-name
+ "Doe", // last-name
+ gender_t::male, // gender
+ 32, // age
+ 1));
+
+ // Add the Jane Doe record.
+ //
+ ps.push_back (
+ person_t ("Jane", // first-name
+ "Doe", // last-name
+ gender_t::female, // gender
+ 28, // age
+ 2)); // id
+
+ // Add middle name to the Jane Doe record.
+ //
+ person_t&amp; jane (ps.back ());
+ jane.middle_name ("Mary");
+
+ // Serialize the object model to XML.
+ //
+ xml_schema::namespace_infomap map;
+ map[""].name = "";
+ map[""].schema = "people.xsd";
+
+ people (cout, ppl, map);
+}
+ </pre>
+
+ <p>The only new part in the above application is the calls
+ to the <code>people_t</code> and <code>person_t</code>
+ constructors. As a general rule, for each C++ class
+ XSD generates a constructor with initializers
+ for each element and attribute belonging to the <em>one</em>
+ cardinality class. For our vocabulary, the following
+ constructors are generated:</p>
+
+ <pre class="c++">
+class person_t
+{
+ person_t (const first_name_type&amp;,
+ const last_name_type&amp;,
+ const gender_type&amp;,
+ const age_type&amp;,
+ const id_type&amp;);
+};
+
+class people_t
+{
+ people_t ();
+};
+ </pre>
+
+ <p>Note also that we set the <code>middle-name</code> element
+ on the Jane Doe record by obtaining a reference to that record
+ in the object model and setting the <code>middle-name</code>
+ value on it. This is a general rule that should be followed
+ in order to obtain the best performance: if possible,
+ direct modifications to the object model should be preferred
+ to modifications on temporaries with subsequent copying. The
+ following code fragment shows a semantically equivalent but
+ slightly slower version:</p>
+
+ <pre class="c++">
+// Add the Jane Doe record.
+//
+person_t jane ("Jane", // first-name
+ "Doe", // last-name
+ gender_t::female, // gender
+ 28, // age
+ 2); // id
+
+jane.middle_name ("Mary");
+
+ps.push_back (jane);
+ </pre>
+
+ <p>We can also go one step further to reduce copying and improve
+ the performance of our application by using the non-copying
+ <code>push_back()</code> function which assumes ownership
+ of the passed objects:</p>
+
+ <pre class="c++">
+// Add the John Doe record.
+//
+auto_ptr&lt;person_t> john_p (
+ new person_t ("John", // first-name
+ "Doe", // last-name
+ gender_t::male, // gender
+ 32, // age
+ 1));
+ps.push_back (john_p); // assumes ownership
+
+// Add the Jane Doe record.
+//
+auto_ptr&lt;person_t> jane_p (
+ new person_t ("Jane", // first-name
+ "Doe", // last-name
+ gender_t::female, // gender
+ 28, // age
+ 2)); // id
+ps.push_back (jane_p); // assumes ownership
+ </pre>
+
+ <p>For more information on the non-copying modifier functions refer to
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.8">Section
+ 2.8, "Mapping for Local Elements and Attributes"</a> in the C++/Tree Mapping
+ User Manual. The above application produces the following output:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0" ?>
+&lt;people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="people.xsd">
+
+ &lt;person id="1">
+ &lt;first-name>John&lt;/first-name>
+ &lt;last-name>Doe&lt;/last-name>
+ &lt;gender>male&lt;/gender>
+ &lt;age>32&lt;/age>
+ &lt;/person>
+
+ &lt;person id="2">
+ &lt;first-name>Jane&lt;/first-name>
+ &lt;middle-name>Mary&lt;/middle-name>
+ &lt;last-name>Doe&lt;/last-name>
+ &lt;gender>female&lt;/gender>
+ &lt;age>28&lt;/age>
+ &lt;/person>
+
+&lt;/people>
+ </pre>
+
+ <h2><a name="4.5">4.5 Mapping for the Built-in XML Schema Types</a></h2>
+
+ <p>Our person record vocabulary uses several built-in XML Schema
+ types: <code>string</code>, <code>short</code>, and
+ <code>unsignedInt</code>. Until now we haven't talked about
+ the mapping of built-in XML Schema types to C++ types and how
+ to work with them. This section provides an overview
+ of the built-in types. For more detailed information refer
+ to <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.5">Section
+ 2.5, "Mapping for Built-in Data Types"</a> in the C++/Tree Mapping
+ User Manual.</p>
+
+ <p>In XML Schema, built-in types are defined in the XML Schema namespace.
+ By default, the C++/Tree mapping maps this namespace to C++
+ namespace <code>xml_schema</code> (this mapping can be altered
+ with the <code>--namespace-map</code> option). The following table
+ summarizes the mapping of XML Schema built-in types to C++ types:</p>
+
+ <!-- border="1" is necessary for html2ps -->
+ <table id="builtin" border="1">
+ <tr>
+ <th>XML Schema type</th>
+ <th>Alias in the <code>xml_schema</code> namespace</th>
+ <th>C++ type</th>
+ </tr>
+
+ <tr>
+ <th colspan="3">fixed-length integral types</th>
+ </tr>
+ <!-- 8-bit -->
+ <tr>
+ <td><code>byte</code></td>
+ <td><code>byte</code></td>
+ <td><code>signed&nbsp;char</code></td>
+ </tr>
+ <tr>
+ <td><code>unsignedByte</code></td>
+ <td><code>unsigned_byte</code></td>
+ <td><code>unsigned&nbsp;char</code></td>
+ </tr>
+
+ <!-- 16-bit -->
+ <tr>
+ <td><code>short</code></td>
+ <td><code>short_</code></td>
+ <td><code>short</code></td>
+ </tr>
+ <tr>
+ <td><code>unsignedShort</code></td>
+ <td><code>unsigned_short</code></td>
+ <td><code>unsigned&nbsp;short</code></td>
+ </tr>
+
+ <!-- 32-bit -->
+ <tr>
+ <td><code>int</code></td>
+ <td><code>int_</code></td>
+ <td><code>int</code></td>
+ </tr>
+ <tr>
+ <td><code>unsignedInt</code></td>
+ <td><code>unsigned_int</code></td>
+ <td><code>unsigned&nbsp;int</code></td>
+ </tr>
+
+ <!-- 64-bit -->
+ <tr>
+ <td><code>long</code></td>
+ <td><code>long_</code></td>
+ <td><code>long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>unsignedLong</code></td>
+ <td><code>unsigned_long</code></td>
+ <td><code>unsigned&nbsp;long&nbsp;long</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">arbitrary-length integral types</th>
+ </tr>
+ <tr>
+ <td><code>integer</code></td>
+ <td><code>integer</code></td>
+ <td><code>long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>nonPositiveInteger</code></td>
+ <td><code>non_positive_integer</code></td>
+ <td><code>long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>nonNegativeInteger</code></td>
+ <td><code>non_negative_integer</code></td>
+ <td><code>unsigned long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>positiveInteger</code></td>
+ <td><code>positive_integer</code></td>
+ <td><code>unsigned long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>negativeInteger</code></td>
+ <td><code>negative_integer</code></td>
+ <td><code>long&nbsp;long</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">boolean types</th>
+ </tr>
+ <tr>
+ <td><code>boolean</code></td>
+ <td><code>boolean</code></td>
+ <td><code>bool</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">fixed-precision floating-point types</th>
+ </tr>
+ <tr>
+ <td><code>float</code></td>
+ <td><code>float_</code></td>
+ <td><code>float</code></td>
+ </tr>
+ <tr>
+ <td><code>double</code></td>
+ <td><code>double_</code></td>
+ <td><code>double</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">arbitrary-precision floating-point types</th>
+ </tr>
+ <tr>
+ <td><code>decimal</code></td>
+ <td><code>decimal</code></td>
+ <td><code>double</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">string types</th>
+ </tr>
+ <tr>
+ <td><code>string</code></td>
+ <td><code>string</code></td>
+ <td>type derived from <code>std::basic_string</code></td>
+ </tr>
+ <tr>
+ <td><code>normalizedString</code></td>
+ <td><code>normalized_string</code></td>
+ <td>type derived from <code>string</code></td>
+ </tr>
+ <tr>
+ <td><code>token</code></td>
+ <td><code>token</code></td>
+ <td>type&nbsp;derived&nbsp;from&nbsp;<code>normalized_string</code></td>
+ </tr>
+ <tr>
+ <td><code>Name</code></td>
+ <td><code>name</code></td>
+ <td>type derived from <code>token</code></td>
+ </tr>
+ <tr>
+ <td><code>NMTOKEN</code></td>
+ <td><code>nmtoken</code></td>
+ <td>type derived from <code>token</code></td>
+ </tr>
+ <tr>
+ <td><code>NMTOKENS</code></td>
+ <td><code>nmtokens</code></td>
+ <td>type derived from <code>sequence&lt;nmtoken></code></td>
+ </tr>
+ <tr>
+ <td><code>NCName</code></td>
+ <td><code>ncname</code></td>
+ <td>type derived from <code>name</code></td>
+ </tr>
+ <tr>
+ <td><code>language</code></td>
+ <td><code>language</code></td>
+ <td>type derived from <code>token</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">qualified name</th>
+ </tr>
+ <tr>
+ <td><code>QName</code></td>
+ <td><code>qname</code></td>
+ <td><code>xml_schema::qname</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">ID/IDREF types</th>
+ </tr>
+ <tr>
+ <td><code>ID</code></td>
+ <td><code>id</code></td>
+ <td>type derived from <code>ncname</code></td>
+ </tr>
+ <tr>
+ <td><code>IDREF</code></td>
+ <td><code>idref</code></td>
+ <td>type derived from <code>ncname</code></td>
+ </tr>
+ <tr>
+ <td><code>IDREFS</code></td>
+ <td><code>idrefs</code></td>
+ <td>type derived from <code>sequence&lt;idref></code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">URI types</th>
+ </tr>
+ <tr>
+ <td><code>anyURI</code></td>
+ <td><code>uri</code></td>
+ <td>type derived from <code>std::basic_string</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">binary types</th>
+ </tr>
+ <tr>
+ <td><code>base64Binary</code></td>
+ <td><code>base64_binary</code></td>
+ <td><code>xml_schema::base64_binary</code></td>
+ </tr>
+ <tr>
+ <td><code>hexBinary</code></td>
+ <td><code>hex_binary</code></td>
+ <td><code>xml_schema::hex_binary</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">date/time types</th>
+ </tr>
+ <tr>
+ <td><code>date</code></td>
+ <td><code>date</code></td>
+ <td><code>xml_schema::date</code></td>
+ </tr>
+ <tr>
+ <td><code>dateTime</code></td>
+ <td><code>date_time</code></td>
+ <td><code>xml_schema::date_time</code></td>
+ </tr>
+ <tr>
+ <td><code>duration</code></td>
+ <td><code>duration</code></td>
+ <td><code>xml_schema::duration</code></td>
+ </tr>
+ <tr>
+ <td><code>gDay</code></td>
+ <td><code>gday</code></td>
+ <td><code>xml_schema::gday</code></td>
+ </tr>
+ <tr>
+ <td><code>gMonth</code></td>
+ <td><code>gmonth</code></td>
+ <td><code>xml_schema::gmonth</code></td>
+ </tr>
+ <tr>
+ <td><code>gMonthDay</code></td>
+ <td><code>gmonth_day</code></td>
+ <td><code>xml_schema::gmonth_day</code></td>
+ </tr>
+ <tr>
+ <td><code>gYear</code></td>
+ <td><code>gyear</code></td>
+ <td><code>xml_schema::gyear</code></td>
+ </tr>
+ <tr>
+ <td><code>gYearMonth</code></td>
+ <td><code>gyear_month</code></td>
+ <td><code>xml_schema::gyear_month</code></td>
+ </tr>
+ <tr>
+ <td><code>time</code></td>
+ <td><code>time</code></td>
+ <td><code>xml_schema::time</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">entity types</th>
+ </tr>
+ <tr>
+ <td><code>ENTITY</code></td>
+ <td><code>entity</code></td>
+ <td>type derived from <code>name</code></td>
+ </tr>
+ <tr>
+ <td><code>ENTITIES</code></td>
+ <td><code>entities</code></td>
+ <td>type derived from <code>sequence&lt;entity></code></td>
+ </tr>
+ </table>
+
+ <p>As you can see from the table above a number of built-in
+ XML Schema types are mapped to fundamental C++ types such
+ as <code>int</code> or <code>bool</code>. All string-based
+ XML Schema types are mapped to C++ types that are derived
+ from either <code>std::string</code> or
+ <code>std::wstring</code>, depending on the character
+ type selected. For access and modification purposes these
+ types can be treated as <code>std::string</code>. A number
+ of built-in types, such as <code>qname</code>, the binary
+ types, and the date/time types do not have suitable
+ fundamental or standard C++ types to map to. As a result,
+ these types are implemented from scratch in the XSD runtime.
+ For more information on their interfaces refer to
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.5">Section
+ 2.5, "Mapping for Built-in Data Types"</a> in the C++/Tree Mapping
+ User Manual.</p>
+
+
+ <!-- Chapater 5 -->
+
+
+ <h1><a name="5">5 Parsing</a></h1>
+
+ <p>We have already seen how to parse XML to an object model in this guide
+ before. In this chapter we will discuss the parsing topic in more
+ detail.</p>
+
+ <p>By default, the C++/Tree mapping provides a total of 14 overloaded
+ parsing functions. They differ in the input methods used to
+ read XML as well as the error reporting mechanisms. It is also possible
+ to generate types for root elements instead of parsing and serialization
+ functions. This may be useful if your XML vocabulary has multiple
+ root elements. For more information on element types refer to
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.9">Section
+ 2.9, "Mapping for Global Elements"</a> in the C++/Tree Mapping User
+ Manual.</p>
+
+
+ <p>In this section we will discuss the most commonly used versions of
+ the parsing functions. For a comprehensive description of parsing
+ refer to <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#3">Chapter
+ 3, "Parsing"</a> in the C++/Tree Mapping User Manual. For the <code>people</code>
+ global element from our person record vocabulary, we will concentrate
+ on the following three parsing functions:</p>
+
+ <pre class="c++">
+std::auto_ptr&lt;people_t>
+people (const std::string&amp; uri,
+ xml_schema::flags f = 0,
+ const xml_schema::properties&amp; p = xml_schema::properties ());
+
+std::auto_ptr&lt;people_t>
+people (std::istream&amp; is,
+ xml_schema::flags f = 0,
+ const xml_schema::properties&amp; p = xml_schema::properties ());
+
+std::auto_ptr&lt;people_t>
+people (std::istream&amp; is,
+ const std::string&amp; resource_id,
+ xml_schema::flags f = 0,
+ const xml_schema::properties&amp; p = ::xml_schema::properties ());
+ </pre>
+
+ <p>The first function parses a local file or a URI. We have already
+ used this parsing function in the previous chapters. The second
+ and third functions read XML from a standard input stream. The
+ last function also requires a resource id. This id is used to
+ identify the XML document being parser in diagnostics messages
+ as well as to resolve relative paths to other documents (for example,
+ schemas) that might be referenced from the XML document.</p>
+
+ <p>The last two arguments to all three parsing functions are parsing
+ flags and properties. The flags argument provides a number of ways
+ to fine-tune the parsing process. The properties argument allows
+ to pass additional information to the parsing functions. We will
+ use these two arguments in <a href="#5.1">Section 5.1, "XML Schema
+ Validation and Searching"</a> below. The following example shows
+ how we can use the above parsing functions:</p>
+
+ <pre class="c++">
+using std::auto_ptr;
+
+// Parse a local file or URI.
+//
+auto_ptr&lt;people_t> p1 (people ("people.xml"));
+auto_ptr&lt;people_t> p2 (people ("http://example.com/people.xml"));
+
+// Parse a local file via ifstream.
+//
+std::ifstream ifs ("people.xml");
+auto_ptr&lt;people_t> p3 (people (ifs, "people.xml"));
+
+// Parse an XML string.
+//
+std::string str ("..."); // XML in a string.
+std::istringstream iss (str);
+auto_ptr&lt;people_t> p4 (people (iss));
+ </pre>
+
+
+ <h2><a name="5.1">5.1 XML Schema Validation and Searching</a></h2>
+
+ <p>The C++/Tree mapping relies on the underlying Xerces-C++ XML
+ parser for full XML document validation. The XML Schema
+ validation is enabled by default and can be disabled by
+ passing the <code>xml_schema::flags::dont_validate</code>
+ flag to the parsing functions, for example:</p>
+
+ <pre class="c++">
+auto_ptr&lt;people_t> p (
+ people ("people.xml", xml_schema::flags::dont_validate));
+ </pre>
+
+ <p>Even when XML Schema validation is disabled, the generated
+ code still performs a number of checks to prevent
+ construction of an inconsistent object model (for example, an
+ object model with missing required attributes or elements).</p>
+
+ <p>When XML Schema validation is enabled, the XML parser needs
+ to locate a schema to validate against. There are several
+ methods to provide the schema location information to the
+ parser. The easiest and most commonly used method is to
+ specify schema locations in the XML document itself
+ with the <code>schemaLocation</code> or
+ <code>noNamespaceSchemaLocation</code> attributes, for example:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0" ?>
+&lt;people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="people.xsd"
+ xsi:schemaLocation="http://www.w3.org/XML/1998/namespace xml.xsd">
+ </pre>
+
+ <p>As you might have noticed, we used this method in all the sample XML
+ documents presented in this guide up until now. Note that the
+ schema locations specified with these two attributes are relative
+ to the document's path unless they are absolute URIs (that is
+ start with <code>http://</code>, <code>file://</code>, etc.).
+ In particular, if you specify just file names as your schema
+ locations, as we did above, then the schemas should reside in
+ the same directory as the XML document itself.</p>
+
+ <p>Another method of providing the schema location information
+ is via the <code>xml_schema::properties</code> argument, as
+ shown in the following example:</p>
+
+ <pre class="c++">
+xml_schema::properties props;
+props.no_namespace_schema_location ("people.xsd");
+props.schema_location ("http://www.w3.org/XML/1998/namespace", "xml.xsd");
+
+auto_ptr&lt;people_t> p (people ("people.xml", 0, props));
+ </pre>
+
+ <p>The schema locations provided with this method overrides
+ those specified in the XML document. As with the previous
+ method, the schema locations specified this way are
+ relative to the document's path unless they are absolute URIs.
+ In particular, if you want to use local schemas that are
+ not related to the document being parsed, then you will
+ need to use the <code>file://</code> URI. The following
+ example shows how to use schemas that reside in the current
+ working directory:</p>
+
+ <pre class="c++">
+#include &lt;unistd.h> // getcwd
+#include &lt;limits.h> // PATH_MAX
+
+char cwd[PATH_MAX];
+if (getcwd (cwd, PATH_MAX) == 0)
+{
+ // Buffer too small?
+}
+
+xml_schema::properties props;
+
+props.no_namespace_schema_location (
+ "file:///" + std::string (cwd) + "people.xsd");
+
+props.schema_location (
+ "http://www.w3.org/XML/1998/namespace",
+ "file:///" + std::string (cwd) + "xml.xsd");
+
+auto_ptr&lt;people_t> p (people ("people.xml", 0, props));
+ </pre>
+
+ <p>A third method is the most useful if you are planning to parse
+ several XML documents of the same vocabulary. In that case
+ it may be beneficial to pre-parse and cache the schema in
+ the XML parser which can then be used to parse all documents
+ without re-parsing the schemas. For more information on
+ this method refer to the <code>caching</code> example in the
+ <code>examples/cxx/tree/</code> directory of the XSD
+ distribution.</p>
+
+ <p>When the XML parser cannot locate a schema for the
+ XML document, the validation fails and XML document
+ elements and attributes for which schema definitions could
+ not be located are reported in the diagnostics. For
+ example, if we remove the <code>noNamespaceSchemaLocation</code>
+ attribute in <code>people.xml</code> from the previous chapter,
+ then we will get the following diagnostics if we try to parse
+ this file with validation enabled:</p>
+
+ <pre class="terminal">
+people.xml:3:18 error: Unknown element 'person'
+people.xml:3:18 error: Attribute 'id' is not declared for element 'person'
+people.xml:4:17 error: Unknown element 'first-name'
+people.xml:5:16 error: Unknown element 'last-name'
+people.xml:6:13 error: Unknown element 'gender'
+people.xml:7:10 error: Unknown element 'age'
+people.xml:9:18 error: Unknown element 'person'
+people.xml:9:18 error: Attribute 'id' is not declared for element 'person'
+people.xml:10:17 error: Unknown element 'first-name'
+people.xml:11:18 error: Unknown element 'middle-name'
+people.xml:12:16 error: Unknown element 'last-name'
+people.xml:13:13 error: Unknown element 'gender'
+people.xml:14:10 error: Unknown element 'age'
+ </pre>
+
+ <h2><a name="5.2">5.2 Error Handling</a></h2>
+
+ <p>The parsing functions offer a number of ways to handle error conditions
+ with the C++ exceptions being the most commonly used mechanism. All
+ C++/Tree exceptions derive from common base <code>xml_schema::exception</code>
+ which in turn derives from <code>std::exception</code>. The easiest
+ way to uniformly handle all possible C++/Tree exceptions and print
+ detailed information about the error is to catch and print
+ <code>xml_schema::exception</code>, as shown in the following
+ example:</p>
+
+ <pre class="c++">
+try
+{
+ auto_ptr&lt;people_t> p (people ("people.xml"));
+}
+catch (const xml_schema::exception&amp; e)
+{
+ cerr &lt;&lt; e &lt;&lt; endl;
+}
+ </pre>
+
+ <p>Each individual C++/Tree exception also allows you to obtain
+ error details programmatically. For example, the
+ <code>xml_schema::parsing</code> exception is thrown when
+ the XML parsing and validation in the underlying XML parser
+ fails. It encapsulates various diagnostics information
+ such as the file name, line and column numbers, as well as the
+ error or warning message for each entry. For more information
+ about this and other exceptions that can be thrown during
+ parsing, refer to
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#3.3">Section
+ 3.3, "Error Handling"</a> in the C++/Tree Mapping
+ User Manual.</p>
+
+ <p>Note that if you are parsing <code>std::istream</code> on which
+ exceptions are not enabled, then you will need to check the
+ stream state after the call to the parsing function in order
+ to detect any possible stream failures, for example:</p>
+
+ <pre class="c++">
+std::ifstream ifs ("people.xml");
+
+if (ifs.fail ())
+{
+ cerr &lt;&lt; "people.xml: unable to open" &lt;&lt; endl;
+ return 1;
+}
+
+auto_ptr&lt;people_t> p (people (ifs, "people.xml"));
+
+if (ifs.fail ())
+{
+ cerr &lt;&lt; "people.xml: read error" &lt;&lt; endl;
+ return 1;
+}
+ </pre>
+
+ <p>The above example can be rewritten to use exceptions as
+ shown below:</p>
+
+ <pre class="c++">
+try
+{
+ std::ifstream ifs;
+ ifs.exceptions (std::ifstream::badbit | std::ifstream::failbit);
+ ifs.open ("people.xml");
+
+ auto_ptr&lt;people_t> p (people (ifs, "people.xml"));
+}
+catch (const std::ifstream::failure&amp;)
+{
+ cerr &lt;&lt; "people.xml: unable to open or read error" &lt;&lt; endl;
+ return 1;
+}
+ </pre>
+
+
+ <!-- Chapater 6 -->
+
+
+ <h1><a name="6">6 Serialization</a></h1>
+
+ <p>We have already seen how to serialize an object model back to XML
+ in this guide before. In this chapter we will discuss the
+ serialization topic in more detail.</p>
+
+ <p>By default, the C++/Tree mapping provides a total of 8 overloaded
+ serialization functions. They differ in the output methods used to write
+ XML as well as the error reporting mechanisms. It is also possible to
+ generate types for root elements instead of parsing and serialization
+ functions. This may be useful if your XML vocabulary has multiple
+ root elements. For more information on element types refer to
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#2.9">Section
+ 2.9, "Mapping for Global Elements"</a> in the C++/Tree Mapping User
+ Manual.</p>
+
+
+ <p>In this section we will discuss the most commonly
+ used version of serialization functions. For a comprehensive description
+ of serialization refer to
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#4">Chapter
+ 4, "Serialization"</a> in the C++/Tree Mapping User Manual. For the
+ <code>people</code> global element from our person record vocabulary,
+ we will concentrate on the following serialization function:</p>
+
+ <pre class="c++">
+void
+people (std::ostream&amp; os,
+ const people_t&amp; x,
+ const xml_schema::namespace_infomap&amp; map =
+ xml_schema::namespace_infomap (),
+ const std::string&amp; encoding = "UTF-8",
+ xml_schema::flags f = 0);
+ </pre>
+
+ <p>This function serializes the object model passed as the second
+ argument to the standard output stream passed as the first
+ argument. The third argument is a namespace information map
+ which we will discuss in more detail in the next section.
+ The fourth argument is a character encoding that the resulting
+ XML document should be in. Possible valid values for this
+ argument are "US-ASCII", "ISO8859-1", "UTF-8", "UTF-16BE",
+ "UTF-16LE", "UCS-4BE", and "UCS-4LE". Finally, the flags
+ argument allows fine-tuning of the serialization process.
+ The following example shows how we can use the above serialization
+ function:</p>
+
+ <pre class="c++">
+people_t&amp; p = ...
+
+xml_schema::namespace_infomap map;
+map[""].schema = "people.xsd";
+
+// Serialize to stdout.
+//
+people (std::cout, p, map);
+
+// Serialize to a file.
+//
+std::ofstream ofs ("people.xml");
+people (ofs, p, map);
+
+// Serialize to a string.
+//
+std::ostringstream oss;
+people (oss, p, map);
+std::string xml (oss.str ());
+ </pre>
+
+
+ <h2><a name="6.1">6.1 Namespace and Schema Information</a></h2>
+
+ <p>While XML serialization can be done just from the object
+ model alone, it is often desirable to assign meaningful
+ prefixes to XML namespaces used in the vocabulary as
+ well as to provide the schema location information.
+ This is accomplished by passing the namespace information
+ map to the serialization function. The key in this map is
+ a namespace prefix that should be assigned to an XML namespace
+ specified in the <code>name</code> variable of the
+ map value. You can also assign an optional schema location for
+ this namespace in the <code>schema</code> variable. Based
+ on each key-value entry in this map, the serialization
+ function adds two attributes to the resulting XML document:
+ the namespace-prefix mapping attribute and schema location
+ attribute. The empty prefix indicates that the namespace
+ should be mapped without a prefix. For example, the following
+ map:</p>
+
+ <pre class="c++">
+xml_schema::namespace_infomap map;
+
+map[""].name = "http://www.example.com/example";
+map[""].schema = "example.xsd";
+
+map["x"].name = "http://www.w3.org/XML/1998/namespace";
+map["x"].schema = "xml.xsd";
+ </pre>
+
+ <p>Results in the following XML document:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0" ?>
+&lt;example
+ xmlns="http://www.example.com/example"
+ xmlns:x="http://www.w3.org/XML/1998/namespace"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.example.com/example example.xsd
+ http://www.w3.org/XML/1998/namespace xml.xsd">
+ </pre>
+
+ <p>The empty namespace indicates that the vocabulary has no target
+ namespace. For example, the following map results in only the
+ <code>noNamespaceSchemaLocation</code> attribute being added:</p>
+
+ <pre class="c++">
+xml_schema::namespace_infomap map;
+
+map[""].name = "";
+map[""].schema = "example.xsd";
+ </pre>
+
+ <h2><a name="6.2">6.2 Error Handling</a></h2>
+
+ <p>Similar to the parsing functions, the serialization functions offer a
+ number of ways to handle error conditions with the C++ exceptions being
+ the most commonly used mechanisms. As with parsing, the easiest way to
+ uniformly handle all possible serialization exceptions and print
+ detailed information about the error is to catch and print
+ <code>xml_schema::exception</code>:</p>
+
+ <pre class="c++">
+try
+{
+ people_t&amp; p = ...
+
+ xml_schema::namespace_infomap map;
+ map[""].schema = "people.xsd";
+
+ people (std::cout, p, map));
+}
+catch (const xml_schema::exception&amp; e)
+{
+ cerr &lt;&lt; e &lt;&lt; endl;
+}
+ </pre>
+
+ <p>The most commonly encountered serialization exception is
+ <code>xml_schema::serialization</code>. It is thrown
+ when the XML serialization in the underlying XML writer
+ fails. It encapsulates various diagnostics information
+ such as the file name, line and column numbers, as well as the
+ error or warning message for each entry. For more information
+ about this and other exceptions that can be thrown during
+ serialization, refer to
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/#4.4">Section
+ 4.4, "Error Handling"</a> in the C++/Tree Mapping
+ User Manual.</p>
+
+ <p>Note that if you are serializing to <code>std::ostream</code> on
+ which exceptions are not enabled, then you will need to check the
+ stream state after the call to the serialization function in order
+ to detect any possible stream failures, for example:</p>
+
+ <pre class="c++">
+std::ofstream ofs ("people.xml");
+
+if (ofs.fail ())
+{
+ cerr &lt;&lt; "people.xml: unable to open" &lt;&lt; endl;
+ return 1;
+}
+
+people (ofs, p, map));
+
+if (ofs.fail ())
+{
+ cerr &lt;&lt; "people.xml: write error" &lt;&lt; endl;
+ return 1;
+}
+ </pre>
+
+ <p>The above example can be rewritten to use exceptions as
+ shown below:</p>
+
+ <pre class="c++">
+try
+{
+ std::ofstream ofs;
+ ofs.exceptions (std::ofstream::badbit | std::ofstream::failbit);
+ ofs.open ("people.xml");
+
+ people (ofs, p, map));
+}
+catch (const std::ofstream::failure&amp;)
+{
+ cerr &lt;&lt; "people.xml: unable to open or write error" &lt;&lt; endl;
+ return 1;
+}
+ </pre>
+
+ </div>
+</div>
+
+</body>
+</html>
diff --git a/documentation/cxx/tree/guide/makefile b/documentation/cxx/tree/guide/makefile
new file mode 100644
index 0000000..188b419
--- /dev/null
+++ b/documentation/cxx/tree/guide/makefile
@@ -0,0 +1,12 @@
+.PHONY: all
+all: cxx-tree-guide.ps cxx-tree-guide.pdf
+
+cxx-tree-guide.pdf: cxx-tree-guide.ps
+ ps2pdf14 $<
+
+cxx-tree-guide.ps: index.xhtml guide.html2ps
+ html2ps -f guide.html2ps -o $@ $<
+
+.PHONY: clean
+clean:
+ rm -f cxx-tree-guide.ps cxx-tree-guide.pdf
diff --git a/documentation/cxx/tree/manual/index.xhtml b/documentation/cxx/tree/manual/index.xhtml
new file mode 100644
index 0000000..d468fe3
--- /dev/null
+++ b/documentation/cxx/tree/manual/index.xhtml
@@ -0,0 +1,5868 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+
+<head>
+ <title>C++/Tree Mapping User Manual</title>
+
+ <meta name="copyright" content="&copy; 2005-2009 Code Synthesis Tools CC"/>
+ <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,tree,serialization,guide,manual,examples"/>
+ <meta name="description" content="C++/Tree Mapping User Manual"/>
+ <meta name="revision" content="2.3.0"/>
+
+ <link rel="stylesheet" type="text/css" href="../../../default.css" />
+ <!--[if lt IE 7]><link rel="stylesheet" type="text/css" href="/default-ie.css"/><![endif]-->
+
+<style type="text/css">
+ pre {
+ padding : 0 0 0 0em;
+ margin : 0em 0em 0em 0;
+
+ font-size : 102%
+ }
+
+ body {
+ min-width: 48em;
+ }
+
+ h1 {
+ font-weight: bold;
+ font-size: 200%;
+ }
+
+ h2 {
+ font-weight : bold;
+ font-size : 150%;
+
+ padding-top : 0.8em;
+ }
+
+ h3 {
+ font-size : 130%;
+ padding-top : 0.8em;
+ }
+
+ /* Adjust indentation for three levels. */
+ #container {
+ max-width: 48em;
+ }
+
+ #content {
+ padding: 0 0.1em 0 4em;
+ /*background-color: red;*/
+ }
+
+ #content h1 {
+ margin-left: -2.06em;
+ }
+
+ #content h2 {
+ margin-left: -1.33em;
+ }
+
+ /* Title page */
+
+ #titlepage {
+ padding: 2em 0 1em 0;
+ border-bottom: 1px solid black;
+ }
+
+ #titlepage #title {
+ font-weight: bold;
+ font-size: 200%;
+ text-align: center;
+ padding: 1em 0 2em 0;
+ }
+
+ /* Lists */
+ ul.list li {
+ padding-top : 0.3em;
+ padding-bottom : 0.3em;
+ }
+
+
+ /* Built-in table */
+ #builtin {
+ margin: 2em 0 2em 0;
+
+ border-collapse : collapse;
+ border : 1px solid;
+ border-color : #000000;
+
+ font-size : 11px;
+ line-height : 14px;
+ }
+
+ #builtin th, #builtin td {
+ border: 1px solid;
+ padding : 0.9em 0.9em 0.7em 0.9em;
+ }
+
+ #builtin th {
+ background : #cde8f6;
+ }
+
+ #builtin td {
+ text-align: left;
+ }
+
+
+ /* default-fixed */
+ #default-fixed {
+ margin: 2em 0 2em 0;
+
+ border-collapse : collapse;
+ border : 1px solid;
+ border-color : #000000;
+
+ font-size : 11px;
+ line-height : 14px;
+ }
+
+ #default-fixed th, #default-fixed td {
+ border: 1px solid;
+ padding : 0.9em 0.9em 0.7em 0.9em;
+ }
+
+ #default-fixed th {
+ background : #cde8f6;
+ }
+
+ #default-fixed td {
+ text-align: center;
+ }
+
+
+ /* */
+ dl dt {
+ padding : 0.8em 0 0 0;
+ }
+
+
+ /* TOC */
+ table.toc {
+ border-style : none;
+ border-collapse : separate;
+ border-spacing : 0;
+
+ margin : 0.2em 0 0.2em 0;
+ padding : 0 0 0 0;
+ }
+
+ table.toc tr {
+ padding : 0 0 0 0;
+ margin : 0 0 0 0;
+ }
+
+ table.toc * td, table.toc * th {
+ border-style : none;
+ margin : 0 0 0 0;
+ vertical-align : top;
+ }
+
+ table.toc * th {
+ font-weight : normal;
+ padding : 0em 0.1em 0em 0;
+ text-align : left;
+ white-space : nowrap;
+ }
+
+ table.toc * table.toc th {
+ padding-left : 1em;
+ }
+
+ table.toc * td {
+ padding : 0em 0 0em 0.7em;
+ text-align : left;
+ }
+</style>
+
+
+</head>
+
+<body>
+<div id="container">
+ <div id="content">
+
+ <div class="noprint">
+
+ <div id="titlepage">
+ <div id="title">C++/Tree Mapping User Manual</div>
+
+ <p>Copyright &copy; 2005-2009 CODE SYNTHESIS TOOLS CC</p>
+
+ <p>Permission is granted to copy, distribute and/or modify this
+ document under the terms of the
+ <a href="http://www.codesynthesis.com/licenses/fdl-1.2.txt">GNU Free
+ Documentation License, version 1.2</a>; with no Invariant Sections,
+ no Front-Cover Texts and no Back-Cover Texts.
+ </p>
+
+ <p>This document is available in the following formats:
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/index.xhtml">XHTML</a>,
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.pdf">PDF</a>, and
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.ps">PostScript</a>.</p>
+ </div>
+
+ <h1>Table of Contents</h1>
+
+ <table class="toc">
+ <tr>
+ <th></th><td><a href="#0">Preface</a>
+ <table class="toc">
+ <tr><th></th><td><a href="#0.1">About This Document</a></td></tr>
+ <tr><th></th><td><a href="#0.2">More Information</a></td></tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>1</th><td><a href="#1">Introduction</a></td>
+ </tr>
+
+ <tr>
+ <th>2</th><td><a href="#2">C++/Tree Mapping</a>
+ <table class="toc">
+ <tr>
+ <th>2.1</th><td><a href="#2.1">Preliminary Information</a>
+ <table class="toc">
+ <tr><th>2.1.1</th><td><a href="#2.1.1">Identifiers</a></td></tr>
+ <tr><th>2.1.2</th><td><a href="#2.1.2">Character Type</a></td></tr>
+ <tr><th>2.1.3</th><td><a href="#2.1.3">XML Schema Namespace</a></td></tr>
+ <tr><th>2.1.4</th><td><a href="#2.1.4">Anonymous Types</a></td></tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th>2.2</th><td><a href="#2.2">Error Handling</a>
+ <table class="toc">
+ <tr><th>2.2.1</th><td><a href="#2.2.1"><code>xml_schema::duplicate_id</code></a></td></tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th>2.3</th><td><a href="#2.3">Mapping for <code>import</code> and <code>include</code></a>
+ <table class="toc">
+ <tr><th>2.3.1</th><td><a href="#2.3.1">Import</a></td></tr>
+ <tr><th>2.3.2</th><td><a href="#2.3.2">Inclusion with Target Namespace</a></td></tr>
+ <tr><th>2.3.3</th><td><a href="#2.3.3">Inclusion without Target Namespace</a></td></tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th>2.4</th><td><a href="#2.4">Mapping for Namespaces</a></td>
+ </tr>
+ <tr>
+ <th>2.5</th><td><a href="#2.5">Mapping for Built-in Data Types</a>
+ <table class="toc">
+ <tr><th>2.5.1</th><td><a href="#2.5.1">Inheritance from Built-in Data Types</a></td></tr>
+ <tr><th>2.5.2</th><td><a href="#2.5.2">Mapping for <code>anyType</code></a></td></tr>
+ <tr><th>2.5.3</th><td><a href="#2.5.3">Mapping for <code>anySimpleType</code></a></td></tr>
+ <tr><th>2.5.4</th><td><a href="#2.5.4">Mapping for <code>QName</code></a></td></tr>
+ <tr><th>2.5.5</th><td><a href="#2.5.5">Mapping for <code>IDREF</code></a></td></tr>
+ <tr><th>2.5.6</th><td><a href="#2.5.6">Mapping for <code>base64Binary</code> and <code>hexBinary</code></a></td></tr>
+ <tr><th>2.5.7</th><td><a href="#2.5.7">Time Zone Representation</a></td></tr>
+ <tr><th>2.5.8</th><td><a href="#2.5.8">Mapping for <code>date</code></a></td></tr>
+ <tr><th>2.5.9</th><td><a href="#2.5.9">Mapping for <code>dateTime</code></a></td></tr>
+ <tr><th>2.5.10</th><td><a href="#2.5.10">Mapping for <code>duration</code></a></td></tr>
+ <tr><th>2.5.11</th><td><a href="#2.5.11">Mapping for <code>gDay</code></a></td></tr>
+ <tr><th>2.5.12</th><td><a href="#2.5.12">Mapping for <code>gMonth</code></a></td></tr>
+ <tr><th>2.5.13</th><td><a href="#2.5.13">Mapping for <code>gMonthDay</code></a></td></tr>
+ <tr><th>2.5.14</th><td><a href="#2.5.14">Mapping for <code>gYear</code></a></td></tr>
+ <tr><th>2.5.15</th><td><a href="#2.5.15">Mapping for <code>gYearMonth</code></a></td></tr>
+ <tr><th>2.5.16</th><td><a href="#2.5.16">Mapping for <code>time</code></a></td></tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th>2.6</th><td><a href="#2.6">Mapping for Simple Types</a>
+ <table class="toc">
+ <tr><th>2.6.1</th><td><a href="#2.6.1">Mapping for Derivation by Restriction</a></td></tr>
+ <tr><th>2.6.2</th><td><a href="#2.6.2">Mapping for Enumerations</a></td></tr>
+ <tr><th>2.6.3</th><td><a href="#2.6.3">Mapping for Derivation by List</a></td></tr>
+ <tr><th>2.6.4</th><td><a href="#2.6.4">Mapping for Derivation by Union</a></td></tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th>2.7</th><td><a href="#2.7">Mapping for Complex Types</a>
+ <table class="toc">
+ <tr><th>2.7.1</th><td><a href="#2.7.1">Mapping for Derivation by Extension</a></td></tr>
+ <tr><th>2.7.2</th><td><a href="#2.7.2">Mapping for Derivation by Restriction</a></td></tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th>2.8</th><td><a href="#2.8">Mapping for Local Elements and Attributes</a>
+ <table class="toc">
+ <tr><th>2.8.1</th><td><a href="#2.8.1">Mapping for Members with the One Cardinality Class</a></td></tr>
+ <tr><th>2.8.2</th><td><a href="#2.8.2">Mapping for Members with the Optional Cardinality Class</a></td></tr>
+ <tr><th>2.8.3</th><td><a href="#2.8.3">Mapping for Members with the Sequence Cardinality Class</a></td></tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th>2.9</th><td><a href="#2.9">Mapping for Global Elements</a>
+ <table class="toc">
+ <tr><th>2.9.1</th><td><a href="#2.9.1">Element Types</a></td></tr>
+ <tr><th>2.9.2</th><td><a href="#2.9.2">Element Map</a></td></tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th>2.10</th><td><a href="#2.10">Mapping for Global Attributes</a></td>
+ </tr>
+ <tr>
+ <th>2.11</th><td><a href="#2.11">Mapping for <code>xsi:type</code> and Substitution Groups</a></td>
+ </tr>
+ <tr>
+ <th>2.12</th><td><a href="#2.12">Mapping for <code>any</code> and <code>anyAttribute</code></a>
+ <table class="toc">
+ <tr><th>2.12.1</th><td><a href="#2.12.1">Mapping for <code>any</code> with the One Cardinality Class</a></td></tr>
+ <tr><th>2.12.2</th><td><a href="#2.12.2">Mapping for <code>any</code> with the Optional Cardinality Class</a></td></tr>
+ <tr><th>2.12.3</th><td><a href="#2.12.3">Mapping for <code>any</code> with the Sequence Cardinality Class</a></td></tr>
+ <tr><th>2.12.4</th><td><a href="#2.12.4">Mapping for <code>anyAttribute</code></a></td></tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th>2.13</th><td><a href="#2.13">Mapping for Mixed Content Models</a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>3</th><td><a href="#3">Parsing</a>
+ <table class="toc">
+ <tr>
+ <th>3.1</th><td><a href="#3.1">Initializing the Xerces-C++ Runtime</a></td>
+ </tr>
+ <tr>
+ <th>3.2</th><td><a href="#3.2">Flags and Properties</a></td>
+ </tr>
+ <tr>
+ <th>3.3</th><td><a href="#3.3">Error Handling</a>
+ <table class="toc">
+ <tr><th>3.3.1</th><td><a href="#3.3.1"><code>xml_schema::parsing</code></a></td></tr>
+ <tr><th>3.3.2</th><td><a href="#3.3.2"><code>xml_schema::expected_element</code></a></td></tr>
+ <tr><th>3.3.3</th><td><a href="#3.3.3"><code>xml_schema::unexpected_element</code></a></td></tr>
+ <tr><th>3.3.4</th><td><a href="#3.3.4"><code>xml_schema::expected_attribute</code></a></td></tr>
+ <tr><th>3.3.5</th><td><a href="#3.3.5"><code>xml_schema::unexpected_enumerator</code></a></td></tr>
+ <tr><th>3.3.6</th><td><a href="#3.3.6"><code>xml_schema::expected_text_content</code></a></td></tr>
+ <tr><th>3.3.7</th><td><a href="#3.3.7"><code>xml_schema::no_type_info</code></a></td></tr>
+ <tr><th>3.3.8</th><td><a href="#3.3.8"><code>xml_schema::not_derived</code></a></td></tr>
+ <tr><th>3.3.9</th><td><a href="#3.3.9"><code>xml_schema::not_prefix_mapping</code></a></td></tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th>3.4</th><td><a href="#3.4">Reading from a Local File or URI</a></td>
+ </tr>
+ <tr>
+ <th>3.5</th><td><a href="#3.5">Reading from <code>std::istream</code></a></td>
+ </tr>
+ <tr>
+ <th>3.6</th><td><a href="#3.6">Reading from <code>xercesc::InputSource</code></a></td>
+ </tr>
+ <tr>
+ <th>3.7</th><td><a href="#3.7">Reading from DOM</a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>4</th><td><a href="#4">Serialization</a>
+ <table class="toc">
+ <tr>
+ <th>4.1</th><td><a href="#4.1">Initializing the Xerces-C++ Runtime</a></td>
+ </tr>
+ <tr>
+ <th>4.2</th><td><a href="#4.2">Namespace Infomap and Character Encoding</a></td>
+ </tr>
+ <tr>
+ <th>4.3</th><td><a href="#4.3">Flags</a></td>
+ </tr>
+ <tr>
+ <th>4.4</th><td><a href="#4.4">Error Handling</a>
+ <table class="toc">
+ <tr><th>4.4.1</th><td><a href="#4.4.1"><code>xml_schema::serialization</code></a></td></tr>
+ <tr><th>4.4.2</th><td><a href="#4.4.2"><code>xml_schema::unexpected_element</code></a></td></tr>
+ <tr><th>4.4.3</th><td><a href="#4.4.3"><code>xml_schema::no_type_info</code></a></td></tr>
+ </table>
+ </td>
+ </tr>
+ <tr>
+ <th>4.5</th><td><a href="#4.5">Serializing to <code>std::ostream</code></a></td>
+ </tr>
+ <tr>
+ <th>4.6</th><td><a href="#4.6">Serializing to <code>xercesc::XMLFormatTarget</code></a></td>
+ </tr>
+ <tr>
+ <th>4.7</th><td><a href="#4.7">Serializing to DOM</a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th>5</th><td><a href="#5">Additional Functionality</a>
+ <table class="toc">
+ <tr>
+ <th>5.1</th><td><a href="#5.1">DOM Association</a></td>
+ </tr>
+ <tr>
+ <th>5.2</th><td><a href="#5.2">Binary Serialization</a></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+
+ <tr>
+ <th></th><td><a href="#A">Appendix A &mdash; Default and Fixed Values</a></td>
+ </tr>
+
+ </table>
+ </div>
+
+ <h1><a name="0">Preface</a></h1>
+
+ <h2><a name="0.1">About This Document</a></h2>
+
+ <p>This document describes the mapping of W3C XML Schema
+ to the C++ programming language as implemented by
+ <a href="http://www.codesynthesis.com/products/xsd">CodeSynthesis
+ XSD</a> - an XML Schema to C++ data binding compiler. The mapping
+ represents information stored in XML instance documents as a
+ statically-typed, tree-like in-memory data structure and is
+ called C++/Tree.
+ </p>
+
+ <p>Revision 2.3.0<br/> <!-- Remember to change revision in other places -->
+ This revision of the manual describes the C++/Tree
+ mapping as implemented by CodeSynthesis XSD version 3.3.0.
+ </p>
+
+ <p>This document is available in the following formats:
+ <a href="http://codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/index.xhtml">XHTML</a>,
+ <a href="http://codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.pdf">PDF</a>, and
+ <a href="http://codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.ps">PostScript</a>.</p>
+
+ <h2><a name="0.2">More Information</a></h2>
+
+ <p>Beyond this manual, you may also find the following sources of
+ information useful:</p>
+
+ <ul class="list">
+ <li><a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/guide/">C++/Tree
+ Mapping Getting Started Guide</a></li>
+
+ <li><a href="http://wiki.codesynthesis.com/Tree/Customization_guide">C++/Tree
+ Mapping Customization Guide</a></li>
+
+ <li><a href="http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/dbxml/">C++/Tree
+ Mapping and Berkeley DB XML Integration Guide</a></li>
+
+ <li><a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree
+ Mapping Frequently Asked Questions (FAQ)</a></li>
+
+ <li><a href="http://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD
+ Compiler Command Line Manual</a></li>
+
+ <li>The <code>examples/cxx/tree/</code> directory in the XSD
+ distribution contains a collection of examples and a README
+ file with an overview of each example.</li>
+
+ <li>The <code>README</code> file in the XSD distribution explains
+ how to compile the examples on various platforms.</li>
+
+ <li>The <a href="http://www.codesynthesis.com/mailman/listinfo/xsd-users">xsd-users</a>
+ mailing list is a place to ask questions. Furthermore the
+ <a href="http://www.codesynthesis.com/pipermail/xsd-users/">archives</a>
+ may already have answers to some of your questions.</li>
+
+ </ul>
+
+
+ <h1><a name="1">1 Introduction</a></h1>
+
+ <p>C++/Tree is a W3C XML Schema to C++ mapping that represents the
+ data stored in XML as a statically-typed, vocabulary-specific
+ object model. Based on a formal description of an XML vocabulary
+ (schema), the C++/Tree mapping produces a tree-like data structure
+ suitable for in-memory processing as well as XML parsing and
+ serialization code.</p>
+
+ <p>A typical application that processes XML documents usually
+ performs the following three steps: it first reads (parses) an XML
+ instance document to an object model, it then performs
+ some useful computations on that model which may involve
+ modification of the model, and finally it may write (serialize)
+ the modified object model back to XML.
+ </p>
+
+ <p>The C++/Tree mapping consists of C++ types that represent the
+ given vocabulary (<a href="#2">Chapter 2, "C++/Tree Mapping"</a>),
+ a set of parsing functions that convert XML documents to
+ a tree-like in-memory data structure (<a href="#3">Chapter 3,
+ "Parsing"</a>), and a set of serialization functions that convert
+ the object model back to XML (<a href="#4">Chapter 4,
+ "Serialization"</a>). Furthermore, the mapping provides a number
+ of additional features, such as DOM association and binary
+ serialization, that can be useful in some applications
+ (<a href="#5">Chapter 5, "Additional Functionality"</a>).
+ </p>
+
+
+ <!-- Chapter 2 -->
+
+
+ <h1><a name="2">2 C++/Tree Mapping</a></h1>
+
+ <h2><a name="2.1">2.1 Preliminary Information</a></h2>
+
+ <h3><a name="2.1.1">2.1.1 Identifiers</a></h3>
+
+ <p>XML Schema names may happen to be reserved C++ keywords or contain
+ characters that are illegal in C++ identifiers. To avoid C++ compilation
+ problems, such names are changed (escaped) when mapped to C++. If an
+ XML Schema name is a C++ keyword, the "_" suffix is added to it. All
+ character of an XML Schema name that are not allowed in C++ identifiers
+ are replaced with "_".
+ </p>
+
+ <p>For example, XML Schema name <code>try</code> will be mapped to
+ C++ identifier <code>try_</code>. Similarly, XML Schema name
+ <code>strange.na-me</code> will be mapped to C++ identifier
+ <code>strange_na_me</code>.
+ </p>
+
+ <p>Furthermore, conflicts between type names and function names in the
+ same scope are resolved using name escaping. Such conflicts include
+ both a global element (which is mapped to a set of parsing and/or
+ serialization functions or element types, see <a href="#2.9">Section
+ 2.9, "Mapping for Global Elements"</a>) and a global type sharing the
+ same name as well as a local element or attribute inside a type having
+ the same name as the type itself.</p>
+
+ <p>For example, if we had a global type <code>catalog</code>
+ and a global element with the same name then the type would be
+ mapped to a C++ class with name <code>catalog</code> while the
+ parsing functions corresponding to the global element would have
+ their names escaped as <code>catalog_</code>.
+ </p>
+
+ <p>By default the mapping uses the so-called K&amp;R (Kernighan and
+ Ritchie) identifier naming convention which is also used throughout
+ this manual. In this convention both type and function names are in
+ lower case and words are separated by underscores. If your application
+ code or schemas use a different notation, you may want to change the
+ naming convention used by the mapping for consistency.
+ The compiler supports a set of widely-used naming conventions
+ that you can select with the <code>--type-naming</code> and
+ <code>--function-naming</code> options. You can also further
+ refine one of the predefined conventions or create a completely
+ custom naming scheme by using the <code>--*-regex</code> options.
+ For more detailed information on these options refer to the NAMING
+ CONVENTION section in the <a href="http://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD
+ Compiler Command Line Manual</a>.</p>
+
+ <h3><a name="2.1.2">2.1.2 Character Type</a></h3>
+
+ <p>The code that implements the mapping, depending on the
+ <code>--char-type</code> option, is generated using either
+ <code>char</code> or <code>wchar_t</code> as the character
+ type. In this document code samples use symbol <code>C</code>
+ to refer to the character type you have selected when translating
+ your schemas, for example <code>std::basic_string&lt;C></code>.
+ </p>
+
+
+ <h3><a name="2.1.3">2.1.3 XML Schema Namespace</a></h3>
+
+ <p>The mapping relies on some predefined types, classes, and functions
+ that are logically defined in the XML Schema namespace reserved for
+ the XML Schema language (<code>http://www.w3.org/2001/XMLSchema</code>).
+ By default, this namespace is mapped to C++ namespace
+ <code>xml_schema</code>. It is automatically accessible
+ from a C++ compilation unit that includes a header file generated
+ from an XML Schema definition.
+ </p>
+
+ <p>Note that, if desired, the default mapping of this namespace can be
+ changed as described in <a href="#2.4">Section 2.4, "Mapping for
+ Namespaces"</a>.
+ </p>
+
+
+ <h3><a name="2.1.4">2.1.4 Anonymous Types</a></h3>
+
+ <p>For the purpose of code generation, anonymous types defined in
+ XML Schema are automatically assigned names that are derived
+ from enclosing attributes and elements. Otherwise, such types
+ follows standard mapping rules for simple and complex type
+ definitions (see <a href="#2.6">Section 2.6, "Mapping for Simple Types"</a>
+ and <a href="#2.7">Section 2.7, "Mapping for Complex Types"</a>).
+ For example, in the following schema fragment:
+ </p>
+
+ <pre class="xml">
+&lt;element name="object">
+ &lt;complexType>
+ ...
+ &lt;/complexType>
+&lt;/element>
+ </pre>
+
+ <p>The anonymous type defined inside element <code>object</code> will
+ be given name <code>object</code>. The compiler has a number of
+ options that control the process of anonymous type naming. For more
+ information refer to the <a href="http://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD
+ Compiler Command Line Manual</a>.</p>
+
+
+ <h2><a name="2.2">2.2 Error Handling</a></h2>
+
+ <p>The mapping uses the C++ exception handling mechanism as a primary way
+ of reporting error conditions. All exceptions that are specified in
+ this mapping derive from <code>xml_schema::exception</code> which
+ itself is derived from <code>std::exception</code>:
+ </p>
+
+ <pre class="c++">
+struct exception: virtual std::exception
+{
+ friend
+ std::basic_ostream&lt;C>&amp;
+ operator&lt;&lt; (std::basic_ostream&lt;C>&amp; os, const exception&amp; e)
+ {
+ e.print (os);
+ return os;
+ }
+
+protected:
+ virtual void
+ print (std::basic_ostream&lt;C>&amp;) const = 0;
+};
+ </pre>
+
+ <p>The exception hierarchy supports "virtual" <code>operator&lt;&lt;</code>
+ which allows you to obtain diagnostics corresponding to the thrown
+ exception using the base exception interface. For example:</p>
+
+ <pre class="c++">
+try
+{
+ ...
+}
+catch (const xml_schema::exception&amp; e)
+{
+ cerr &lt;&lt; e &lt;&lt; endl;
+}
+ </pre>
+
+ <p>The following sub-sections describe exceptions thrown by the
+ types that constitute the object model.
+ <a href="#3.3">Section 3.3, "Error Handling"</a> of
+ <a href="#3">Chapter 3, "Parsing"</a> describes exceptions
+ and error handling mechanisms specific to the parsing functions.
+ <a href="#4.4">Section 4.4, "Error Handling"</a> of
+ <a href="#4">Chapter 4, "Serialization"</a> describes exceptions
+ and error handling mechanisms specific to the serialization functions.
+ </p>
+
+
+ <h3><a name="2.2.1">2.2.1 <code>xml_schema::duplicate_id</code></a></h3>
+
+ <pre class="c++">
+struct duplicate_id: virtual exception
+{
+ duplicate_id (const std::basic_string&lt;C>&amp; id);
+
+ const std::basic_string&lt;C>&amp;
+ id () const;
+
+ virtual const char*
+ what () const throw ();
+};
+ </pre>
+
+ <p>The <code>xml_schema::duplicate_id</code> is thrown when
+ a conflicting instance of <code>xml_schema::id</code> (see
+ <a href="#2.5">Section 2.5, "Mapping for Built-in Data Types"</a>)
+ is added to a tree. The offending ID value can be obtained using
+ the <code>id</code> function.
+ </p>
+
+ <h2><a name="2.3">2.3 Mapping for <code>import</code> and <code>include</code></a></h2>
+
+ <h3><a name="2.3.1">2.3.1 Import</a></h3>
+
+ <p>The XML Schema <code>import</code> element is mapped to the C++
+ Preprocessor <code>#include</code> directive. The value of
+ the <code>schemaLocation</code> attribute is used to derive
+ the name of the header file that appears in the <code>#include</code>
+ directive. For instance:
+ </p>
+
+ <pre class="xml">
+&lt;import namespace="http://www.codesynthesis.com/test"
+ schemaLocation="test.xsd"/>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+#include "test.hxx"
+ </pre>
+
+ <p>Note that you will need to compile imported schemas separately
+ in order to produce corresponding header files.</p>
+
+ <h3><a name="2.3.2">2.3.2 Inclusion with Target Namespace</a></h3>
+
+ <p>The XML Schema <code>include</code> element which refers to a schema
+ with a target namespace or appears in a schema without a target namespace
+ follows the same mapping rules as the <code>import</code> element,
+ see <a href="#2.3.1">Section 2.3.1, "Import"</a>.
+ </p>
+
+ <h3><a name="2.3.3">2.3.3 Inclusion without Target Namespace</a></h3>
+
+ <p>For the XML Schema <code>include</code> element which refers to a schema
+ without a target namespace and appears in a schema with a target
+ namespace (such inclusion sometimes called "chameleon inclusion"),
+ declarations and definitions from the included schema are generated
+ in-line in the namespace of the including schema as if they were
+ declared and defined there verbatim. For example, consider the
+ following two schemas:
+ </p>
+
+ <pre class="xml">
+&lt;-- common.xsd -->
+&lt;schema>
+ &lt;complexType name="type">
+ ...
+ &lt;/complexType>
+&lt;/schema>
+
+&lt;-- test.xsd -->
+&lt;schema targetNamespace="http://www.codesynthesis.com/test">
+ &lt;include schemaLocation="common.xsd"/>
+&lt;/schema>
+ </pre>
+
+ <p>The fragment of interest from the generated header file for
+ <code>text.xsd</code> would look like this:</p>
+
+ <pre class="c++">
+// test.hxx
+namespace test
+{
+ class type
+ {
+ ...
+ };
+}
+ </pre>
+
+ <h2><a name="2.4">2.4 Mapping for Namespaces</a></h2>
+
+ <p>An XML Schema namespace is mapped to one or more nested C++
+ namespaces. XML Schema namespaces are identified by URIs.
+ By default, a namespace URI is mapped to a sequence of
+ C++ namespace names by removing the protocol and host parts
+ and splitting the rest into a sequence of names with '<code>/</code>'
+ as the name separator. For instance:
+ </p>
+
+ <pre class="xml">
+&lt;schema targetNamespace="http://www.codesynthesis.com/system/test">
+ ...
+&lt;/schema>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+namespace system
+{
+ namespace test
+ {
+ ...
+ }
+}
+ </pre>
+
+ <p>The default mapping of namespace URIs to C++ namespace names can be
+ altered using the <code>--namespace-map</code> and
+ <code>--namespace-regex</code> options. See the
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD
+ Compiler Command Line Manual</a> for more information.
+ </p>
+
+ <h2><a name="2.5">2.5 Mapping for Built-in Data Types</a></h2>
+
+ <p>The mapping of XML Schema built-in data types to C++ types is
+ summarized in the table below.</p>
+
+ <!-- border="1" is necessary for html2ps -->
+ <table id="builtin" border="1">
+ <tr>
+ <th>XML Schema type</th>
+ <th>Alias in the <code>xml_schema</code> namespace</th>
+ <th>C++ type</th>
+ </tr>
+
+ <tr>
+ <th colspan="3">anyType and anySimpleType types</th>
+ </tr>
+ <tr>
+ <td><code>anyType</code></td>
+ <td><code>type</code></td>
+ <td><a href="#2.5.2">Section 2.5.2, "Mapping for <code>anyType</code>"</a></td>
+ </tr>
+ <tr>
+ <td><code>anySimpleType</code></td>
+ <td><code>simple_type</code></td>
+ <td><a href="#2.5.3">Section 2.5.3, "Mapping for <code>anySimpleType</code>"</a></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">fixed-length integral types</th>
+ </tr>
+ <!-- 8-bit -->
+ <tr>
+ <td><code>byte</code></td>
+ <td><code>byte</code></td>
+ <td><code>signed&nbsp;char</code></td>
+ </tr>
+ <tr>
+ <td><code>unsignedByte</code></td>
+ <td><code>unsigned_byte</code></td>
+ <td><code>unsigned&nbsp;char</code></td>
+ </tr>
+
+ <!-- 16-bit -->
+ <tr>
+ <td><code>short</code></td>
+ <td><code>short_</code></td>
+ <td><code>short</code></td>
+ </tr>
+ <tr>
+ <td><code>unsignedShort</code></td>
+ <td><code>unsigned_short</code></td>
+ <td><code>unsigned&nbsp;short</code></td>
+ </tr>
+
+ <!-- 32-bit -->
+ <tr>
+ <td><code>int</code></td>
+ <td><code>int_</code></td>
+ <td><code>int</code></td>
+ </tr>
+ <tr>
+ <td><code>unsignedInt</code></td>
+ <td><code>unsigned_int</code></td>
+ <td><code>unsigned&nbsp;int</code></td>
+ </tr>
+
+ <!-- 64-bit -->
+ <tr>
+ <td><code>long</code></td>
+ <td><code>long_</code></td>
+ <td><code>long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>unsignedLong</code></td>
+ <td><code>unsigned_long</code></td>
+ <td><code>unsigned&nbsp;long&nbsp;long</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">arbitrary-length integral types</th>
+ </tr>
+ <tr>
+ <td><code>integer</code></td>
+ <td><code>integer</code></td>
+ <td><code>long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>nonPositiveInteger</code></td>
+ <td><code>non_positive_integer</code></td>
+ <td><code>long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>nonNegativeInteger</code></td>
+ <td><code>non_negative_integer</code></td>
+ <td><code>unsigned long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>positiveInteger</code></td>
+ <td><code>positive_integer</code></td>
+ <td><code>unsigned long&nbsp;long</code></td>
+ </tr>
+ <tr>
+ <td><code>negativeInteger</code></td>
+ <td><code>negative_integer</code></td>
+ <td><code>long&nbsp;long</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">boolean types</th>
+ </tr>
+ <tr>
+ <td><code>boolean</code></td>
+ <td><code>boolean</code></td>
+ <td><code>bool</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">fixed-precision floating-point types</th>
+ </tr>
+ <tr>
+ <td><code>float</code></td>
+ <td><code>float_</code></td>
+ <td><code>float</code></td>
+ </tr>
+ <tr>
+ <td><code>double</code></td>
+ <td><code>double_</code></td>
+ <td><code>double</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">arbitrary-precision floating-point types</th>
+ </tr>
+ <tr>
+ <td><code>decimal</code></td>
+ <td><code>decimal</code></td>
+ <td><code>double</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">string types</th>
+ </tr>
+ <tr>
+ <td><code>string</code></td>
+ <td><code>string</code></td>
+ <td>type derived from <code>std::basic_string</code></td>
+ </tr>
+ <tr>
+ <td><code>normalizedString</code></td>
+ <td><code>normalized_string</code></td>
+ <td>type derived from <code>string</code></td>
+ </tr>
+ <tr>
+ <td><code>token</code></td>
+ <td><code>token</code></td>
+ <td>type&nbsp;derived&nbsp;from&nbsp;<code>normalized_string</code></td>
+ </tr>
+ <tr>
+ <td><code>Name</code></td>
+ <td><code>name</code></td>
+ <td>type derived from <code>token</code></td>
+ </tr>
+ <tr>
+ <td><code>NMTOKEN</code></td>
+ <td><code>nmtoken</code></td>
+ <td>type derived from <code>token</code></td>
+ </tr>
+ <tr>
+ <td><code>NMTOKENS</code></td>
+ <td><code>nmtokens</code></td>
+ <td>type derived from <code>sequence&lt;nmtoken></code></td>
+ </tr>
+ <tr>
+ <td><code>NCName</code></td>
+ <td><code>ncname</code></td>
+ <td>type derived from <code>name</code></td>
+ </tr>
+ <tr>
+ <td><code>language</code></td>
+ <td><code>language</code></td>
+ <td>type derived from <code>token</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">qualified name</th>
+ </tr>
+ <tr>
+ <td><code>QName</code></td>
+ <td><code>qname</code></td>
+ <td><a href="#2.5.4">Section 2.5.4, "Mapping for <code>QName</code>"</a></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">ID/IDREF types</th>
+ </tr>
+ <tr>
+ <td><code>ID</code></td>
+ <td><code>id</code></td>
+ <td>type derived from <code>ncname</code></td>
+ </tr>
+ <tr>
+ <td><code>IDREF</code></td>
+ <td><code>idref</code></td>
+ <td><a href="#2.5.5">Section 2.5.5, "Mapping for <code>IDREF</code>"</a></td>
+ </tr>
+ <tr>
+ <td><code>IDREFS</code></td>
+ <td><code>idrefs</code></td>
+ <td>type derived from <code>sequence&lt;idref></code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">URI types</th>
+ </tr>
+ <tr>
+ <td><code>anyURI</code></td>
+ <td><code>uri</code></td>
+ <td>type derived from <code>std::basic_string</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">binary types</th>
+ </tr>
+ <tr>
+ <td><code>base64Binary</code></td>
+ <td><code>base64_binary</code></td>
+ <td rowspan="2"><a href="#2.5.6">Section 2.5.6, "Mapping for
+ <code>base64Binary</code> and <code>hexBinary</code>"</a></td>
+ </tr>
+ <tr>
+ <td><code>hexBinary</code></td>
+ <td><code>hex_binary</code></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">date/time types</th>
+ </tr>
+ <tr>
+ <td><code>date</code></td>
+ <td><code>date</code></td>
+ <td><a href="#2.5.8">Section 2.5.8, "Mapping for
+ <code>date</code>"</a></td>
+ </tr>
+ <tr>
+ <td><code>dateTime</code></td>
+ <td><code>date_time</code></td>
+ <td><a href="#2.5.9">Section 2.5.9, "Mapping for
+ <code>dateTime</code>"</a></td>
+ </tr>
+ <tr>
+ <td><code>duration</code></td>
+ <td><code>duration</code></td>
+ <td><a href="#2.5.10">Section 2.5.10, "Mapping for
+ <code>duration</code>"</a></td>
+ </tr>
+ <tr>
+ <td><code>gDay</code></td>
+ <td><code>gday</code></td>
+ <td><a href="#2.5.11">Section 2.5.11, "Mapping for
+ <code>gDay</code>"</a></td>
+ </tr>
+ <tr>
+ <td><code>gMonth</code></td>
+ <td><code>gmonth</code></td>
+ <td><a href="#2.5.12">Section 2.5.12, "Mapping for
+ <code>gMonth</code>"</a></td>
+ </tr>
+ <tr>
+ <td><code>gMonthDay</code></td>
+ <td><code>gmonth_day</code></td>
+ <td><a href="#2.5.13">Section 2.5.13, "Mapping for
+ <code>gMonthDay</code>"</a></td>
+ </tr>
+ <tr>
+ <td><code>gYear</code></td>
+ <td><code>gyear</code></td>
+ <td><a href="#2.5.14">Section 2.5.14, "Mapping for
+ <code>gYear</code>"</a></td>
+ </tr>
+ <tr>
+ <td><code>gYearMonth</code></td>
+ <td><code>gyear_month</code></td>
+ <td><a href="#2.5.15">Section 2.5.15, "Mapping for
+ <code>gYearMonth</code>"</a></td>
+ </tr>
+ <tr>
+ <td><code>time</code></td>
+ <td><code>time</code></td>
+ <td><a href="#2.5.16">Section 2.5.16, "Mapping for
+ <code>time</code>"</a></td>
+ </tr>
+
+ <tr>
+ <th colspan="3">entity types</th>
+ </tr>
+ <tr>
+ <td><code>ENTITY</code></td>
+ <td><code>entity</code></td>
+ <td>type derived from <code>name</code></td>
+ </tr>
+ <tr>
+ <td><code>ENTITIES</code></td>
+ <td><code>entities</code></td>
+ <td>type derived from <code>sequence&lt;entity></code></td>
+ </tr>
+ </table>
+
+ <p>All XML Schema built-in types are mapped to C++ classes that are
+ derived from the <code>xml_schema::simple_type</code> class except
+ where the mapping is to a fundamental C++ type.</p>
+
+ <p>The <code>sequence</code> class template is defined in an
+ implementation-specific namespace. It conforms to the
+ sequence interface as defined by the ISO/ANSI Standard for
+ C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences").
+ Practically, this means that you can treat such a sequence
+ as if it was <code>std::vector</code>. One notable extension
+ to the standard interface that is available only for
+ sequences of non-fundamental C++ types is the addition of
+ the overloaded <code>push_back</code> and <code>insert</code>
+ member functions which instead of the constant reference
+ to the element type accept automatic pointer to the element
+ type. These functions assume ownership of the pointed to
+ object and resets the passed automatic pointer.
+ </p>
+
+ <h3><a name="2.5.1">2.5.1 Inheritance from Built-in Data Types</a></h3>
+
+ <p>In cases where the mapping calls for an inheritance from a built-in
+ type which is mapped to a fundamental C++ type, a proxy type is
+ used instead of the fundamental C++ type (C++ does not allow
+ inheritance from fundamental types). For instance:</p>
+
+ <pre class="xml">
+&lt;simpleType name="my_int">
+ &lt;restriction base="int"/>
+&lt;/simpleType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class my_int: public fundamental_base&lt;int>
+{
+ ...
+};
+ </pre>
+
+ <p>The <code>fundamental_base</code> class template provides a close
+ emulation (though not exact) of a fundamental C++ type.
+ It is defined in an implementation-specific namespace and has the
+ following interface:</p>
+
+ <pre class="c++">
+template &lt;typename X>
+class fundamental_base: public simple_type
+{
+public:
+ fundamental_base ();
+ fundamental_base (X)
+ fundamental_base (const fundamental_base&amp;)
+
+public:
+ fundamental_base&amp;
+ operator= (const X&amp;);
+
+public:
+ operator const X &amp; () const;
+ operator X&amp; ();
+
+ template &lt;typename Y>
+ operator Y () const;
+
+ template &lt;typename Y>
+ operator Y ();
+};
+ </pre>
+
+ <h3><a name="2.5.2">2.5.2 Mapping for <code>anyType</code></a></h3>
+
+ <p>The XML Schema <code>anyType</code> built-in data type is mapped to the
+ <code>xml_schema::type</code> C++ class:</p>
+
+ <pre class="c++">
+class type
+{
+public:
+ virtual
+ ~type ();
+
+public:
+ type ();
+ type (const type&amp;);
+
+public:
+ type&amp;
+ operator= (const type&amp;);
+
+public:
+ virtual type*
+ _clone () const;
+
+ // DOM association.
+ //
+public:
+ const xercesc::DOMNode*
+ _node () const;
+
+ xercesc::DOMNode*
+ _node ();
+};
+ </pre>
+
+ <p>For more information about DOM association refer to
+ <a href="#5.1">Section 5.1, "DOM Association"</a>.</p>
+
+ <h3><a name="2.5.3">2.5.3 Mapping for <code>anySimpleType</code></a></h3>
+
+ <p>The XML Schema <code>anySimpleType</code> built-in data type is mapped
+ to the <code>xml_schema::simple_type</code> C++ class:</p>
+
+ <pre class="c++">
+class simple_type: public type
+{
+public:
+ simple_type ();
+ simple_type (const simple_type&amp;);
+
+public:
+ simple_type&amp;
+ operator= (const simple_type&amp;);
+
+public:
+ virtual simple_type*
+ _clone () const;
+};
+ </pre>
+
+
+ <h3><a name="2.5.4">2.5.4 Mapping for <code>QName</code></a></h3>
+
+ <p>The XML Schema <code>QName</code> built-in data type is mapped to the
+ <code>xml_schema::qname</code> C++ class:</p>
+
+ <pre class="c++">
+class qname: public simple_type
+{
+public:
+ qname (const ncname&amp;);
+ qname (const uri&amp;, const ncname&amp;);
+ qname (const qname&amp;);
+
+public:
+ qname&amp;
+ operator= (const qname&amp;);
+
+public:
+ virtual qname*
+ _clone () const;
+
+public:
+ bool
+ qualified () const;
+
+ const uri&amp;
+ namespace_ () const;
+
+ const ncname&amp;
+ name () const;
+};
+ </pre>
+
+ <p>The <code>qualified</code> accessor function can be used to determine
+ if the name is qualified.</p>
+
+ <h3><a name="2.5.5">2.5.5 Mapping for <code>IDREF</code></a></h3>
+
+ <p>The XML Schema <code>IDREF</code> built-in data type is mapped to the
+ <code>xml_schema::idref</code> C++ class. This class implements the
+ smart pointer C++ idiom:</p>
+
+ <pre class="c++">
+class idref: public ncname
+{
+public:
+ idref (const C* s);
+ idref (const C* s, std::size_t n);
+ idref (std::size_t n, C c);
+ idref (const std::basic_string&lt;C>&amp;);
+ idref (const std::basic_string&lt;C>&amp;,
+ std::size_t pos,
+ std::size_t n = npos);
+
+public:
+ idref (const idref&amp;);
+
+public:
+ virtual idref*
+ _clone () const;
+
+public:
+ idref&amp;
+ operator= (C c);
+
+ idref&amp;
+ operator= (const C* s);
+
+ idref&amp;
+ operator= (const std::basic_string&lt;C>&amp;)
+
+ idref&amp;
+ operator= (const idref&amp;);
+
+public:
+ const type*
+ operator-> () const;
+
+ type*
+ operator-> ();
+
+ const type&amp;
+ operator* () const;
+
+ type&amp;
+ operator* ();
+
+ const type*
+ get () const;
+
+ type*
+ get ();
+
+ // Conversion to bool.
+ //
+public:
+ typedef void (idref::*bool_convertible)();
+ operator bool_convertible () const;
+};
+ </pre>
+
+ <p>The object, <code>idref</code> instance refers to, is the immediate
+ container of the matching <code>id</code> instance. For example,
+ with the following instance document and schema:
+ </p>
+
+
+ <pre class="xml">
+&lt;!-- test.xml -->
+&lt;root>
+ &lt;object id="obj-1" text="hello"/>
+ &lt;reference>obj-1&lt;/reference>
+&lt;/root>
+
+&lt;!-- test.xsd -->
+&lt;schema>
+ &lt;complexType name="object_type">
+ &lt;attribute name="id" type="ID"/>
+ &lt;attribute name="text" type="string"/>
+ &lt;/complexType>
+
+ &lt;complexType name="root_type">
+ &lt;sequence>
+ &lt;element name="object" type="object_type"/>
+ &lt;element name="reference" type="IDREF"/>
+ &lt;/sequence>
+ &lt;/complexType>
+
+ &lt;element name="root" type="root_type"/>
+&lt;/schema>
+ </pre>
+
+ <p>The <code>ref</code> instance in the code below will refer to
+ an object of type <code>object_type</code>:</p>
+
+ <pre class="c++">
+root_type&amp; root = ...;
+xml_schema::idref&amp; ref (root.reference ());
+object_type&amp; obj (dynamic_cast&lt;object_type&amp;> (*ref));
+cout &lt;&lt; obj.text () &lt;&lt; endl;
+ </pre>
+
+ <p>The smart pointer interface of the <code>idref</code> class always
+ returns a pointer or reference to <code>xml_schema::type</code>.
+ This means that you will need to manually cast such pointer or
+ reference to its real (dynamic) type before you can use it (unless
+ all you need is the base interface provided by
+ <code>xml_schema::type</code>). As a special extension to the XML
+ Schema language, the mapping supports static typing of <code>idref</code>
+ references by employing the <code>refType</code> extension attribute.
+ The following example illustrates this mechanism:
+ </p>
+
+ <pre class="xml">
+&lt;!-- test.xsd -->
+&lt;schema
+ xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension">
+
+ ...
+
+ &lt;element name="reference" type="IDREF" xse:refType="object_type"/>
+
+ ...
+
+&lt;/schema>
+ </pre>
+
+ <p>With this modification we do not need to do manual casting anymore:
+ </p>
+
+ <pre class="c++">
+root_type&amp; root = ...;
+root_type::reference_type&amp; ref (root.reference ());
+object_type&amp; obj (*ref);
+cout &lt;&lt; ref->text () &lt;&lt; endl;
+ </pre>
+
+
+ <h3><a name="2.5.6">2.5.6 Mapping for <code>base64Binary</code> and
+ <code>hexBinary</code></a></h3>
+
+ <p>The XML Schema <code>base64Binary</code> and <code>hexBinary</code>
+ built-in data types are mapped to the
+ <code>xml_schema::base64_binary</code> and
+ <code>xml_schema::hex_binary</code> C++ classes, respectively. The
+ <code>base64_binary</code> and <code>hex_binary</code> classes
+ support a simple buffer abstraction by inheriting from the
+ <code>xml_schema::buffer</code> class:
+ </p>
+
+ <pre class="c++">
+class bounds: public virtual exception
+{
+public:
+ virtual const char*
+ what () const throw ();
+};
+
+class buffer
+{
+public:
+ typedef std::size_t size_t;
+
+public:
+ buffer (size_t size = 0);
+ buffer (size_t size, size_t capacity);
+ buffer (const void* data, size_t size);
+ buffer (const void* data, size_t size, size_t capacity);
+ buffer (void* data,
+ size_t size,
+ size_t capacity,
+ bool assume_ownership);
+
+public:
+ buffer (const buffer&amp;);
+
+ buffer&amp;
+ operator= (const buffer&amp;);
+
+ void
+ swap (buffer&amp;);
+
+public:
+ size_t
+ capacity () const;
+
+ bool
+ capacity (size_t);
+
+public:
+ size_t
+ size () const;
+
+ bool
+ size (size_t);
+
+public:
+ const char*
+ data () const;
+
+ char*
+ data ();
+
+ const char*
+ begin () const;
+
+ char*
+ begin ();
+
+ const char*
+ end () const;
+
+ char*
+ end ();
+};
+ </pre>
+
+ <p>If the <code>assume_ownership</code> argument to the constructor
+ is <code>true</code>, the instance assumes ownership of the
+ memory block pointed to by the <code>data</code> argument and will
+ eventually release it by calling <code>operator delete</code>. The
+ <code>capacity</code> and <code>size</code> modifier functions return
+ <code>true</code> if the underlying buffer has moved.
+ </p>
+
+ <p>The <code>bounds</code> exception is thrown if the constructor
+ arguments violate the <code>(size&nbsp;&lt;=&nbsp;capacity)</code>
+ constraint.</p>
+
+ <p>The <code>base64_binary</code> and <code>hex_binary</code> classes
+ support the <code>buffer</code> interface and perform automatic
+ decoding/encoding from/to the Base64 and Hex formats, respectively:
+ </p>
+
+ <pre class="c++">
+class base64_binary: public simple_type, public buffer
+{
+public:
+ base64_binary (size_t size = 0);
+ base64_binary (size_t size, size_t capacity);
+ base64_binary (const void* data, size_t size);
+ base64_binary (const void* data, size_t size, size_t capacity);
+ base64_binary (void* data,
+ size_t size,
+ size_t capacity,
+ bool assume_ownership);
+
+public:
+ base64_binary (const base64_binary&amp;);
+
+ base64_binary&amp;
+ operator= (const base64_binary&amp;);
+
+ virtual base64_binary*
+ _clone () const;
+
+public:
+ std::basic_string&lt;C>
+ encode () const;
+};
+ </pre>
+
+ <pre class="c++">
+class hex_binary: public simple_type, public buffer
+{
+public:
+ hex_binary (size_t size = 0);
+ hex_binary (size_t size, size_t capacity);
+ hex_binary (const void* data, size_t size);
+ hex_binary (const void* data, size_t size, size_t capacity);
+ hex_binary (void* data,
+ size_t size,
+ size_t capacity,
+ bool assume_ownership);
+
+public:
+ hex_binary (const hex_binary&amp;);
+
+ hex_binary&amp;
+ operator= (const hex_binary&amp;);
+
+ virtual hex_binary*
+ _clone () const;
+
+public:
+ std::basic_string&lt;C>
+ encode () const;
+};
+ </pre>
+
+
+ <h2><a name="2.5.7">2.5.7 Time Zone Representation</a></h2>
+
+ <p>The <code>date</code>, <code>dateTime</code>, <code>gDay</code>,
+ <code>gMonth</code>, <code>gMonthDay</code>, <code>gYear</code>,
+ <code>gYearMonth</code>, and <code>time</code> XML Schema built-in
+ types all include an optional time zone component. The following
+ <code>xml_schema::time_zone</code> base class is used to represent
+ this information:</p>
+
+ <pre class="c++">
+class time_zone
+{
+public:
+ time_zone ();
+ time_zone (short hours, short minutes);
+
+ bool
+ zone_present () const;
+
+ void
+ zone_reset ();
+
+ short
+ zone_hours () const;
+
+ void
+ zone_hours (short);
+
+ short
+ zone_minutes () const;
+
+ void
+ zone_minutes (short);
+};
+
+bool
+operator== (const time_zone&amp;, const time_zone&amp;);
+
+bool
+operator!= (const time_zone&amp;, const time_zone&amp;);
+ </pre>
+
+ <p>The <code>zone_present()</code> accessor function returns <code>true</code>
+ if the time zone is specified. The <code>zone_reset()</code> modifier
+ function resets the time zone object to the <em>not specified</em>
+ state. If the time zone offset is negative then both hours and
+ minutes components are represented as negative integers.</p>
+
+
+ <h2><a name="2.5.8">2.5.8 Mapping for <code>date</code></a></h2>
+
+ <p>The XML Schema <code>date</code> built-in data type is mapped to the
+ <code>xml_schema::date</code> C++ class which represents a year, a day,
+ and a month with an optional time zone. Its interface is presented
+ below. For more information on the base <code>xml_schema::time_zone</code>
+ class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone
+ Representation"</a>.</p>
+
+ <pre class="c++">
+class date: public simple_type, public time_zone
+{
+public:
+ date (int year, unsigned short month, unsigned short day);
+ date (int year, unsigned short month, unsigned short day,
+ short zone_hours, short zone_minutes);
+
+public:
+ date (const date&amp;);
+
+ date&amp;
+ operator= (const date&amp;);
+
+ virtual date*
+ _clone () const;
+
+public:
+ int
+ year () const;
+
+ void
+ year (int);
+
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+
+ unsigned short
+ day () const;
+
+ void
+ day (unsigned short);
+};
+
+bool
+operator== (const date&amp;, const date&amp;);
+
+bool
+operator!= (const date&amp;, const date&amp;);
+ </pre>
+
+ <h2><a name="2.5.9">2.5.9 Mapping for <code>dateTime</code></a></h2>
+
+ <p>The XML Schema <code>dateTime</code> built-in data type is mapped to the
+ <code>xml_schema::date_time</code> C++ class which represents a year, a month,
+ a day, hours, minutes, and seconds with an optional time zone. Its interface
+ is presented below. For more information on the base
+ <code>xml_schema::time_zone</code> class refer to <a href="#2.5.7">Section
+ 2.5.7, "Time Zone Representation"</a>.</p>
+
+ <pre class="c++">
+class date_time: public simple_type, public time_zone
+{
+public:
+ date_time (int year, unsigned short month, unsigned short day,
+ unsigned short hours, unsigned short minutes,
+ double seconds);
+
+ date_time (int year, unsigned short month, unsigned short day,
+ unsigned short hours, unsigned short minutes,
+ double seconds, short zone_hours, short zone_minutes);
+public:
+ date_time (const date_time&amp;);
+
+ date_time&amp;
+ operator= (const date_time&amp;);
+
+ virtual date_time*
+ _clone () const;
+
+public:
+ int
+ year () const;
+
+ void
+ year (int);
+
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+
+ unsigned short
+ day () const;
+
+ void
+ day (unsigned short);
+
+ unsigned short
+ hours () const;
+
+ void
+ hours (unsigned short);
+
+ unsigned short
+ minutes () const;
+
+ void
+ minutes (unsigned short);
+
+ double
+ seconds () const;
+
+ void
+ seconds (double);
+};
+
+bool
+operator== (const date_time&amp;, const date_time&amp;);
+
+bool
+operator!= (const date_time&amp;, const date_time&amp;);
+ </pre>
+
+
+ <h2><a name="2.5.10">2.5.10 Mapping for <code>duration</code></a></h2>
+
+ <p>The XML Schema <code>duration</code> built-in data type is mapped to the
+ <code>xml_schema::duration</code> C++ class which represents a potentially
+ negative duration in the form of years, months, days, hours, minutes,
+ and seconds. Its interface is presented below.</p>
+
+ <pre class="c++">
+class duration: public simple_type
+{
+public:
+ duration (bool negative,
+ unsigned int years, unsigned int months, unsigned int days,
+ unsigned int hours, unsigned int minutes, double seconds);
+public:
+ duration (const duration&amp;);
+
+ duration&amp;
+ operator= (const duration&amp;);
+
+ virtual duration*
+ _clone () const;
+
+public:
+ bool
+ negative () const;
+
+ void
+ negative (bool);
+
+ unsigned int
+ years () const;
+
+ void
+ years (unsigned int);
+
+ unsigned int
+ months () const;
+
+ void
+ months (unsigned int);
+
+ unsigned int
+ days () const;
+
+ void
+ days (unsigned int);
+
+ unsigned int
+ hours () const;
+
+ void
+ hours (unsigned int);
+
+ unsigned int
+ minutes () const;
+
+ void
+ minutes (unsigned int);
+
+ double
+ seconds () const;
+
+ void
+ seconds (double);
+};
+
+bool
+operator== (const duration&amp;, const duration&amp;);
+
+bool
+operator!= (const duration&amp;, const duration&amp;);
+ </pre>
+
+
+ <h2><a name="2.5.11">2.5.11 Mapping for <code>gDay</code></a></h2>
+
+ <p>The XML Schema <code>gDay</code> built-in data type is mapped to the
+ <code>xml_schema::gday</code> C++ class which represents a day of the
+ month with an optional time zone. Its interface is presented below.
+ For more information on the base <code>xml_schema::time_zone</code>
+ class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone
+ Representation"</a>.</p>
+
+ <pre class="c++">
+class gday: public simple_type, public time_zone
+{
+public:
+ explicit
+ gday (unsigned short day);
+ gday (unsigned short day, short zone_hours, short zone_minutes);
+
+public:
+ gday (const gday&amp;);
+
+ gday&amp;
+ operator= (const gday&amp;);
+
+ virtual gday*
+ _clone () const;
+
+public:
+ unsigned short
+ day () const;
+
+ void
+ day (unsigned short);
+};
+
+bool
+operator== (const gday&amp;, const gday&amp;);
+
+bool
+operator!= (const gday&amp;, const gday&amp;);
+ </pre>
+
+
+ <h2><a name="2.5.12">2.5.12 Mapping for <code>gMonth</code></a></h2>
+
+ <p>The XML Schema <code>gMonth</code> built-in data type is mapped to the
+ <code>xml_schema::gmonth</code> C++ class which represents a month of the
+ year with an optional time zone. Its interface is presented below.
+ For more information on the base <code>xml_schema::time_zone</code>
+ class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone
+ Representation"</a>.</p>
+
+ <pre class="c++">
+class gmonth: public simple_type, public time_zone
+{
+public:
+ explicit
+ gmonth (unsigned short month);
+ gmonth (unsigned short month,
+ short zone_hours, short zone_minutes);
+
+public:
+ gmonth (const gmonth&amp;);
+
+ gmonth&amp;
+ operator= (const gmonth&amp;);
+
+ virtual gmonth*
+ _clone () const;
+
+public:
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+};
+
+bool
+operator== (const gmonth&amp;, const gmonth&amp;);
+
+bool
+operator!= (const gmonth&amp;, const gmonth&amp;);
+ </pre>
+
+
+ <h2><a name="2.5.13">2.5.13 Mapping for <code>gMonthDay</code></a></h2>
+
+ <p>The XML Schema <code>gMonthDay</code> built-in data type is mapped to the
+ <code>xml_schema::gmonth_day</code> C++ class which represents a day and
+ a month of the year with an optional time zone. Its interface is presented
+ below. For more information on the base <code>xml_schema::time_zone</code>
+ class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone
+ Representation"</a>.</p>
+
+ <pre class="c++">
+class gmonth_day: public simple_type, public time_zone
+{
+public:
+ gmonth_day (unsigned short month, unsigned short day);
+ gmonth_day (unsigned short month, unsigned short day,
+ short zone_hours, short zone_minutes);
+
+public:
+ gmonth_day (const gmonth_day&amp;);
+
+ gmonth_day&amp;
+ operator= (const gmonth_day&amp;);
+
+ virtual gmonth_day*
+ _clone () const;
+
+public:
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+
+ unsigned short
+ day () const;
+
+ void
+ day (unsigned short);
+};
+
+bool
+operator== (const gmonth_day&amp;, const gmonth_day&amp;);
+
+bool
+operator!= (const gmonth_day&amp;, const gmonth_day&amp;);
+ </pre>
+
+
+ <h2><a name="2.5.14">2.5.14 Mapping for <code>gYear</code></a></h2>
+
+ <p>The XML Schema <code>gYear</code> built-in data type is mapped to the
+ <code>xml_schema::gyear</code> C++ class which represents a year with
+ an optional time zone. Its interface is presented below. For more
+ information on the base <code>xml_schema::time_zone</code> class refer
+ to <a href="#2.5.7">Section 2.5.7, "Time Zone Representation"</a>.</p>
+
+ <pre class="c++">
+class gyear: public simple_type, public time_zone
+{
+public:
+ explicit
+ gyear (int year);
+ gyear (int year, short zone_hours, short zone_minutes);
+
+public:
+ gyear (const gyear&amp;);
+
+ gyear&amp;
+ operator= (const gyear&amp;);
+
+ virtual gyear*
+ _clone () const;
+
+public:
+ int
+ year () const;
+
+ void
+ year (int);
+};
+
+bool
+operator== (const gyear&amp;, const gyear&amp;);
+
+bool
+operator!= (const gyear&amp;, const gyear&amp;);
+ </pre>
+
+
+ <h2><a name="2.5.15">2.5.15 Mapping for <code>gYearMonth</code></a></h2>
+
+ <p>The XML Schema <code>gYearMonth</code> built-in data type is mapped to
+ the <code>xml_schema::gyear_month</code> C++ class which represents
+ a year and a month with an optional time zone. Its interface is presented
+ below. For more information on the base <code>xml_schema::time_zone</code>
+ class refer to <a href="#2.5.7">Section 2.5.7, "Time Zone
+ Representation"</a>.</p>
+
+ <pre class="c++">
+class gyear_month: public simple_type, public time_zone
+{
+public:
+ gyear_month (int year, unsigned short month);
+ gyear_month (int year, unsigned short month,
+ short zone_hours, short zone_minutes);
+public:
+ gyear_month (const gyear_month&amp;);
+
+ gyear_month&amp;
+ operator= (const gyear_month&amp;);
+
+ virtual gyear_month*
+ _clone () const;
+
+public:
+ int
+ year () const;
+
+ void
+ year (int);
+
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+};
+
+bool
+operator== (const gyear_month&amp;, const gyear_month&amp;);
+
+bool
+operator!= (const gyear_month&amp;, const gyear_month&amp;);
+ </pre>
+
+
+ <h2><a name="2.5.16">2.5.16 Mapping for <code>time</code></a></h2>
+
+ <p>The XML Schema <code>time</code> built-in data type is mapped to
+ the <code>xml_schema::time</code> C++ class which represents hours,
+ minutes, and seconds with an optional time zone. Its interface is
+ presented below. For more information on the base
+ <code>xml_schema::time_zone</code> class refer to
+ <a href="#2.5.7">Section 2.5.7, "Time Zone Representation"</a>.</p>
+
+ <pre class="c++">
+class time: public simple_type, public time_zone
+{
+public:
+ time (unsigned short hours, unsigned short minutes, double seconds);
+ time (unsigned short hours, unsigned short minutes, double seconds,
+ short zone_hours, short zone_minutes);
+
+public:
+ time (const time&amp;);
+
+ time&amp;
+ operator= (const time&amp;);
+
+ virtual time*
+ _clone () const;
+
+public:
+ unsigned short
+ hours () const;
+
+ void
+ hours (unsigned short);
+
+ unsigned short
+ minutes () const;
+
+ void
+ minutes (unsigned short);
+
+ double
+ seconds () const;
+
+ void
+ seconds (double);
+};
+
+bool
+operator== (const time&amp;, const time&amp;);
+
+bool
+operator!= (const time&amp;, const time&amp;);
+ </pre>
+
+
+ <!-- Mapping for Simple Types -->
+
+ <h2><a name="2.6">2.6 Mapping for Simple Types</a></h2>
+
+ <p>An XML Schema simple type is mapped to a C++ class with the same
+ name as the simple type. The class defines a public copy constructor,
+ a public copy assignment operator, and a public virtual
+ <code>_clone</code> function. The <code>_clone</code> function is
+ declared <code>const</code>, does not take any arguments, and returns
+ a pointer to a complete copy of the instance allocated in the free
+ store. The <code>_clone</code> function shall be used to make copies
+ when static type and dynamic type of the instance may differ (see
+ <a href="#2.11">Section 2.11, "Mapping for <code>xsi:type</code>
+ and Substitution Groups"</a>). For instance:</p>
+
+ <pre class="xml">
+&lt;simpleType name="object">
+ ...
+&lt;/simpleType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class object: ...
+{
+public:
+ object (const object&amp;);
+
+public:
+ object&amp;
+ operator= (const object&amp;);
+
+public:
+ virtual object*
+ _clone () const;
+
+ ...
+
+};
+ </pre>
+
+ <p>The base class specification and the rest of the class definition
+ depend on the type of derivation used to define the simple type. </p>
+
+
+ <h3><a name="2.6.1">2.6.1 Mapping for Derivation by Restriction</a></h3>
+
+ <p>XML Schema derivation by restriction is mapped to C++ public
+ inheritance. The base type of the restriction becomes the base
+ type for the resulting C++ class. In addition to the members described
+ in <a href="#2.6">Section 2.6, "Mapping for Simple Types"</a>, the
+ resulting C++ class defines a public constructor with the base type
+ as its single argument. For instance:</p>
+
+ <pre class="xml">
+&lt;simpleType name="object">
+ &lt;restriction base="base">
+ ...
+ &lt;/restriction>
+&lt;/simpleType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class object: public base
+{
+public:
+ object (const base&amp;);
+ object (const object&amp;);
+
+public:
+ object&amp;
+ operator= (const object&amp;);
+
+public:
+ virtual object*
+ _clone () const;
+};
+ </pre>
+
+
+ <h3><a name="2.6.2">2.6.2 Mapping for Enumerations</a></h3>
+
+<p>XML Schema restriction by enumeration is mapped to a C++ class
+ with semantics similar to C++ <code>enum</code>. Each XML Schema
+ enumeration element is mapped to a C++ enumerator with the
+ name derived from the <code>value</code> attribute and defined
+ in the class scope. In addition to the members
+ described in <a href="#2.6">Section 2.6, "Mapping for Simple Types"</a>,
+ the resulting C++ class defines a public constructor that can be called
+ with one of the enumerators as its single argument, a public constructor
+ that can be called with enumeration's base value as its single
+ argument, a public assignment operator that can be used to assign the
+ value of one of the enumerators, and a public implicit conversion
+ operator to the underlying C++ enum type.</p>
+
+<p>Furthermore, for string-based enumeration types, the resulting C++
+ class defines a public constructor with a single argument of type
+ <code>const C*</code> and a public constructor with a single
+ argument of type <code>const std::basic_string&lt;C>&amp;</code>.
+ For instance:</p>
+
+ <pre class="xml">
+&lt;simpleType name="color">
+ &lt;restriction base="string">
+ &lt;enumeration value="red"/>
+ &lt;enumeration value="green"/>
+ &lt;enumeration value="blue"/>
+ &lt;/restriction>
+&lt;/simpleType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class color: xml_schema::string
+{
+public:
+ enum value
+ {
+ red,
+ green,
+ blue
+ };
+
+public:
+ color (value);
+ color (const C*);
+ color (const std::basic_string&lt;C>&amp;);
+ color (const xml_schema::string&amp;);
+ color (const color&amp;);
+
+public:
+ color&amp;
+ operator= (value);
+
+ color&amp;
+ operator= (const color&amp;);
+
+public:
+ virtual color*
+ _clone () const;
+
+public:
+ operator value () const;
+};
+ </pre>
+
+ <h3><a name="2.6.3">2.6.3 Mapping for Derivation by List</a></h3>
+
+ <p>XML Schema derivation by list is mapped to C++ public
+ inheritance from <code>xml_schema::simple_type</code>
+ (<a href="#2.5.3">Section 2.5.3, "Mapping for
+ <code>anySimpleType</code>"</a>) and a suitable sequence type.
+ The list item type becomes the element type of the sequence.
+ In addition to the members described in <a href="#2.6">Section 2.6,
+ "Mapping for Simple Types"</a>, the resulting C++ class defines
+ a public default constructor, a public constructor
+ with the first argument of type <code>size_type</code> and
+ the second argument of list item type that creates
+ a list object with the specified number of copies of the specified
+ element value, and a public constructor with the two arguments
+ of an input iterator type that creates a list object from an
+ iterator range. For instance:
+ </p>
+
+ <pre class="xml">
+&lt;simpleType name="int_list">
+ &lt;list itemType="int"/>
+&lt;/simpleType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class int_list: public simple_type,
+ public sequence&lt;int>
+{
+public:
+ int_list ();
+ int_list (size_type n, int x);
+
+ template &lt;typename I>
+ int_list (const I&amp; begin, const I&amp; end);
+ int_list (const int_list&amp;);
+
+public:
+ int_list&amp;
+ operator= (const int_list&amp;);
+
+public:
+ virtual int_list*
+ _clone () const;
+};
+ </pre>
+
+ <p>The <code>sequence</code> class template is defined in an
+ implementation-specific namespace. It conforms to the
+ sequence interface as defined by the ISO/ANSI Standard for
+ C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences").
+ Practically, this means that you can treat such a sequence
+ as if it was <code>std::vector</code>. One notable extension
+ to the standard interface that is available only for
+ sequences of non-fundamental C++ types is the addition of
+ the overloaded <code>push_back</code> and <code>insert</code>
+ member functions which instead of the constant reference
+ to the element type accept automatic pointer to the element
+ type. These functions assume ownership of the pointed to
+ object and resets the passed automatic pointer.
+ </p>
+
+ <h3><a name="2.6.4">2.6.4 Mapping for Derivation by Union</a></h3>
+
+ <p>XML Schema derivation by union is mapped to C++ public
+ inheritance from <code>xml_schema::simple_type</code>
+ (<a href="#2.5.3">Section 2.5.3, "Mapping for
+ <code>anySimpleType</code>"</a>) and <code>std::basic_string&lt;C></code>.
+ In addition to the members described in <a href="#2.6">Section 2.6,
+ "Mapping for Simple Types"</a>, the resulting C++ class defines a
+ public constructor with a single argument of type <code>const C*</code>
+ and a public constructor with a single argument of type
+ <code>const std::basic_string&lt;C>&amp;</code>. For instance:
+ </p>
+
+ <pre class="xml">
+&lt;simpleType name="int_string_union">
+ &lt;xsd:union memberTypes="xsd:int xsd:string"/>
+&lt;/simpleType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class int_string_union: public simple_type,
+ public std::basic_string&lt;C>
+{
+public:
+ int_string_union (const C*);
+ int_string_union (const std::basic_string&lt;C>&amp;);
+ int_string_union (const int_string_union&amp;);
+
+public:
+ int_string_union&amp;
+ operator= (const int_string_union&amp;);
+
+public:
+ virtual int_string_union*
+ _clone () const;
+};
+ </pre>
+
+ <h2><a name="2.7">2.7 Mapping for Complex Types</a></h2>
+
+ <p>An XML Schema complex type is mapped to a C++ class with the same
+ name as the complex type. The class defines a public copy constructor,
+ a public copy assignment operator, and a public virtual
+ <code>_clone</code> function. The <code>_clone</code> function is
+ declared <code>const</code>, does not take any arguments, and returns
+ a pointer to a complete copy of the instance allocated in the free
+ store. The <code>_clone</code> function shall be used to make copies
+ when static type and dynamic type of the instance may differ (see
+ <a href="#2.11">Section 2.11, "Mapping for <code>xsi:type</code>
+ and Substitution Groups"</a>).</p>
+
+ <p>Additionally, the resulting C++ class
+ defines two public constructors that take an initializer for each
+ member of the complex type and all its base types that belongs to
+ the One cardinality class (see <a href="#2.8">Section 2.8, "Mapping
+ for Local Elements and Attributes"</a>). In the first constructor,
+ the arguments are passed as constant references and the newly created
+ instance is initialized with copies of the passed objects. In the
+ second constructor, arguments that are complex types (that is,
+ they themselves contain elements or attributes) are passed as
+ references to <code>std::auto_ptr</code>. In this case the newly
+ created instance is directly initialized with and assumes ownership
+ of the pointed to objects and the <code>std::auto_ptr</code> arguments
+ are reset to <code>0</code>. For instance:</p>
+
+ <pre class="xml">
+&lt;complexType name="complex">
+ &lt;sequence>
+ &lt;element name="a" type="int"/>
+ &lt;element name="b" type="string"/>
+ &lt;/sequence>
+&lt;/complexType>
+
+&lt;complexType name="object">
+ &lt;sequence>
+ &lt;element name="s-one" type="boolean"/>
+ &lt;element name="c-one" type="complex"/>
+ &lt;element name="optional" type="int" minOccurs="0"/>
+ &lt;element name="sequence" type="string" maxOccurs="unbounded"/>
+ &lt;/sequence>
+&lt;/complexType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class complex: xml_schema::type
+{
+public:
+ object (const int&amp; a, const xml_schema::string&amp; b);
+ object (const complex&amp;);
+
+public:
+ object&amp;
+ operator= (const complex&amp;);
+
+public:
+ virtual complex*
+ _clone () const;
+
+ ...
+
+};
+
+class object: xml_schema::type
+{
+public:
+ object (const bool&amp; s_one, const complex&amp; c_one);
+ object (const bool&amp; s_one, std::auto_ptr&lt;complex>&amp; c_one);
+ object (const object&amp;);
+
+public:
+ object&amp;
+ operator= (const object&amp;);
+
+public:
+ virtual object*
+ _clone () const;
+
+ ...
+
+};
+ </pre>
+
+ <p>Notice that the generated <code>complex</code> class does not
+ have the second (<code>std::auto_ptr</code>) version of the
+ constructor since all its required members are of simple types.</p>
+
+ <p>If an XML Schema complex type has an ultimate base which is an XML
+ Schema simple type then the resulting C++ class also defines a public
+ constructor that takes an initializer for the base type as well as
+ for each member of the complex type and all its base types that
+ belongs to the One cardinality class. For instance:</p>
+
+ <pre class="xml">
+&lt;complexType name="object">
+ &lt;simpleContent>
+ &lt;extension base="date">
+ &lt;attribute name="lang" type="language" use="required"/>
+ &lt;/extension>
+ &lt;/simpleContent>
+&lt;/complexType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class object: xml_schema::string
+{
+public:
+ object (const xml_schema::language&amp; lang);
+
+ object (const xml_schema::date&amp; base,
+ const xml_schema::language&amp; lang);
+
+ ...
+
+};
+ </pre>
+
+ <p>Furthermore, for string-based XML Schema complex types, the resulting C++
+ class also defines two public constructors with the first arguments
+ of type <code>const C*</code> and <code>std::basic_string&lt;C>&amp;</code>,
+ respectively, followed by arguments for each member of the complex
+ type and all its base types that belongs to the One cardinality
+ class. For enumeration-based complex types the resulting C++
+ class also defines a public constructor with the first arguments
+ of the underlying enum type followed by arguments for each member
+ of the complex type and all its base types that belongs to the One
+ cardinality class. For instance:</p>
+
+ <pre class="xml">
+&lt;simpleType name="color">
+ &lt;restriction base="string">
+ &lt;enumeration value="red"/>
+ &lt;enumeration value="green"/>
+ &lt;enumeration value="blue"/>
+ &lt;/restriction>
+&lt;/simpleType>
+
+&lt;complexType name="object">
+ &lt;simpleContent>
+ &lt;extension base="color">
+ &lt;attribute name="lang" type="language" use="required"/>
+ &lt;/extension>
+ &lt;/simpleContent>
+&lt;/complexType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class color: xml_schema::string
+{
+public:
+ enum value
+ {
+ red,
+ green,
+ blue
+ };
+
+public:
+ color (value);
+ color (const C*);
+ color (const std::basic_string&lt;C>&amp;);
+
+ ...
+
+};
+
+class object: color
+{
+public:
+ object (const color&amp; base,
+ const xml_schema::language&amp; lang);
+
+ object (const color::value&amp; base,
+ const xml_schema::language&amp; lang);
+
+ object (const C* base,
+ const xml_schema::language&amp; lang);
+
+ object (const std::basic_string&lt;C>&amp; base,
+ const xml_schema::language&amp; lang);
+
+ ...
+
+};
+ </pre>
+
+ <p>Additional constructors can be requested with the
+ <code>--generate-default-ctor</code> and
+ <code>--generate-from-base-ctor</code> options. See the
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD
+ Compiler Command Line Manual</a> for details.</p>
+
+ <p>If an XML Schema complex type is not explicitly derived from any type,
+ the resulting C++ class is derived from <code>xml_schema::type</code>.
+ In cases where an XML Schema complex type is defined using derivation
+ by extension or restriction, the resulting C++ base class specification
+ depends on the type of derivation and is described in the subsequent
+ sections.
+ </p>
+
+ <p>The mapping for elements and attributes that are defined in a complex
+ type is described in <a href="#2.8">Section 2.8, "Mapping for Local
+ Elements and Attributes"</a>.
+ </p>
+
+ <h3><a name="2.7.1">2.7.1 Mapping for Derivation by Extension</a></h3>
+
+ <p>XML Schema derivation by extension is mapped to C++ public
+ inheritance. The base type of the extension becomes the base
+ type for the resulting C++ class.
+ </p>
+
+ <h3><a name="2.7.2">2.7.2 Mapping for Derivation by Restriction</a></h3>
+
+ <p>XML Schema derivation by restriction is mapped to C++ public
+ inheritance. The base type of the restriction becomes the base
+ type for the resulting C++ class. XML Schema elements and
+ attributes defined within restriction do not result in any
+ definitions in the resulting C++ class. Instead, corresponding
+ (unrestricted) definitions are inherited from the base class.
+ In the future versions of this mapping, such elements and
+ attributes may result in redefinitions of accessors and
+ modifiers to reflect their restricted semantics.
+ </p>
+
+ <!-- 2.8 Mapping for Local Elements and Attributes -->
+
+ <h2><a name="2.8">2.8 Mapping for Local Elements and Attributes</a></h2>
+
+ <p>XML Schema element and attribute definitions are called local
+ if they appear within a complex type definition, an element group
+ definition, or an attribute group definitions.
+ </p>
+
+ <p>Local XML Schema element and attribute definitions have the same
+ C++ mapping. Therefore, in this section, local elements and
+ attributes are collectively called members.
+ </p>
+
+ <p>While there are many different member cardinality combinations
+ (determined by the <code>use</code> attribute for attributes and
+ the <code>minOccurs</code> and <code>maxOccurs</code> attributes
+ for elements), the mapping divides all possible cardinality
+ combinations into three cardinality classes:
+ </p>
+
+ <dl>
+ <dt><i>one</i></dt>
+ <dd>attributes: <code>use == "required"</code></dd>
+ <dd>attributes: <code>use == "optional"</code> and has default or fixed value</dd>
+ <dd>elements: <code>minOccurs == "1"</code> and <code>maxOccurs == "1"</code></dd>
+
+ <dt><i>optional</i></dt>
+ <dd>attributes: <code>use == "optional"</code> and doesn't have default or fixed value</dd>
+ <dd>elements: <code>minOccurs == "0"</code> and <code>maxOccurs == "1"</code></dd>
+
+ <dt><i>sequence</i></dt>
+ <dd>elements: <code>maxOccurs > "1"</code></dd>
+ </dl>
+
+ <p>An optional attribute with a default or fixed value acquires this value
+ if the attribute hasn't been specified in an instance document (see
+ <a href="#A">Appendix A, "Default and Fixed Values"</a>). This
+ mapping places such optional attributes to the One cardinality
+ class.</p>
+
+ <p>A member is mapped to a set of public type definitions
+ (<code>typedef</code>s) and a set of public accessor and modifier
+ functions. Type definitions have names derived from the member's
+ name. The accessor and modifier functions have the same name as the
+ member. For example:
+ </p>
+
+ <pre class="xml">
+&lt;complexType name="object">
+ &lt;sequence>
+ &lt;element name="member" type="string"/>
+ &lt;/sequence>
+&lt;/complexType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class object: xml_schema::type
+{
+public:
+ typedef xml_schema::string member_type;
+
+ const member_type&amp;
+ member () const;
+
+ ...
+
+};
+ </pre>
+
+ <p>Names and semantics of type definitions for the member as well
+ as signatures of the accessor and modifier functions depend on
+ the member's cardinality class and are described in the following
+ sub-sections.
+ </p>
+
+
+ <h3><a name="2.8.1">2.8.1 Mapping for Members with the One Cardinality Class</a></h3>
+
+ <p>For the One cardinality class, the type definitions consist of
+ an alias for the member's type with the name created by appending
+ the <code>_type</code> suffix to the member's name.
+ </p>
+
+ <p>The accessor functions come in constant and non-constant versions.
+ The constant accessor function returns a constant reference to the
+ member and can be used for read-only access. The non-constant
+ version returns an unrestricted reference to the member and can
+ be used for read-write access.
+ </p>
+
+ <p>The first modifier function expects an argument of type reference to
+ constant of the member's type. It makes a deep copy of its argument.
+ Except for member's types that are mapped to fundamental C++ types,
+ the second modifier function is provided that expects an argument
+ of type automatic pointer to the member's type. It assumes ownership
+ of the pointed to object and resets the passed automatic pointer.
+ For instance:</p>
+
+ <pre class="xml">
+&lt;complexType name="object">
+ &lt;sequence>
+ &lt;element name="member" type="string"/>
+ &lt;/sequence>
+&lt;/complexType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class object: xml_schema::type
+{
+public:
+ // Type definitions.
+ //
+ typedef xml_schema::string member_type;
+
+ // Accessors.
+ //
+ const member_type&amp;
+ member () const;
+
+ member_type&amp;
+ member ();
+
+ // Modifiers.
+ //
+ void
+ member (const member_type&amp;);
+
+ void
+ member (std::auto_ptr&lt;member_type>);
+ ...
+
+};
+ </pre>
+
+
+ <p>The following code shows how one could use this mapping:</p>
+
+ <pre class="c++">
+void
+f (object&amp; o)
+{
+ using xml_schema::string;
+
+ string s (o.member ()); // get
+ object::member_type&amp; sr (o.member ()); // get
+
+ o.member ("hello"); // set, deep copy
+ o.member () = "hello"; // set, deep copy
+
+ std::auto_ptr&lt;string> p (new string ("hello"));
+ o.member (p); // set, assumes ownership
+}
+ </pre>
+
+
+<h3><a name="2.8.2">2.8.2 Mapping for Members with the Optional Cardinality Class</a></h3>
+
+ <p>For the Optional cardinality class, the type definitions consist of
+ an alias for the member's type with the name created by appending
+ the <code>_type</code> suffix to the member's name and an alias for
+ the container type with the name created by appending the
+ <code>_optional</code> suffix to the member's name.
+ </p>
+
+ <p>Unlike accessor functions for the One cardinality class, accessor
+ functions for the Optional cardinality class return references to
+ corresponding containers rather than directly to members. The
+ accessor functions come in constant and non-constant versions.
+ The constant accessor function returns a constant reference to
+ the container and can be used for read-only access. The non-constant
+ version returns an unrestricted reference to the container
+ and can be used for read-write access.
+ </p>
+
+ <p>The modifier functions are overloaded for the member's
+ type and the container type. The first modifier function
+ expects an argument of type reference to constant of the
+ member's type. It makes a deep copy of its argument.
+ Except for member's types that are mapped to fundamental C++ types,
+ the second modifier function is provided that expects an argument
+ of type automatic pointer to the member's type. It assumes ownership
+ of the pointed to object and resets the passed automatic pointer.
+ The last modifier function expects an argument of type reference
+ to constant of the container type. It makes a deep copy of its
+ argument. For instance:
+ </p>
+
+ <pre class="xml">
+&lt;complexType name="object">
+ &lt;sequence>
+ &lt;element name="member" type="string" minOccurs="0"/>
+ &lt;/sequence>
+&lt;/complexType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class object: xml_schema::type
+{
+public:
+ // Type definitions.
+ //
+ typedef xml_schema::string member_type;
+ typedef optional&lt;member_type> member_optional;
+
+ // Accessors.
+ //
+ const member_optional&amp;
+ member () const;
+
+ member_optional&amp;
+ member ();
+
+ // Modifiers.
+ //
+ void
+ member (const member_type&amp;);
+
+ void
+ member (std::auto_ptr&lt;member_type>);
+
+ void
+ member (const member_optional&amp;);
+
+ ...
+
+};
+ </pre>
+
+
+ <p>The <code>optional</code> class template is defined in an
+ implementation-specific namespace and has the following
+ interface. The <code>auto_ptr</code>-based constructor
+ and modifier function are only available if the template
+ argument is not a fundamental C++ type.
+ </p>
+
+ <pre class="c++">
+template &lt;typename X>
+class optional
+{
+public:
+ optional ();
+
+ // Makes a deep copy.
+ //
+ explicit
+ optional (const X&amp;);
+
+ // Assumes ownership.
+ //
+ explicit
+ optional (std::auto_ptr&lt;X>);
+
+ optional (const optional&amp;);
+
+public:
+ optional&amp;
+ operator= (const X&amp;);
+
+ optional&amp;
+ operator= (const optional&amp;);
+
+ // Pointer-like interface.
+ //
+public:
+ const X*
+ operator-> () const;
+
+ X*
+ operator-> ();
+
+ const X&amp;
+ operator* () const;
+
+ X&amp;
+ operator* ();
+
+ typedef void (optional::*bool_convertible) ();
+ operator bool_convertible () const;
+
+ // Get/set interface.
+ //
+public:
+ bool
+ present () const;
+
+ const X&amp;
+ get () const;
+
+ X&amp;
+ get ();
+
+ // Makes a deep copy.
+ //
+ void
+ set (const X&amp;);
+
+ // Assumes ownership.
+ //
+ void
+ set (std::auto_ptr&lt;X>);
+
+ void
+ reset ();
+};
+
+template &lt;typename X>
+bool
+operator== (const optional&lt;X>&amp;, const optional&lt;X>&amp;);
+
+template &lt;typename X>
+bool
+operator!= (const optional&lt;X>&amp;, const optional&lt;X>&amp;);
+
+template &lt;typename X>
+bool
+operator&lt; (const optional&lt;X>&amp;, const optional&lt;X>&amp;);
+
+template &lt;typename X>
+bool
+operator> (const optional&lt;X>&amp;, const optional&lt;X>&amp;);
+
+template &lt;typename X>
+bool
+operator&lt;= (const optional&lt;X>&amp;, const optional&lt;X>&amp;);
+
+template &lt;typename X>
+bool
+operator>= (const optional&lt;X>&amp;, const optional&lt;X>&amp;);
+ </pre>
+
+
+ <p>The following code shows how one could use this mapping:</p>
+
+ <pre class="c++">
+void
+f (object&amp; o)
+{
+ using xml_schema::string;
+
+ if (o.member ().present ()) // test
+ {
+ string&amp; s (o.member ().get ()); // get
+ o.member ("hello"); // set, deep copy
+ o.member ().set ("hello"); // set, deep copy
+ o.member ().reset (); // reset
+ }
+
+ // Same as above but using pointer notation:
+ //
+ if (o.member ()) // test
+ {
+ string&amp; s (*o.member ()); // get
+ o.member ("hello"); // set, deep copy
+ *o.member () = "hello"; // set, deep copy
+ o.member ().reset (); // reset
+ }
+
+ std::auto_ptr&lt;string> p (new string ("hello"));
+ o.member (p); // set, assumes ownership
+
+ p = new string ("hello");
+ o.member ().set (p); // set, assumes ownership
+}
+ </pre>
+
+
+ <h3><a name="2.8.3">2.8.3 Mapping for Members with the Sequence Cardinality Class</a></h3>
+
+ <p>For the Sequence cardinality class, the type definitions consist of an
+ alias for the member's type with the name created by appending
+ the <code>_type</code> suffix to the member's name, an alias of
+ the container type with the name created by appending the
+ <code>_sequence</code> suffix to the member's name, an alias of
+ the iterator type with the name created by appending the
+ <code>_iterator</code> suffix to the member's name, and an alias
+ of the constant iterator type with the name created by appending the
+ <code>_const_iterator</code> suffix to the member's name.
+ </p>
+
+ <p>The accessor functions come in constant and non-constant versions.
+ The constant accessor function returns a constant reference to the
+ container and can be used for read-only access. The non-constant
+ version returns an unrestricted reference to the container and can
+ be used for read-write access.
+ </p>
+
+ <p>The modifier function expects an argument of type reference to
+ constant of the container type. The modifier function
+ makes a deep copy of its argument. For instance:
+ </p>
+
+
+ <pre class="xml">
+&lt;complexType name="object">
+ &lt;sequence>
+ &lt;element name="member" type="string" minOccurs="unbounded"/>
+ &lt;/sequence>
+&lt;/complexType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class object: xml_schema::type
+{
+public:
+ // Type definitions.
+ //
+ typedef xml_schema::string member_type;
+ typedef sequence&lt;member_type> member_sequence;
+ typedef member_sequence::iterator member_iterator;
+ typedef member_sequence::const_iterator member_const_iterator;
+
+ // Accessors.
+ //
+ const member_sequence&amp;
+ member () const;
+
+ member_sequence&amp;
+ member ();
+
+ // Modifier.
+ //
+ void
+ member (const member_sequence&amp;);
+
+ ...
+
+};
+ </pre>
+
+ <p>The <code>sequence</code> class template is defined in an
+ implementation-specific namespace. It conforms to the
+ sequence interface as defined by the ISO/ANSI Standard for
+ C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences").
+ Practically, this means that you can treat such a sequence
+ as if it was <code>std::vector</code>. One notable extension
+ to the standard interface that is available only for
+ sequences of non-fundamental C++ types is the addition of
+ the overloaded <code>push_back</code> and <code>insert</code>
+ member functions which instead of the constant reference
+ to the element type accept automatic pointer to the element
+ type. These functions assume ownership of the pointed to
+ object and resets the passed automatic pointer.
+ </p>
+
+ <p>The following code shows how one could use this mapping:</p>
+
+ <pre class="c++">
+void
+f (object&amp; o)
+{
+ using xml_schema::string;
+
+ object::member_sequence&amp; s (o.member ());
+
+ // Iteration.
+ //
+ for (object::member_iterator i (s.begin ()); i != s.end (); ++i)
+ {
+ string&amp; value (*i);
+ }
+
+ // Modification.
+ //
+ s.push_back ("hello"); // deep copy
+
+ std::auto_ptr&lt;string> p (new string ("hello"));
+ s.push_back (o); // assumes ownership
+
+ // Setting a new container.
+ //
+ object::member_sequence n;
+ n.push_back ("one");
+ n.push_back ("two");
+ o.member (n); // deep copy
+}
+ </pre>
+
+ <h2><a name="2.9">2.9 Mapping for Global Elements</a></h2>
+
+ <p>An XML Schema element definition is called global if it appears
+ directly under the <code>schema</code> element.
+ A global element is a valid root of an instance document. By
+ default, a global element is mapped to a set of overloaded
+ parsing and, optionally, serialization functions with the
+ same name as the element. It is also possible to generate types
+ for root elements instead of parsing and serialization functions.
+ This is primarily useful to distinguish object models with the
+ same root type but with different root elements. See
+ <a href="#2.9.1">Section 2.9.1, "Element Types"</a> for details.
+ It is also possible to request the generation of an element map
+ which allows uniform parsing and serialization of multiple root
+ elements. See <a href="#2.9.2">Section 2.9.2, "Element Map"</a>
+ for details.
+ </p>
+
+ <p>The parsing functions read XML instance documents and return
+ corresponding object models. Their signatures
+ have the following pattern (<code>type</code> denotes
+ element's type and <code>name</code> denotes element's
+ name):
+ </p>
+
+ <pre class="c++">
+std::auto_ptr&lt;type>
+name (....);
+ </pre>
+
+ <p>The process of parsing, including the exact signatures of the parsing
+ functions, is the subject of <a href="#3">Chapter 3, "Parsing"</a>.
+ </p>
+
+ <p>The serialization functions write object models
+ back to XML instance documents. Their signatures
+ have the following pattern:
+ </p>
+
+ <pre class="c++">
+void
+name (&lt;stream type>&amp;, const type&amp;, ....);
+ </pre>
+
+ <p>The process of serialization, including the exact signatures of the
+ serialization functions, is the subject of <a href="#4">Chapter 4,
+ "Serialization"</a>.
+ </p>
+
+
+ <h3><a name="2.9.1">2.9.1 Element Types</a></h3>
+
+ <p>The generation of element types is requested with the
+ <code>--generate-element-map</code> option. With this option
+ each global element is mapped to a C++ class with the
+ same name as the element. Such a class is derived from
+ <code>xml_schema::element_type</code> and contains the same set
+ of type definitions, constructors, and member function as would a
+ type containing a single element with the One cardinality class
+ named <code>"value"</code>. In addition, the element type also
+ contains a set of member functions for accessing the element
+ name and namespace as well as its value in a uniform manner.
+ For example:</p>
+
+ <pre class="xml">
+&lt;complexType name="type">
+ &lt;sequence>
+ ...
+ &lt;/sequence>
+&lt;/complexType>
+
+&lt;element name="root" type="type"/>
+ </pre>
+
+<p>is mapped to:</p>
+
+ <pre class="c++">
+class type
+{
+ ...
+};
+
+class root: public xml_schema::element_type
+{
+public:
+ // Element value.
+ //
+ typedef type value_type;
+
+ const value_type&amp;
+ value () const;
+
+ value_type&amp;
+ value ();
+
+ void
+ value (const value_type&amp;);
+
+ void
+ value (std::auto_ptr&lt;value_type>);
+
+ // Constructors.
+ //
+ root (const value_type&amp;);
+
+ root (std::auto_ptr&lt;value_type>);
+
+ root (const xercesc::DOMElement&amp;, xml_schema::flags = 0);
+
+ root (const root&amp;, xml_schema::flags = 0);
+
+ virtual root*
+ _clone (xml_schema::flags = 0) const;
+
+ // Element name and namespace.
+ //
+ static const std::string&amp;
+ name ();
+
+ static const std::string&amp;
+ namespace_ ();
+
+ virtual const std::string&amp;
+ _name () const;
+
+ virtual const std::string&amp;
+ _namespace () const;
+
+ // Element value as xml_schema::type.
+ //
+ virtual const xml_schema::type*
+ _value () const;
+
+ virtual xml_schema::type*
+ _value ();
+};
+
+void
+operator&lt;&lt; (xercesc::DOMElement&amp;, const root&amp;);
+ </pre>
+
+ <p>The <code>xml_schema::element_type</code> class is a common
+ base type for all element types and is defined as follows:</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class element_type
+ {
+ public:
+ virtual
+ ~element_type ();
+
+ virtual element_type*
+ _clone (flags f = 0) const = 0;
+
+ virtual const std::basic_string&lt;C>&amp;
+ _name () const = 0;
+
+ virtual const std::basic_string&lt;C>&amp;
+ _namespace () const = 0;
+
+ virtual xml_schema::type*
+ _value () = 0;
+
+ virtual const xml_schema::type*
+ _value () const = 0;
+ };
+}
+ </pre>
+
+ <p>The <code>_value()</code> member function returns a pointer to
+ the element value or 0 if the element is of a fundamental C++
+ type and therefore is not derived from <code>xml_schema::type</code>.
+ </p>
+
+ <p>Unlike parsing and serialization functions, element types
+ are only capable of parsing and serializing from/to a
+ <code>DOMElement</code> object. This means that the application
+ will need to perform its own XML-to-DOM parsing and DOM-to-XML
+ serialization. The following section describes a mechanism
+ provided by the mapping to uniformly parse and serialize
+ multiple root elements.</p>
+
+
+ <h3><a name="2.9.2">2.9.2 Element Map</a></h3>
+
+ <p>When element types are generated for root elements it is also
+ possible to request the generation of an element map with the
+ <code>--generate-element-map</code> option. The element map
+ allows uniform parsing and serialization of multiple root
+ elements via the common <code>xml_schema::element_type</code>
+ base type. The <code>xml_schema::element_map</code> class is
+ defined as follows:</p>
+
+ <pre class="c++">
+namespace xml_schema
+{
+ class element_map
+ {
+ public:
+ static std::auto_ptr&lt;xml_schema::element_type>
+ parse (const xercesc::DOMElement&amp;, flags = 0);
+
+ static void
+ serialize (xercesc::DOMElement&amp;, const element_type&amp;);
+ };
+}
+ </pre>
+
+ <p>The <code>parse()</code> function creates the corresponding
+ element type object based on the element name and namespace
+ and returns it as a pointer to <code>xml_schema::element_type</code>.
+ The <code>serialize()</code> function serializes the passed element
+ object to <code>DOMElement</code>. Note that in case of
+ <code>serialize()</code>, the <code>DOMElement</code> object
+ should have the correct name and namespace. If no element type is
+ available for an element, both functions throw the
+ <code>xml_schema::no_element_info</code> exception:</p>
+
+ <pre class="c++">
+struct no_element_info: virtual exception
+{
+ no_element_info (const std::basic_string&lt;C>&amp; element_name,
+ const std::basic_string&lt;C>&amp; element_namespace);
+
+ const std::basic_string&lt;C>&amp;
+ element_name () const;
+
+ const std::basic_string&lt;C>&amp;
+ element_namespace () const;
+
+ virtual const char*
+ what () const throw ();
+};
+ </pre>
+
+ <p>The application can discover the actual type of the element
+ object returned by <code>parse()</code> either using
+ <code>dynamic_cast</code> or by comparing element names and
+ namespaces. The following code fragments illustrate how the
+ element map can be used:</p>
+
+ <pre class="c++">
+// Parsing.
+//
+DOMElement&amp; e = ... // Parse XML to DOM.
+
+auto_ptr&lt;xml_schema::element_type> r (
+ xml_schema::element_map::parse (e));
+
+if (root1 r1 = dynamic_cast&lt;root1*> (r.get ()))
+{
+ ...
+}
+else if (r->_name == root2::name () &amp;&amp;
+ r->_namespace () == root2::namespace_ ())
+{
+ root2&amp; r2 (static_cast&lt;root2&amp;> (*r));
+
+ ...
+}
+ </pre>
+
+ <pre class="c++">
+// Serialization.
+//
+xml_schema::element_type&amp; r = ...
+
+string name (r._name ());
+string ns (r._namespace ());
+
+DOMDocument&amp; doc = ... // Create a new DOMDocument with name and ns.
+DOMElement&amp; e (*doc->getDocumentElement ());
+
+xml_schema::element_map::serialize (e, r);
+
+// Serialize DOMDocument to XML.
+ </pre>
+
+ <!-- -->
+
+ <h2><a name="2.10">2.10 Mapping for Global Attributes</a></h2>
+
+ <p>An XML Schema attribute definition is called global if it appears
+ directly under the <code>schema</code> element. A global
+ attribute does not have any mapping.
+ </p>
+
+ <!--
+ When it is referenced from
+ a local attribute definition (using the <code>ref</code> attribute)
+ it is treated as a local attribute (see Section 2.8, "Mapping for
+ Local Elements and Attributes").
+ -->
+
+ <h2><a name="2.11">2.11 Mapping for <code>xsi:type</code> and Substitution
+ Groups</a></h2>
+
+ <p>The mapping provides optional support for the XML Schema polymorphism
+ features (<code>xsi:type</code> and substitution groups) which can
+ be requested with the <code>--generate-polymorphic</code> option.
+ When used, the dynamic type of a member may be different from
+ its static type. Consider the following schema definition and
+ instance document:
+ </p>
+
+ <pre class="xml">
+&lt;!-- test.xsd -->
+&lt;schema>
+ &lt;complexType name="base">
+ &lt;attribute name="text" type="string"/>
+ &lt;/complexType>
+
+ &lt;complexType name="derived">
+ &lt;complexContent>
+ &lt;extension base="base">
+ &lt;attribute name="extra-text" type="string"/>
+ &lt;/extension>
+ &lt;/complexContent>
+ &lt;/complexType>
+
+ &lt;complexType name="root_type">
+ &lt;sequence>
+ &lt;element name="item" type="base" maxOccurs="unbounded"/>
+ &lt;/sequence>
+ &lt;/complexType>
+
+ &lt;element name="root" type="root_type"/>
+&lt;/schema>
+
+&lt;!-- test.xml -->
+&lt;root xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ &lt;item text="hello"/>
+ &lt;item text="hello" extra-text="world" xsi:type="derived"/>
+&lt;/root>
+ </pre>
+
+ <p>In the resulting object model, the container for
+ the <code>root::item</code> member will have two elements:
+ the first element's type will be <code>base</code> while
+ the second element's (dynamic) type will be
+ <code>derived</code>. This can be discovered using the
+ <code>dynamic_cast</code> operator as shown in the following
+ example:
+ </p>
+
+ <pre class="c++">
+void
+f (root&amp; r)
+{
+ for (root::item_const_iterator i (r.item ().begin ());
+ i != r.item ().end ()
+ ++i)
+ {
+ if (derived* d = dynamic_cast&lt;derived*> (&amp;(*i)))
+ {
+ // derived
+ }
+ else
+ {
+ // base
+ }
+ }
+}
+ </pre>
+
+ <p>The <code>_clone</code> virtual function should be used instead of
+ copy constructors to make copies of members that might use
+ polymorphism:
+ </p>
+
+ <pre class="c++">
+void
+f (root&amp; r)
+{
+ for (root::item_const_iterator i (r.item ().begin ());
+ i != r.item ().end ()
+ ++i)
+ {
+ std::auto_ptr&lt;base> c (i->_clone ());
+ }
+}
+ </pre>
+
+
+ <!-- Mapping for any and anyAttribute -->
+
+
+ <h2><a name="2.12">2.12 Mapping for <code>any</code> and <code>anyAttribute</code></a></h2>
+
+ <p>For the XML Schema <code>any</code> and <code>anyAttribute</code>
+ wildcards an optional mapping can be requested with the
+ <code>--generate-wildcard</code> option. The mapping represents
+ the content matched by wildcards as DOM fragments. Because the
+ DOM API is used to access such content, the Xerces-C++ runtime
+ should be initialized by the application prior to parsing and
+ should remain initialized for the lifetime of objects with
+ the wildcard content. For more information on the Xerces-C++
+ runtime initialization see <a href="#3.1">Section 3.1,
+ "Initializing the Xerces-C++ Runtime"</a>.
+ </p>
+
+ <p>The mapping for <code>any</code> is similar to the mapping for
+ local elements (see <a href="#2.8">Section 2.8, "Mapping for Local
+ Elements and Attributes"</a>) except that the type used in the
+ wildcard mapping is <code>xercesc::DOMElement</code>. As with local
+ elements, the mapping divides all possible cardinality combinations
+ into three cardinality classes: <i>one</i>, <i>optional</i>, and
+ <i>sequence</i>.
+ </p>
+
+ <p>The mapping for <code>anyAttribute</code> represents the attributes
+ matched by this wildcard as a set of <code>xercesc::DOMAttr</code>
+ objects with a key being the attribute's name and namespace.</p>
+
+ <p>Similar to local elements and attributes, the <code>any</code> and
+ <code>anyAttribute</code> wildcards are mapped to a set of public type
+ definitions (typedefs) and a set of public accessor and modifier
+ functions. Type definitions have names derived from <code>"any"</code>
+ for the <code>any</code> wildcard and <code>"any_attribute"</code>
+ for the <code>anyAttribute</code> wildcard. The accessor and modifier
+ functions are named <code>"any"</code> for the <code>any</code> wildcard
+ and <code>"any_attribute"</code> for the <code>anyAttribute</code>
+ wildcard. Subsequent wildcards in the same type have escaped names
+ such as <code>"any1"</code> or <code>"any_attribute1"</code>.
+ </p>
+
+ <p>Because Xerces-C++ DOM nodes always belong to a <code>DOMDocument</code>,
+ each type with a wildcard has an associated <code>DOMDocument</code>
+ object. The reference to this object can be obtained using the accessor
+ function called <code>dom_document</code>. The access to the document
+ object from the application code may be necessary to create or modify
+ the wildcard content. For example:
+ </p>
+
+ <pre class="xml">
+&lt;complexType name="object">
+ &lt;sequence>
+ &lt;any namespace="##other"/>
+ &lt;/sequence>
+ &lt;anyAttribute namespace="##other"/>
+&lt;/complexType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class object: xml_schema::type
+{
+public:
+ // any
+ //
+ const xercesc::DOMElement&amp;
+ any () const;
+
+ void
+ any (const xercesc::DOMElement&amp;);
+
+ ...
+
+ // any_attribute
+ //
+ typedef attribute_set any_attribute_set;
+ typedef any_attribute_set::iterator any_attribute_iterator;
+ typedef any_attribute_set::const_iterator any_attribute_const_iterator;
+
+ const any_attribute_set&amp;
+ any_attribute () const;
+
+ any_attribute_set&amp;
+ any_attribute ();
+
+ ...
+
+ // DOMDocument object for wildcard content.
+ //
+ const xercesc::DOMDocument&amp;
+ dom_document () const;
+
+ xercesc::DOMDocument&amp;
+ dom_document ();
+
+ ...
+};
+ </pre>
+
+
+ <p>Names and semantics of type definitions for the wildcards as well
+ as signatures of the accessor and modifier functions depend on the
+ wildcard type as well as the cardinality class for the <code>any</code>
+ wildcard. They are described in the following sub-sections.
+ </p>
+
+
+ <h3><a name="2.12.1">2.12.1 Mapping for <code>any</code> with the One Cardinality Class</a></h3>
+
+ <p>For <code>any</code> with the One cardinality class,
+ there are no type definitions. The accessor functions come in
+ constant and non-constant versions. The constant accessor function
+ returns a constant reference to <code>xercesc::DOMElement</code> and
+ can be used for read-only access. The non-constant version returns
+ an unrestricted reference to <code>xercesc::DOMElement</code> and can
+ be used for read-write access.
+ </p>
+
+ <p>The first modifier function expects an argument of type reference
+ to constant <code>xercesc::DOMElement</code> and makes a deep copy
+ of its argument. The second modifier function expects an argument of
+ type pointer to <code>xercesc::DOMElement</code>. This modifier
+ function assumes ownership of its argument and expects the element
+ object to be created using the DOM document associated with this
+ instance. For example:
+ </p>
+
+ <pre class="xml">
+&lt;complexType name="object">
+ &lt;sequence>
+ &lt;any namespace="##other"/>
+ &lt;/sequence>
+&lt;/complexType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class object: xml_schema::type
+{
+public:
+ // Accessors.
+ //
+ const xercesc::DOMElement&amp;
+ any () const;
+
+ xercesc::DOMElement&amp;
+ any ();
+
+ // Modifiers.
+ //
+ void
+ any (const xercesc::DOMElement&amp;);
+
+ void
+ any (xercesc::DOMElement*);
+
+ ...
+
+};
+ </pre>
+
+
+ <p>The following code shows how one could use this mapping:</p>
+
+ <pre class="c++">
+void
+f (object&amp; o, const xercesc::DOMElement&amp; e)
+{
+ using namespace xercesc;
+
+ DOMElement&amp; e1 (o.any ()); // get
+ o.any (e) // set, deep copy
+ DOMDocument&amp; doc (o.dom_document ());
+ o.any (doc.createElement (...)); // set, assumes ownership
+}
+ </pre>
+
+ <h3><a name="2.12.2">2.12.2 Mapping for <code>any</code> with the Optional Cardinality Class</a></h3>
+
+ <p>For <code>any</code> with the Optional cardinality class, the type
+ definitions consist of an alias for the container type with name
+ <code>any_optional</code> (or <code>any1_optional</code>, etc., for
+ subsequent wildcards in the type definition).
+ </p>
+
+ <p>Unlike accessor functions for the One cardinality class, accessor
+ functions for the Optional cardinality class return references to
+ corresponding containers rather than directly to <code>DOMElement</code>.
+ The accessor functions come in constant and non-constant versions.
+ The constant accessor function returns a constant reference to
+ the container and can be used for read-only access. The non-constant
+ version returns an unrestricted reference to the container
+ and can be used for read-write access.
+ </p>
+
+ <p>The modifier functions are overloaded for <code>xercesc::DOMElement</code>
+ and the container type. The first modifier function expects an argument of
+ type reference to constant <code>xercesc::DOMElement</code> and
+ makes a deep copy of its argument. The second modifier function
+ expects an argument of type pointer to <code>xercesc::DOMElement</code>.
+ This modifier function assumes ownership of its argument and expects
+ the element object to be created using the DOM document associated
+ with this instance. The third modifier function expects an argument
+ of type reference to constant of the container type and makes a
+ deep copy of its argument. For instance:
+ </p>
+
+ <pre class="xml">
+&lt;complexType name="object">
+ &lt;sequence>
+ &lt;any namespace="##other" minOccurs="0"/>
+ &lt;/sequence>
+&lt;/complexType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class object: xml_schema::type
+{
+public:
+ // Type definitions.
+ //
+ typedef element_optional any_optional;
+
+ // Accessors.
+ //
+ const any_optional&amp;
+ any () const;
+
+ any_optional&amp;
+ any ();
+
+ // Modifiers.
+ //
+ void
+ any (const xercesc::DOMElement&amp;);
+
+ void
+ any (xercesc::DOMElement*);
+
+ void
+ any (const any_optional&amp;);
+
+ ...
+
+};
+ </pre>
+
+
+ <p>The <code>element_optional</code> container is a
+ specialization of the <code>optional</code> class template described
+ in <a href="#2.8.2">Section 2.8.2, "Mapping for Members with the Optional
+ Cardinality Class"</a>. Its interface is presented below:
+ </p>
+
+ <pre class="c++">
+class element_optional
+{
+public:
+ explicit
+ element_optional (xercesc::DOMDocument&amp;);
+
+ // Makes a deep copy.
+ //
+ element_optional (const xercesc::DOMElement&amp;, xercesc::DOMDocument&amp;);
+
+ // Assumes ownership.
+ //
+ element_optional (xercesc::DOMElement*, xercesc::DOMDocument&amp;);
+
+ element_optional (const element_optional&amp;, xercesc::DOMDocument&amp;);
+
+public:
+ element_optional&amp;
+ operator= (const xercesc::DOMElement&amp;);
+
+ element_optional&amp;
+ operator= (const element_optional&amp;);
+
+ // Pointer-like interface.
+ //
+public:
+ const xercesc::DOMElement*
+ operator-> () const;
+
+ xercesc::DOMElement*
+ operator-> ();
+
+ const xercesc::DOMElement&amp;
+ operator* () const;
+
+ xercesc::DOMElement&amp;
+ operator* ();
+
+ typedef void (element_optional::*bool_convertible) ();
+ operator bool_convertible () const;
+
+ // Get/set interface.
+ //
+public:
+ bool
+ present () const;
+
+ const xercesc::DOMElement&amp;
+ get () const;
+
+ xercesc::DOMElement&amp;
+ get ();
+
+ // Makes a deep copy.
+ //
+ void
+ set (const xercesc::DOMElement&amp;);
+
+ // Assumes ownership.
+ //
+ void
+ set (xercesc::DOMElement*);
+
+ void
+ reset ();
+};
+
+bool
+operator== (const element_optional&amp;, const element_optional&amp;);
+
+bool
+operator!= (const element_optional&amp;, const element_optional&amp;);
+ </pre>
+
+
+ <p>The following code shows how one could use this mapping:</p>
+
+ <pre class="c++">
+void
+f (object&amp; o, const xercesc::DOMElement&amp; e)
+{
+ using namespace xercesc;
+
+ DOMDocument&amp; doc (o.dom_document ());
+
+ if (o.any ().present ()) // test
+ {
+ DOMElement&amp; e1 (o.any ().get ()); // get
+ o.any ().set (e); // set, deep copy
+ o.any ().set (doc.createElement (...)); // set, assumes ownership
+ o.any ().reset (); // reset
+ }
+
+ // Same as above but using pointer notation:
+ //
+ if (o.member ()) // test
+ {
+ DOMElement&amp; e1 (*o.any ()); // get
+ o.any (e); // set, deep copy
+ o.any (doc.createElement (...)); // set, assumes ownership
+ o.any ().reset (); // reset
+ }
+}
+ </pre>
+
+
+
+ <h3><a name="2.12.3">2.12.3 Mapping for <code>any</code> with the Sequence Cardinality Class</a></h3>
+
+ <p>For <code>any</code> with the Sequence cardinality class, the type
+ definitions consist of an alias of the container type with name
+ <code>any_sequence</code> (or <code>any1_sequence</code>, etc., for
+ subsequent wildcards in the type definition), an alias of the iterator
+ type with name <code>any_iterator</code> (or <code>any1_iterator</code>,
+ etc., for subsequent wildcards in the type definition), and an alias
+ of the constant iterator type with name <code>any_const_iterator</code>
+ (or <code>any1_const_iterator</code>, etc., for subsequent wildcards
+ in the type definition).
+ </p>
+
+ <p>The accessor functions come in constant and non-constant versions.
+ The constant accessor function returns a constant reference to the
+ container and can be used for read-only access. The non-constant
+ version returns an unrestricted reference to the container and can
+ be used for read-write access.
+ </p>
+
+ <p>The modifier function expects an argument of type reference to
+ constant of the container type. The modifier function makes
+ a deep copy of its argument. For instance:
+ </p>
+
+
+ <pre class="xml">
+&lt;complexType name="object">
+ &lt;sequence>
+ &lt;any namespace="##other" minOccurs="unbounded"/>
+ &lt;/sequence>
+&lt;/complexType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class object: xml_schema::type
+{
+public:
+ // Type definitions.
+ //
+ typedef element_sequence any_sequence;
+ typedef any_sequence::iterator any_iterator;
+ typedef any_sequence::const_iterator any_const_iterator;
+
+ // Accessors.
+ //
+ const any_sequence&amp;
+ any () const;
+
+ any_sequence&amp;
+ any ();
+
+ // Modifier.
+ //
+ void
+ any (const any_sequence&amp;);
+
+ ...
+
+};
+ </pre>
+
+ <p>The <code>element_sequence</code> container is a
+ specialization of the <code>sequence</code> class template described
+ in <a href="#2.8.3">Section 2.8.3, "Mapping for Members with the
+ Sequence Cardinality Class"</a>. Its interface is similar to
+ the sequence interface as defined by the ISO/ANSI Standard for
+ C++ (ISO/IEC 14882:1998, Section 23.1.1, "Sequences") and is
+ presented below:
+ </p>
+
+ <pre class="c++">
+class element_sequence
+{
+public:
+ typedef xercesc::DOMElement value_type;
+ typedef xercesc::DOMElement* pointer;
+ typedef const xercesc::DOMElement* const_pointer;
+ typedef xercesc::DOMElement&amp; reference;
+ typedef const xercesc::DOMElement&amp; const_reference;
+
+ typedef &lt;implementation-defined> iterator;
+ typedef &lt;implementation-defined> const_iterator;
+ typedef &lt;implementation-defined> reverse_iterator;
+ typedef &lt;implementation-defined> const_reverse_iterator;
+
+ typedef &lt;implementation-defined> size_type;
+ typedef &lt;implementation-defined> difference_type;
+ typedef &lt;implementation-defined> allocator_type;
+
+public:
+ explicit
+ element_sequence (xercesc::DOMDocument&amp;);
+
+ // DOMElement cannot be default-constructed.
+ //
+ // explicit
+ // element_sequence (size_type n);
+
+ element_sequence (size_type n,
+ const xercesc::DOMElement&amp;,
+ xercesc::DOMDocument&amp;);
+
+ template &lt;typename I>
+ element_sequence (const I&amp; begin,
+ const I&amp; end,
+ xercesc::DOMDocument&amp;);
+
+ element_sequence (const element_sequence&amp;, xercesc::DOMDocument&amp;);
+
+ element_sequence&amp;
+ operator= (const element_sequence&amp;);
+
+public:
+ void
+ assign (size_type n, const xercesc::DOMElement&amp;);
+
+ template &lt;typename I>
+ void
+ assign (const I&amp; begin, const I&amp; end);
+
+public:
+ // This version of resize can only be used to shrink the
+ // sequence because DOMElement cannot be default-constructed.
+ //
+ void
+ resize (size_type);
+
+ void
+ resize (size_type, const xercesc::DOMElement&amp;);
+
+public:
+ size_type
+ size () const;
+
+ size_type
+ max_size () const;
+
+ size_type
+ capacity () const;
+
+ bool
+ empty () const;
+
+ void
+ reserve (size_type);
+
+ void
+ clear ();
+
+public:
+ const_iterator
+ begin () const;
+
+ const_iterator
+ end () const;
+
+ iterator
+ begin ();
+
+ iterator
+ end ();
+
+ const_reverse_iterator
+ rbegin () const;
+
+ const_reverse_iterator
+ rend () const
+
+ reverse_iterator
+ rbegin ();
+
+ reverse_iterator
+ rend ();
+
+public:
+ xercesc::DOMElement&amp;
+ operator[] (size_type);
+
+ const xercesc::DOMElement&amp;
+ operator[] (size_type) const;
+
+ xercesc::DOMElement&amp;
+ at (size_type);
+
+ const xercesc::DOMElement&amp;
+ at (size_type) const;
+
+ xercesc::DOMElement&amp;
+ front ();
+
+ const xercesc::DOMElement&amp;
+ front () const;
+
+ xercesc::DOMElement&amp;
+ back ();
+
+ const xercesc::DOMElement&amp;
+ back () const;
+
+public:
+ // Makes a deep copy.
+ //
+ void
+ push_back (const xercesc::DOMElement&amp;);
+
+ // Assumes ownership.
+ //
+ void
+ push_back (xercesc::DOMElement*);
+
+ void
+ pop_back ();
+
+ // Makes a deep copy.
+ //
+ iterator
+ insert (iterator position, const xercesc::DOMElement&amp;);
+
+ // Assumes ownership.
+ //
+ iterator
+ insert (iterator position, xercesc::DOMElement*);
+
+ void
+ insert (iterator position, size_type n, const xercesc::DOMElement&amp;);
+
+ template &lt;typename I>
+ void
+ insert (iterator position, const I&amp; begin, const I&amp; end);
+
+ iterator
+ erase (iterator position);
+
+ iterator
+ erase (iterator begin, iterator end);
+
+public:
+ // Note that the DOMDocument object of the two sequences being
+ // swapped should be the same.
+ //
+ void
+ swap (sequence&amp; x);
+};
+
+inline bool
+operator== (const element_sequence&amp;, const element_sequence&amp;);
+
+inline bool
+operator!= (const element_sequence&amp;, const element_sequence&amp;);
+ </pre>
+
+
+ <p>The following code shows how one could use this mapping:</p>
+
+ <pre class="c++">
+void
+f (object&amp; o, const xercesc::DOMElement&amp; e)
+{
+ using namespace xercesc;
+
+ object::any_sequence&amp; s (o.any ());
+
+ // Iteration.
+ //
+ for (object::any_iterator i (s.begin ()); i != s.end (); ++i)
+ {
+ DOMElement&amp; e (*i);
+ }
+
+ // Modification.
+ //
+ s.push_back (e); // deep copy
+ DOMDocument&amp; doc (o.dom_document ());
+ s.push_back (doc.createElement (...)); // assumes ownership
+}
+ </pre>
+
+
+ <h3><a name="2.12.4">2.12.4 Mapping for <code>anyAttribute</code></a></h3>
+
+ <p>For <code>anyAttribute</code> the type definitions consist of an alias
+ of the container type with name <code>any_attribute_set</code>
+ (or <code>any1_attribute_set</code>, etc., for subsequent wildcards
+ in the type definition), an alias of the iterator type with name
+ <code>any_attribute_iterator</code> (or <code>any1_attribute_iterator</code>,
+ etc., for subsequent wildcards in the type definition), and an alias
+ of the constant iterator type with name <code>any_attribute_const_iterator</code>
+ (or <code>any1_attribute_const_iterator</code>, etc., for subsequent
+ wildcards in the type definition).
+ </p>
+
+ <p>The accessor functions come in constant and non-constant versions.
+ The constant accessor function returns a constant reference to the
+ container and can be used for read-only access. The non-constant
+ version returns an unrestricted reference to the container and can
+ be used for read-write access.
+ </p>
+
+ <p>The modifier function expects an argument of type reference to
+ constant of the container type. The modifier function makes
+ a deep copy of its argument. For instance:
+ </p>
+
+
+ <pre class="xml">
+&lt;complexType name="object">
+ &lt;sequence>
+ ...
+ &lt;/sequence>
+ &lt;anyAttribute namespace="##other"/>
+&lt;/complexType>
+ </pre>
+
+ <p>is mapped to:</p>
+
+ <pre class="c++">
+class object: xml_schema::type
+{
+public:
+ // Type definitions.
+ //
+ typedef attribute_set any_attribute_set;
+ typedef any_attribute_set::iterator any_attribute_iterator;
+ typedef any_attribute_set::const_iterator any_attribute_const_iterator;
+
+ // Accessors.
+ //
+ const any_attribute_set&amp;
+ any_attribute () const;
+
+ any_attribute_set&amp;
+ any_attribute ();
+
+ // Modifier.
+ //
+ void
+ any_attribute (const any_attribute_set&amp;);
+
+ ...
+
+};
+ </pre>
+
+ <p>The <code>attribute_set</code> class is an associative container
+ similar to the <code>std::set</code> class template as defined by
+ the ISO/ANSI Standard for C++ (ISO/IEC 14882:1998, Section 23.3.3,
+ "Class template set") with the key being the attribute's name
+ and namespace. Unlike <code>std::set</code>, <code>attribute_set</code>
+ allows searching using names and namespaces instead of
+ <code>xercesc::DOMAttr</code> objects. It is defined in an
+ implementation-specific namespace and its interface is presented
+ below:
+ </p>
+
+ <pre class="c++">
+class attribute_set
+{
+public:
+ typedef xercesc::DOMAttr key_type;
+ typedef xercesc::DOMAttr value_type;
+ typedef xercesc::DOMAttr* pointer;
+ typedef const xercesc::DOMAttr* const_pointer;
+ typedef xercesc::DOMAttr&amp; reference;
+ typedef const xercesc::DOMAttr&amp; const_reference;
+
+ typedef &lt;implementation-defined> iterator;
+ typedef &lt;implementation-defined> const_iterator;
+ typedef &lt;implementation-defined> reverse_iterator;
+ typedef &lt;implementation-defined> const_reverse_iterator;
+
+ typedef &lt;implementation-defined> size_type;
+ typedef &lt;implementation-defined> difference_type;
+ typedef &lt;implementation-defined> allocator_type;
+
+public:
+ attribute_set (xercesc::DOMDocument&amp;);
+
+ template &lt;typename I>
+ attribute_set (const I&amp; begin, const I&amp; end, xercesc::DOMDocument&amp;);
+
+ attribute_set (const attribute_set&amp;, xercesc::DOMDocument&amp;);
+
+ attribute_set&amp;
+ operator= (const attribute_set&amp;);
+
+public:
+ const_iterator
+ begin () const;
+
+ const_iterator
+ end () const;
+
+ iterator
+ begin ();
+
+ iterator
+ end ();
+
+ const_reverse_iterator
+ rbegin () const;
+
+ const_reverse_iterator
+ rend () const;
+
+ reverse_iterator
+ rbegin ();
+
+ reverse_iterator
+ rend ();
+
+public:
+ size_type
+ size () const;
+
+ size_type
+ max_size () const;
+
+ bool
+ empty () const;
+
+ void
+ clear ();
+
+public:
+ // Makes a deep copy.
+ //
+ std::pair&lt;iterator, bool>
+ insert (const xercesc::DOMAttr&amp;);
+
+ // Assumes ownership.
+ //
+ std::pair&lt;iterator, bool>
+ insert (xercesc::DOMAttr*);
+
+ // Makes a deep copy.
+ //
+ iterator
+ insert (iterator position, const xercesc::DOMAttr&amp;);
+
+ // Assumes ownership.
+ //
+ iterator
+ insert (iterator position, xercesc::DOMAttr*);
+
+ template &lt;typename I>
+ void
+ insert (const I&amp; begin, const I&amp; end);
+
+public:
+ void
+ erase (iterator position);
+
+ size_type
+ erase (const std::basic_string&lt;C>&amp; name);
+
+ size_type
+ erase (const std::basic_string&lt;C>&amp; namespace_,
+ const std::basic_string&lt;C>&amp; name);
+
+ size_type
+ erase (const XMLCh* name);
+
+ size_type
+ erase (const XMLCh* namespace_, const XMLCh* name);
+
+ void
+ erase (iterator begin, iterator end);
+
+public:
+ size_type
+ count (const std::basic_string&lt;C>&amp; name) const;
+
+ size_type
+ count (const std::basic_string&lt;C>&amp; namespace_,
+ const std::basic_string&lt;C>&amp; name) const;
+
+ size_type
+ count (const XMLCh* name) const;
+
+ size_type
+ count (const XMLCh* namespace_, const XMLCh* name) const;
+
+ iterator
+ find (const std::basic_string&lt;C>&amp; name);
+
+ iterator
+ find (const std::basic_string&lt;C>&amp; namespace_,
+ const std::basic_string&lt;C>&amp; name);
+
+ iterator
+ find (const XMLCh* name);
+
+ iterator
+ find (const XMLCh* namespace_, const XMLCh* name);
+
+ const_iterator
+ find (const std::basic_string&lt;C>&amp; name) const;
+
+ const_iterator
+ find (const std::basic_string&lt;C>&amp; namespace_,
+ const std::basic_string&lt;C>&amp; name) const;
+
+ const_iterator
+ find (const XMLCh* name) const;
+
+ const_iterator
+ find (const XMLCh* namespace_, const XMLCh* name) const;
+
+public:
+ // Note that the DOMDocument object of the two sets being
+ // swapped should be the same.
+ //
+ void
+ swap (attribute_set&amp;);
+};
+
+bool
+operator== (const attribute_set&amp;, const attribute_set&amp;);
+
+bool
+operator!= (const attribute_set&amp;, const attribute_set&amp;);
+ </pre>
+
+ <p>The following code shows how one could use this mapping:</p>
+
+ <pre class="c++">
+void
+f (object&amp; o, const xercesc::DOMAttr&amp; a)
+{
+ using namespace xercesc;
+
+ object::any_attribute_set&amp; s (o.any_attribute ());
+
+ // Iteration.
+ //
+ for (object::any_attribute_iterator i (s.begin ()); i != s.end (); ++i)
+ {
+ DOMAttr&amp; a (*i);
+ }
+
+ // Modification.
+ //
+ s.insert (a); // deep copy
+ DOMDocument&amp; doc (o.dom_document ());
+ s.insert (doc.createAttribute (...)); // assumes ownership
+
+ // Searching.
+ //
+ object::any_attribute_iterator i (s.find ("name"));
+ i = s.find ("http://www.w3.org/XML/1998/namespace", "lang");
+}
+ </pre>
+
+ <!-- Mapping for Mixed Content Models -->
+
+ <h2><a name="2.13">2.13 Mapping for Mixed Content Models</a></h2>
+
+ <p>XML Schema mixed content models do not have a direct C++ mapping.
+ Instead, information in XML instance documents, corresponding to
+ a mixed content model, can be accessed using generic DOM nodes that
+ can optionally be associated with object model nodes. See
+ <a href="#5.1">Section 5.1, "DOM Association"</a> for more
+ information about keeping association with DOM nodes.
+ </p>
+
+
+ <!-- Parsing -->
+
+
+ <h1><a name="3">3 Parsing</a></h1>
+
+ <p>This chapter covers various aspects of parsing XML instance
+ documents in order to obtain corresponding tree-like object
+ model.
+ </p>
+
+ <p>Each global XML Schema element in the form:</p>
+
+ <pre class="xml">
+&lt;element name="name" type="type"/>
+ </pre>
+
+ <p>is mapped to 14 overloaded C++ functions in the form:</p>
+
+ <pre class="c++">
+// Read from a URI or a local file.
+//
+
+std::auto_ptr&lt;type>
+name (const std::basic_string&lt;C>&amp; uri,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+
+std::auto_ptr&lt;type>
+name (const std::basic_string&lt;C>&amp; uri,
+ xml_schema::error_handler&amp;,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+
+std::auto_ptr&lt;type>
+name (const std::basic_string&lt;C>&amp; uri,
+ xercesc::DOMErrorHandler&amp;,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+
+
+// Read from std::istream.
+//
+
+std::auto_ptr&lt;type>
+name (std::istream&amp;,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+
+std::auto_ptr&lt;type>
+name (std::istream&amp;,
+ xml_schema::error_handler&amp;,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+
+std::auto_ptr&lt;type>
+name (std::istream&amp;,
+ xercesc::DOMErrorHandler&amp;,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+
+
+std::auto_ptr&lt;type>
+name (std::istream&amp;,
+ const std::basic_string&lt;C>&amp; id,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+
+std::auto_ptr&lt;type>
+name (std::istream&amp;,
+ const std::basic_string&lt;C>&amp; id,
+ xml_schema::error_handler&amp;,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+
+std::auto_ptr&lt;type>
+name (std::istream&amp;,
+ const std::basic_string&lt;C>&amp; id,
+ xercesc::DOMErrorHandler&amp;,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+
+
+// Read from InputSource.
+//
+
+std::auto_ptr&lt;type>
+name (xercesc::InputSource&amp;,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+
+std::auto_ptr&lt;type>
+name (xercesc::InputSource&amp;,
+ xml_schema::error_handler&amp;,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+
+std::auto_ptr&lt;type>
+name (xercesc::InputSource&amp;,
+ xercesc::DOMErrorHandler&amp;,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+
+
+// Read from DOM.
+//
+
+std::auto_ptr&lt;type>
+name (const xercesc::DOMDocument&amp;,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+
+std::auto_ptr&lt;type>
+name (xml_schema::dom::auto_ptr&lt;xercesc::DOMDocument>&amp;,
+ xml_schema::flags = 0,
+ const xml_schema::properties&amp; = xml_schema::properties ());
+ </pre>
+
+ <p>You can choose between reading an XML instance from a local file,
+ URI, <code>std::istream</code>, <code>xercesc::InputSource</code>,
+ or a pre-parsed DOM instance in the form of
+ <code>xercesc::DOMDocument</code>. Each of these parsing functions
+ is discussed in more detail in the following sections.
+ </p>
+
+ <h2><a name="3.1">3.1 Initializing the Xerces-C++ Runtime</a></h2>
+
+ <p>Some parsing functions expect you to initialize the Xerces-C++
+ runtime while others initialize and terminate it as part of their
+ work. The general rule is as follows: if a function has any arguments
+ or return a value that is an instance of a Xerces-C++ type, then
+ this function expects you to initialize the Xerces-C++ runtime.
+ Otherwise, the function initializes and terminates the runtime for
+ you. Note that it is legal to have nested calls to the Xerces-C++
+ initialize and terminate functions as long as the calls are balanced.
+ </p>
+
+ <p>You can instruct parsing functions that initialize and terminate
+ the runtime not to do so by passing the
+ <code>xml_schema::flags::dont_initialize</code> flag (see
+ <a href="#3.2">Section 3.2, "Flags and Properties"</a>).
+ </p>
+
+
+ <h2><a name="3.2">3.2 Flags and Properties</a></h2>
+
+ <p>Parsing flags and properties are the last two arguments of every
+ parsing function. They allow you to fine-tune the process of
+ instance validation and parsing. Both arguments are optional.
+ </p>
+
+
+ <p>The following flags are recognized by the parsing functions:</p>
+
+ <dl>
+ <dt><code>xml_schema::flags::keep_dom</code></dt>
+ <dd>Keep association between DOM nodes and the resulting
+ object model nodes. For more information about DOM association
+ refer to <a href="#5.1">Section 5.1, "DOM Association"</a>.</dd>
+
+ <dt><code>xml_schema::flags::own_dom</code></dt>
+ <dd>Assume ownership of the DOM document passed. This flag only
+ makes sense together with the <code>keep_dom</code> flag in
+ the call to the parsing function with the
+ <code>xml_schema::dom::auto_ptr&lt;DOMDocument></code>
+ argument.</dd>
+
+ <dt><code>xml_schema::flags::dont_validate</code></dt>
+ <dd>Do not validate instance documents against schemas.</dd>
+
+ <dt><code>xml_schema::flags::dont_initialize</code></dt>
+ <dd>Do not initialize the Xerces-C++ runtime.</dd>
+ </dl>
+
+ <p>You can pass several flags by combining them using the bit-wise OR
+ operator. For example:</p>
+
+ <pre class="c++">
+using xml_schema::flags;
+
+std::auto_ptr&lt;type> r (
+ name ("test.xml", flags::keep_dom | flags::dont_validate));
+ </pre>
+
+ <p>By default, validation of instance documents is turned on even
+ though parsers generated by XSD do not assume instance
+ documents are valid. They include a number of checks that prevent
+ construction of inconsistent object models. This,
+ however, does not mean that an instance document that was
+ successfully parsed by the XSD-generated parsers is
+ valid per the corresponding schema. If an instance document is not
+ "valid enough" for the generated parsers to construct consistent
+ object model, one of the exceptions defined in
+ <code>xml_schema</code> namespace is thrown (see
+ <a href="#3.3">Section 3.3, "Error Handling"</a>).
+ </p>
+
+ <p>For more information on the Xerces-C++ runtime initialization
+ refer to <a href="#3.1">Section 3.1, "Initializing the Xerces-C++
+ Runtime"</a>.
+ </p>
+
+ <p>The <code>xml_schema::properties</code> class allows you to
+ programmatically specify schema locations to be used instead
+ of those specified with the <code>xsi::schemaLocation</code>
+ and <code>xsi::noNamespaceSchemaLocation</code> attributes
+ in instance documents. The interface of the <code>properties</code>
+ class is presented below:
+ </p>
+
+ <pre class="c++">
+class properties
+{
+public:
+ void
+ schema_location (const std::basic_string&lt;C>&amp; namespace_,
+ const std::basic_string&lt;C>&amp; location);
+ void
+ no_namespace_schema_location (const std::basic_string&lt;C>&amp; location);
+};
+ </pre>
+
+ <p>Note that all locations are relative to an instance document unless
+ they are URIs. For example, if you want to use a local file as your
+ schema, then you will need to pass
+ <code>file:///absolute/path/to/your/schema</code> as the location
+ argument.
+ </p>
+
+ <h2><a name="3.3">3.3 Error Handling</a></h2>
+
+ <p>As discussed in <a href="#2.2">Section 2.2, "Error Handling"</a>,
+ the mapping uses the C++ exception handling mechanism as its primary
+ way of reporting error conditions. However, to handle recoverable
+ parsing and validation errors and warnings, a callback interface maybe
+ preferred by the application.</p>
+
+ <p>To better understand error handling and reporting strategies employed
+ by the parsing functions, it is useful to know that the
+ transformation of an XML instance document to a statically-typed
+ tree happens in two stages. The first stage, performed by Xerces-C++,
+ consists of parsing an XML document into a DOM instance. For short,
+ we will call this stage the XML-DOM stage. Validation, if not disabled,
+ happens during this stage. The second stage,
+ performed by the generated parsers, consist of parsing the DOM
+ instance into the statically-typed tree. We will call this stage
+ the DOM-Tree stage. Additional checks are performed during this
+ stage in order to prevent construction of inconsistent tree which
+ could otherwise happen when validation is disabled, for example.</p>
+
+ <p>All parsing functions except the one that operates on a DOM instance
+ come in overloaded triples. The first function in such a triple
+ reports error conditions exclusively by throwing exceptions. It
+ accumulates all the parsing and validation errors of the XML-DOM
+ stage and throws them in a single instance of the
+ <code>xml_schema::parsing</code> exception (described below).
+ The second and the third functions in the triple use callback
+ interfaces to report parsing and validation errors and warnings.
+ The two callback interfaces are <code>xml_schema::error_handler</code>
+ and <code>xercesc::DOMErrorHandler</code>. For more information
+ on the <code>xercesc::DOMErrorHandler</code> interface refer to
+ the Xerces-C++ documentation. The <code>xml_schema::error_handler</code>
+ interface is presented below:
+ </p>
+
+ <pre class="c++">
+class error_handler
+{
+public:
+ struct severity
+ {
+ enum value
+ {
+ warning,
+ error,
+ fatal
+ };
+ };
+
+ virtual bool
+ handle (const std::basic_string&lt;C>&amp; id,
+ unsigned long line,
+ unsigned long column,
+ severity,
+ const std::basic_string&lt;C>&amp; message) = 0;
+
+ virtual
+ ~error_handler ();
+};
+ </pre>
+
+ <p>The <code>id</code> argument of the <code>error_handler::handle</code>
+ function identifies the resource being parsed (e.g., a file name or
+ URI).
+ </p>
+
+ <p>By returning <code>true</code> from the <code>handle</code> function
+ you instruct the parser to recover and continue parsing. Returning
+ <code>false</code> results in termination of the parsing process.
+ An error with the <code>fatal</code> severity level results in
+ termination of the parsing process no matter what is returned from
+ the <code>handle</code> function. It is safe to throw an exception
+ from the <code>handle</code> function.
+ </p>
+
+ <p>The DOM-Tree stage reports error conditions exclusively by throwing
+ exceptions. Individual exceptions thrown by the parsing functions
+ are described in the following sub-sections.
+ </p>
+
+
+ <h3><a name="3.3.1">3.3.1 <code>xml_schema::parsing</code></a></h3>
+
+ <pre class="c++">
+struct severity
+{
+ enum value
+ {
+ warning,
+ error
+ };
+
+ severity (value);
+ operator value () const;
+};
+
+struct error
+{
+ error (severity,
+ const std::basic_string&lt;C>&amp; id,
+ unsigned long line,
+ unsigned long column,
+ const std::basic_string&lt;C>&amp; message);
+
+ severity
+ severity () const;
+
+ const std::basic_string&lt;C>&amp;
+ id () const;
+
+ unsigned long
+ line () const;
+
+ unsigned long
+ column () const;
+
+ const std::basic_string&lt;C>&amp;
+ message () const;
+};
+
+std::basic_ostream&lt;C>&amp;
+operator&lt;&lt; (std::basic_ostream&lt;C>&amp;, const error&amp;);
+
+struct diagnostics: std::vector&lt;error>
+{
+};
+
+std::basic_ostream&lt;C>&amp;
+operator&lt;&lt; (std::basic_ostream&lt;C>&amp;, const diagnostics&amp;);
+
+struct parsing: virtual exception
+{
+ parsing ();
+ parsing (const diagnostics&amp;);
+
+ const diagnostics&amp;
+ diagnostics () const;
+
+ virtual const char*
+ what () const throw ();
+};
+ </pre>
+
+ <p>The <code>xml_schema::parsing</code> exception is thrown if there
+ were parsing or validation errors reported during the XML-DOM stage.
+ If no callback interface was provided to the parsing function, the
+ exception contains a list of errors and warnings accessible using
+ the <code>diagnostics</code> function. The usual conditions when
+ this exception is thrown include malformed XML instances and, if
+ validation is turned on, invalid instance documents.
+ </p>
+
+ <h3><a name="3.3.2">3.3.2 <code>xml_schema::expected_element</code></a></h3>
+
+ <pre class="c++">
+struct expected_element: virtual exception
+{
+ expected_element (const std::basic_string&lt;C>&amp; name,
+ const std::basic_string&lt;C>&amp; namespace_);
+
+
+ const std::basic_string&lt;C>&amp;
+ name () const;
+
+ const std::basic_string&lt;C>&amp;
+ namespace_ () const;
+
+
+ virtual const char*
+ what () const throw ();
+};
+ </pre>
+
+ <p>The <code>xml_schema::expected_element</code> exception is thrown
+ when an expected element is not encountered by the DOM-Tree stage.
+ The name and namespace of the expected element can be obtained using
+ the <code>name</code> and <code>namespace_</code> functions respectively.
+ </p>
+
+
+ <h3><a name="3.3.3">3.3.3 <code>xml_schema::unexpected_element</code></a></h3>
+
+ <pre class="c++">
+struct unexpected_element: virtual exception
+{
+ unexpected_element (const std::basic_string&lt;C>&amp; encountered_name,
+ const std::basic_string&lt;C>&amp; encountered_namespace,
+ const std::basic_string&lt;C>&amp; expected_name,
+ const std::basic_string&lt;C>&amp; expected_namespace)
+
+
+ const std::basic_string&lt;C>&amp;
+ encountered_name () const;
+
+ const std::basic_string&lt;C>&amp;
+ encountered_namespace () const;
+
+
+ const std::basic_string&lt;C>&amp;
+ expected_name () const;
+
+ const std::basic_string&lt;C>&amp;
+ expected_namespace () const;
+
+
+ virtual const char*
+ what () const throw ();
+};
+ </pre>
+
+ <p>The <code>xml_schema::unexpected_element</code> exception is thrown
+ when an unexpected element is encountered by the DOM-Tree stage.
+ The name and namespace of the encountered element can be obtained
+ using the <code>encountered_name</code> and
+ <code>encountered_namespace</code> functions respectively. If an
+ element was expected instead of the encountered one, its name
+ and namespace can be obtained using the <code>expected_name</code> and
+ <code>expected_namespace</code> functions respectively. Otherwise
+ these functions return empty strings.
+ </p>
+
+ <h3><a name="3.3.4">3.3.4 <code>xml_schema::expected_attribute</code></a></h3>
+
+ <pre class="c++">
+struct expected_attribute: virtual exception
+{
+ expected_attribute (const std::basic_string&lt;C>&amp; name,
+ const std::basic_string&lt;C>&amp; namespace_);
+
+
+ const std::basic_string&lt;C>&amp;
+ name () const;
+
+ const std::basic_string&lt;C>&amp;
+ namespace_ () const;
+
+
+ virtual const char*
+ what () const throw ();
+};
+ </pre>
+
+ <p>The <code>xml_schema::expected_attribute</code> exception is thrown
+ when an expected attribute is not encountered by the DOM-Tree stage.
+ The name and namespace of the expected attribute can be obtained using
+ the <code>name</code> and <code>namespace_</code> functions respectively.
+ </p>
+
+
+ <h3><a name="3.3.5">3.3.5 <code>xml_schema::unexpected_enumerator</code></a></h3>
+
+ <pre class="c++">
+struct unexpected_enumerator: virtual exception
+{
+ unexpected_enumerator (const std::basic_string&lt;C>&amp; enumerator);
+
+ const std::basic_string&lt;C>&amp;
+ enumerator () const;
+
+ virtual const char*
+ what () const throw ();
+};
+ </pre>
+
+ <p>The <code>xml_schema::unexpected_enumerator</code> exception is thrown
+ when an unexpected enumerator is encountered by the DOM-Tree stage.
+ The enumerator can be obtained using the <code>enumerator</code>
+ functions.
+ </p>
+
+ <h3><a name="3.3.6">3.3.6 <code>xml_schema::expected_text_content</code></a></h3>
+
+ <pre class="c++">
+struct expected_text_content: virtual exception
+{
+ virtual const char*
+ what () const throw ();
+};
+ </pre>
+
+ <p>The <code>xml_schema::expected_text_content</code> exception is thrown
+ when a content other than text is encountered and the text content was
+ expected by the DOM-Tree stage.
+ </p>
+
+ <h3><a name="3.3.7">3.3.7 <code>xml_schema::no_type_info</code></a></h3>
+
+ <pre class="c++">
+struct no_type_info: virtual exception
+{
+ no_type_info (const std::basic_string&lt;C>&amp; type_name,
+ const std::basic_string&lt;C>&amp; type_namespace);
+
+ const std::basic_string&lt;C>&amp;
+ type_name () const;
+
+ const std::basic_string&lt;C>&amp;
+ type_namespace () const;
+
+ virtual const char*
+ what () const throw ();
+};
+ </pre>
+
+ <p>The <code>xml_schema::no_type_info</code> exception is thrown
+ when there is no type information associated with a type specified
+ by the <code>xsi:type</code> attribute. This exception is thrown
+ by the DOM-Tree stage. The name and namespace of the type in question
+ can be obtained using the <code>type_name</code> and
+ <code>type_namespace</code> functions respectively. Usually, catching
+ this exception means that you haven't linked the code generated
+ from the schema defining the type in question with your application
+ or this schema has been compiled without the
+ <code>--generate-polymorphic</code> option.
+ </p>
+
+
+ <h3><a name="3.3.8">3.3.8 <code>xml_schema::not_derived</code></a></h3>
+
+ <pre class="c++">
+struct not_derived: virtual exception
+{
+ not_derived (const std::basic_string&lt;C>&amp; base_type_name,
+ const std::basic_string&lt;C>&amp; base_type_namespace,
+ const std::basic_string&lt;C>&amp; derived_type_name,
+ const std::basic_string&lt;C>&amp; derived_type_namespace);
+
+ const std::basic_string&lt;C>&amp;
+ base_type_name () const;
+
+ const std::basic_string&lt;C>&amp;
+ base_type_namespace () const;
+
+
+ const std::basic_string&lt;C>&amp;
+ derived_type_name () const;
+
+ const std::basic_string&lt;C>&amp;
+ derived_type_namespace () const;
+
+ virtual const char*
+ what () const throw ();
+};
+ </pre>
+
+ <p>The <code>xml_schema::not_derived</code> exception is thrown
+ when a type specified by the <code>xsi:type</code> attribute is
+ not derived from the expected base type. This exception is thrown
+ by the DOM-Tree stage. The name and namespace of the expected
+ base type can be obtained using the <code>base_type_name</code> and
+ <code>base_type_namespace</code> functions respectively. The name
+ and namespace of the offending type can be obtained using the
+ <code>derived_type_name</code> and
+ <code>derived_type_namespace</code> functions respectively.
+ </p>
+
+ <h3><a name="3.3.9">3.3.9 <code>xml_schema::no_prefix_mapping</code></a></h3>
+
+ <pre class="c++">
+struct no_prefix_mapping: virtual exception
+{
+ no_prefix_mapping (const std::basic_string&lt;C>&amp; prefix);
+
+ const std::basic_string&lt;C>&amp;
+ prefix () const;
+
+ virtual const char*
+ what () const throw ();
+};
+ </pre>
+
+ <p>The <code>xml_schema::no_prefix_mapping</code> exception is thrown
+ during the DOM-Tree stage if a namespace prefix is encountered for
+ which a prefix-namespace mapping hasn't been provided. The namespace
+ prefix in question can be obtained using the <code>prefix</code>
+ function.
+ </p>
+
+ <h2><a name="3.4">3.4 Reading from a Local File or URI</a></h2>
+
+ <p>Using a local file or URI is the simplest way to parse an XML instance.
+ For example:</p>
+
+ <pre class="c++">
+using std::auto_ptr;
+
+auto_ptr&lt;type> r1 (name ("test.xml"));
+auto_ptr&lt;type> r2 (name ("http://www.codesynthesis.com/test.xml"));
+ </pre>
+
+ <h2><a name="3.5">3.5 Reading from <code>std::istream</code></a></h2>
+
+ <p>When using an <code>std::istream</code> instance, you may also
+ pass an optional resource id. This id is used to identify the
+ resource (for example in error messages) as well as to resolve
+ relative paths. For instance:</p>
+
+ <pre class="c++">
+using std::auto_ptr;
+
+{
+ std::ifstream ifs ("test.xml");
+ auto_ptr&lt;type> r (name (ifs, "test.xml"));
+}
+
+{
+ std::string str ("..."); // Some XML fragment.
+ std::istringstream iss (str);
+ auto_ptr&lt;type> r (name (iss));
+}
+ </pre>
+
+ <h2><a name="3.6">3.6 Reading from <code>xercesc::InputSource</code></a></h2>
+
+ <p>Reading from a <code>xercesc::InputSource</code> instance
+ is similar to the <code>std::istream</code> case except
+ the resource id is maintained by the <code>InputSource</code>
+ object. For instance:</p>
+
+ <pre class="c++">
+xercesc::StdInInputSource is;
+std::auto_ptr&lt;type> r (name (is));
+ </pre>
+
+ <h2><a name="3.7">3.7 Reading from DOM</a></h2>
+
+ <p>Reading from a <code>xercesc::DOMDocument</code> instance allows
+ you to setup a custom XML-DOM stage. Things like DOM
+ parser reuse, schema pre-parsing, and schema caching can be achieved
+ with this approach. For more information on how to obtain DOM
+ representation from an XML instance refer to the Xerces-C++
+ documentation. In addition, the
+ <a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree Mapping
+ FAQ</a> shows how to parse an XML instance to a Xerces-C++
+ DOM document using the XSD runtime utilities.
+ </p>
+
+ <p>The last parsing function is useful when you would like to perform
+ your own XML-to-DOM parsing and associate the resulting DOM document
+ with the object model nodes. If parsing is successeful, the
+ automatic <code>DOMDocument</code> pointer is reset and the
+ resulting object model assumes ownership of the DOM document
+ passed. For example:</p>
+
+ <pre class="c++">
+xml_schema::dom::auto_ptr&lt;xercesc::DOMDocument> doc = ...
+
+std::auto_ptr&lt;type> r (
+ name (doc, xml_schema::flags::keep_dom | xml_schema::flags::own_dom));
+
+// At this point doc is reset to 0.
+ </pre>
+
+
+
+ <h1><a name="4">4 Serialization</a></h1>
+
+ <p>This chapter covers various aspects of serializing a
+ tree-like object model to DOM or XML.
+ In this regard, serialization is complimentary to the reverse
+ process of parsing a DOM or XML instance into an object model
+ which is discussed in <a href="#3">Chapter 3,
+ "Parsing"</a>. Note that the generation of the serialization code
+ is optional and should be explicitly requested with the
+ <code>--generate-serialization</code> option. See the
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD
+ Compiler Command Line Manual</a> for more information.
+ </p>
+
+ <p>Each global XML Schema element in the form:
+ </p>
+
+
+ <pre class="xml">
+&lt;xsd:element name="name" type="type"/>
+ </pre>
+
+ <p>is mapped to 8 overloaded C++ functions in the form:</p>
+
+ <pre class="c++">
+// Serialize to std::ostream.
+//
+void
+name (std::ostream&amp;,
+ const type&amp;,
+ const xml_schema::namespace_fomap&amp; =
+ xml_schema::namespace_infomap (),
+ const std::basic_string&lt;C>&amp; encoding = "UTF-8",
+ xml_schema::flags = 0);
+
+void
+name (std::ostream&amp;,
+ const type&amp;,
+ xml_schema::error_handler&amp;,
+ const xml_schema::namespace_infomap&amp; =
+ xml_schema::namespace_infomap (),
+ const std::basic_string&lt;C>&amp; encoding = "UTF-8",
+ xml_schema::flags = 0);
+
+void
+name (std::ostream&amp;,
+ const type&amp;,
+ xercesc::DOMErrorHandler&amp;,
+ const xml_schema::namespace_infomap&amp; =
+ xml_schema::namespace_infomap (),
+ const std::basic_string&lt;C>&amp; encoding = "UTF-8",
+ xml_schema::flags = 0);
+
+
+// Serialize to XMLFormatTarget.
+//
+void
+name (xercesc::XMLFormatTarget&amp;,
+ const type&amp;,
+ const xml_schema::namespace_infomap&amp; =
+ xml_schema::namespace_infomap (),
+ const std::basic_string&lt;C>&amp; encoding = "UTF-8",
+ xml_schema::flags = 0);
+
+void
+name (xercesc::XMLFormatTarget&amp;,
+ const type&amp;,
+ xml_schema::error_handler&amp;,
+ const xml_schema::namespace_infomap&amp; =
+ xml_schema::namespace_infomap (),
+ const std::basic_string&lt;C>&amp; encoding = "UTF-8",
+ xml_schema::flags = 0);
+
+void
+name (xercesc::XMLFormatTarget&amp;,
+ const type&amp;,
+ xercesc::DOMErrorHandler&amp;,
+ const xml_schema::namespace_infomap&amp; =
+ xml_schema::namespace_infomap (),
+ const std::basic_string&lt;C>&amp; encoding = "UTF-8",
+ xml_schema::flags = 0);
+
+
+// Serialize to DOM.
+//
+xml_schema::dom::auto_ptr&lt;xercesc::DOMDocument>
+name (const type&amp;,
+ const xml_schema::namespace_infomap&amp;
+ xml_schema::namespace_infomap (),
+ xml_schema::flags = 0);
+
+void
+name (xercesc::DOMDocument&amp;,
+ const type&amp;,
+ xml_schema::flags = 0);
+ </pre>
+
+ <p>You can choose between writing XML to <code>std::ostream</code> or
+ <code>xercesc::XMLFormatTarget</code> and creating a DOM instance
+ in the form of <code>xercesc::DOMDocument</code>. Serialization
+ to <code>ostream</code> or <code>XMLFormatTarget</code> requires a
+ considerably less work while serialization to DOM provides
+ for greater flexibility. Each of these serialization functions
+ is discussed in more detail in the following sections.
+ </p>
+
+
+ <h2><a name="4.1">4.1 Initializing the Xerces-C++ Runtime</a></h2>
+
+ <p>Some serialization functions expect you to initialize the Xerces-C++
+ runtime while others initialize and terminate it as part of their
+ work. The general rule is as follows: if a function has any arguments
+ or return a value that is an instance of a Xerces-C++ type, then
+ this function expects you to initialize the Xerces-C++ runtime.
+ Otherwise, the function initializes and terminates the runtime for
+ you. Note that it is legal to have nested calls to the Xerces-C++
+ initialize and terminate functions as long as the calls are balanced.
+ </p>
+
+ <p>You can instruct serialization functions that initialize and terminate
+ the runtime not to do so by passing the
+ <code>xml_schema::flags::dont_initialize</code> flag (see
+ <a href="#4.3">Section 4.3, "Flags"</a>).
+ </p>
+
+ <h2><a name="4.2">4.2 Namespace Infomap and Character Encoding</a></h2>
+
+ <p>When a document being serialized uses XML namespaces, custom
+ prefix-namespace associations can to be established. If custom
+ prefix-namespace mapping is not provided then generic prefixes
+ (<code>p1</code>, <code>p2</code>, etc) are automatically assigned
+ to namespaces as needed. Also, if
+ you would like the resulting instance document to contain the
+ <code>schemaLocation</code> or <code>noNamespaceSchemaLocation</code>
+ attributes, you will need to provide namespace-schema associations.
+ The <code>xml_schema::namespace_infomap</code> class is used
+ to capture this information:</p>
+
+ <pre class="c++">
+struct namespace_info
+{
+ namespace_info ();
+ namespace_info (const std::basic_string&lt;C>&amp; name,
+ const std::basic_string&lt;C>&amp; schema);
+
+ std::basic_string&lt;C> name;
+ std::basic_string&lt;C> schema;
+};
+
+// Map of namespace prefix to namespace_info.
+//
+struct namespace_infomap: public std::map&lt;std::basic_string&lt;C>,
+ namespace_info>
+{
+};
+ </pre>
+
+ <p>Consider the following associations as an example:</p>
+
+ <pre class="c++">
+xml_schema::namespace_infomap map;
+
+map["t"].name = "http://www.codesynthesis.com/test";
+map["t"].schema = "test.xsd";
+ </pre>
+
+ <p>This map, if passed to one of the serialization functions,
+ could result in the following XML fragment:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0" ?>
+&lt;t:name xmlns:t="http://www.codesynthesis.com/test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/test test.xsd">
+ </pre>
+
+ <p>As you can see, the serialization function automatically added namespace
+ mapping for the <code>xsi</code> prefix. You can change this by
+ providing your own prefix:</p>
+
+ <pre class="c++">
+xml_schema::namespace_infomap map;
+
+map["xsn"].name = "http://www.w3.org/2001/XMLSchema-instance";
+
+map["t"].name = "http://www.codesynthesis.com/test";
+map["t"].schema = "test.xsd";
+ </pre>
+
+ <p>This could result in the following XML fragment:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0" ?>
+&lt;t:name xmlns:t="http://www.codesynthesis.com/test"
+ xmlns:xsn="http://www.w3.org/2001/XMLSchema-instance"
+ xsn:schemaLocation="http://www.codesynthesis.com/test test.xsd">
+ </pre>
+
+ <p>To specify the location of a schema without a namespace you can use
+ an empty prefix as in the example below: </p>
+
+ <pre class="c++">
+xml_schema::namespace_infomap map;
+
+map[""].schema = "test.xsd";
+ </pre>
+
+ <p>This would result in the following XML fragment:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0" ?>
+&lt;name xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="test.xsd">
+ </pre>
+
+ <p>To make a particular namespace default you can use an empty
+ prefix, for example:</p>
+
+ <pre class="c++">
+xml_schema::namespace_infomap map;
+
+map[""].name = "http://www.codesynthesis.com/test";
+map[""].schema = "test.xsd";
+ </pre>
+
+ <p>This could result in the following XML fragment:</p>
+
+ <pre class="xml">
+&lt;?xml version="1.0" ?>
+&lt;name xmlns="http://www.codesynthesis.com/test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/test test.xsd">
+ </pre>
+
+
+ <p>Another bit of information that you can pass to the serialization
+ functions is the character encoding method that you would like to use.
+ Common values for this argument are <code>"US-ASCII"</code>,
+ <code>"ISO8859-1"</code>, <code>"UTF-8"</code>,
+ <code>"UTF-16BE"</code>, <code>"UTF-16LE"</code>,
+ <code>"UCS-4BE"</code>, and <code>"UCS-4LE"</code>. The default
+ encoding is <code>"UTF-8"</code>. For more information on
+ encoding methods see the
+ "<a href="http://en.wikipedia.org/wiki/Character_code">Character
+ Encoding</a>" article from Wikipedia.
+ </p>
+
+ <h2><a name="4.3">4.3 Flags</a></h2>
+
+ <p>Serialization flags are the last argument of every serialization
+ function. They allow you to fine-tune the process of serialization.
+ The flags argument is optional.
+ </p>
+
+
+ <p>The following flags are recognized by the serialization
+ functions:</p>
+
+ <dl>
+ <dt><code>xml_schema::flags::dont_initialize</code></dt>
+ <dd>Do not initialize the Xerces-C++ runtime.</dd>
+
+ <dt><code>xml_schema::flags::dont_pretty_print</code></dt>
+ <dd>Do not add extra spaces or new lines that make the resulting XML
+ slightly bigger but easier to read.</dd>
+
+ <dt><code>xml_schema::flags::no_xml_declaration</code></dt>
+ <dd>Do not write XML declaration (&lt;?xml ... ?>).</dd>
+ </dl>
+
+ <p>You can pass several flags by combining them using the bit-wise OR
+ operator. For example:</p>
+
+ <pre class="c++">
+std::auto_ptr&lt;type> r = ...
+std::ofstream ofs ("test.xml");
+xml_schema::namespace_infomap map;
+name (ofs,
+ *r,
+ map,
+ "UTF-8",
+ xml_schema::flags::no_xml_declaration |
+ xml_schema::flags::dont_pretty_print);
+ </pre>
+
+ <p>For more information on the Xerces-C++ runtime initialization
+ refer to <a href="#4.1">Section 4.1, "Initializing the Xerces-C++
+ Runtime"</a>.
+ </p>
+
+ <h2><a name="4.4">4.4 Error Handling</a></h2>
+
+ <p>As with the parsing functions (see <a href="#3.3">Section 3.3,
+ "Error Handling"</a>), to better understand error handling and
+ reporting strategies employed by the serialization functions, it
+ is useful to know that the transformation of a statically-typed
+ tree to an XML instance document happens in two stages. The first
+ stage, performed by the generated code, consist of building a DOM
+ instance from the statically-typed tree . For short, we will call
+ this stage the Tree-DOM stage. The second stage, performed by
+ Xerces-C++, consists of serializing the DOM instance into the XML
+ document. We will call this stage the DOM-XML stage.
+ </p>
+
+ <p>All serialization functions except the two that serialize into
+ a DOM instance come in overloaded triples. The first function
+ in such a triple reports error conditions exclusively by throwing
+ exceptions. It accumulates all the serialization errors of the
+ DOM-XML stage and throws them in a single instance of the
+ <code>xml_schema::serialization</code> exception (described below).
+ The second and the third functions in the triple use callback
+ interfaces to report serialization errors and warnings. The two
+ callback interfaces are <code>xml_schema::error_handler</code> and
+ <code>xercesc::DOMErrorHandler</code>. The
+ <code>xml_schema::error_handler</code> interface is described in
+ <a href="#3.3">Section 3.3, "Error Handling"</a>. For more information
+ on the <code>xercesc::DOMErrorHandler</code> interface refer to the
+ Xerces-C++ documentation.
+ </p>
+
+ <p>The Tree-DOM stage reports error conditions exclusively by throwing
+ exceptions. Individual exceptions thrown by the serialization functions
+ are described in the following sub-sections.
+ </p>
+
+ <h3><a name="4.4.1">4.4.1 <code>xml_schema::serialization</code></a></h3>
+
+ <pre class="c++">
+struct serialization: virtual exception
+{
+ serialization ();
+ serialization (const diagnostics&amp;);
+
+ const diagnostics&amp;
+ diagnostics () const;
+
+ virtual const char*
+ what () const throw ();
+};
+ </pre>
+
+ <p>The <code>xml_schema::diagnostics</code> class is described in
+ <a href="#3.3.1">Section 3.3.1, "<code>xml_schema::parsing</code>"</a>.
+ The <code>xml_schema::serialization</code> exception is thrown if
+ there were serialization errors reported during the DOM-XML stage.
+ If no callback interface was provided to the serialization function,
+ the exception contains a list of errors and warnings accessible using
+ the <code>diagnostics</code> function.
+ </p>
+
+
+ <h3><a name="4.4.2">4.4.2 <code>xml_schema::unexpected_element</code></a></h3>
+
+ <p>The <code>xml_schema::unexpected_element</code> exception is
+ described in <a href="#3.3.3">Section 3.3.3,
+ "<code>xml_schema::unexpected_element</code>"</a>. It is thrown
+ by the serialization functions during the Tree-DOM stage if the
+ root element name of the provided DOM instance does not match with
+ the name of the element this serialization function is for.
+ </p>
+
+ <h3><a name="4.4.3">4.4.3 <code>xml_schema::no_type_info</code></a></h3>
+
+ <p>The <code>xml_schema::no_type_info</code> exception is
+ described in <a href="#3.3.7">Section 3.3.7,
+ "<code>xml_schema::no_type_info</code>"</a>. It is thrown
+ by the serialization functions during the Tree-DOM stage when there
+ is no type information associated with a dynamic type of an
+ element. Usually, catching this exception means that you haven't
+ linked the code generated from the schema defining the type in
+ question with your application or this schema has been compiled
+ without the <code>--generate-polymorphic</code> option.
+ </p>
+
+ <h2><a name="4.5">4.5 Serializing to <code>std::ostream</code></a></h2>
+
+ <p>In order to serialize to <code>std::ostream</code> you will need
+ an object model, an output stream and, optionally, a namespace
+ infomap. For instance:</p>
+
+ <pre class="c++">
+// Obtain the object model.
+//
+std::auto_ptr&lt;type> r = ...
+
+// Prepare namespace mapping and schema location information.
+//
+xml_schema::namespace_infomap map;
+
+map["t"].name = "http://www.codesynthesis.com/test";
+map["t"].schema = "test.xsd";
+
+// Write it out.
+//
+name (std::cout, *r, map);
+ </pre>
+
+ <p>Note that the output stream is treated as a binary stream. This
+ becomes important when you use a character encoding that is wider
+ than 8-bit <code>char</code>, for instance UTF-16 or UCS-4. For
+ example, things will most likely break if you try to serialize
+ to <code>std::ostringstream</code> with UTF-16 or UCS-4 as an
+ encoding. This is due to the special value,
+ <code>'\0'</code>, that will most likely occur as part of such
+ serialization and it won't have the special meaning assumed by
+ <code>std::ostringstream</code>.
+ </p>
+
+
+ <h2><a name="4.6">4.6 Serializing to <code>xercesc::XMLFormatTarget</code></a></h2>
+
+ <p>Serializing to an <code>xercesc::XMLFormatTarget</code> instance
+ is similar the <code>std::ostream</code> case. For instance:
+ </p>
+
+ <pre class="c++">
+using std::auto_ptr;
+
+// Obtain the object model.
+//
+auto_ptr&lt;type> r = ...
+
+// Prepare namespace mapping and schema location information.
+//
+xml_schema::namespace_infomap map;
+
+map["t"].name = "http://www.codesynthesis.com/test";
+map["t"].schema = "test.xsd";
+
+using namespace xercesc;
+
+XMLPlatformUtils::Initialize ();
+
+{
+ // Choose a target.
+ //
+ auto_ptr&lt;XMLFormatTarget> ft;
+
+ if (argc != 2)
+ {
+ ft = auto_ptr&lt;XMLFormatTarget> (new StdOutFormatTarget ());
+ }
+ else
+ {
+ ft = auto_ptr&lt;XMLFormatTarget> (
+ new LocalFileFormatTarget (argv[1]));
+ }
+
+ // Write it out.
+ //
+ name (*ft, *r, map);
+}
+
+XMLPlatformUtils::Terminate ();
+ </pre>
+
+ <p>Note that we had to initialize the Xerces-C++ runtime before we
+ could call this serialization function.</p>
+
+ <h2><a name="4.7">4.7 Serializing to DOM</a></h2>
+
+ <p>The mapping provides two overloaded functions that implement
+ serialization to a DOM instance. The first creates a DOM instance
+ for you and the second serializes to an existing DOM instance.
+ While serializing to a new DOM instance is similar to serializing
+ to <code>std::ostream</code> or <code>xercesc::XMLFormatTarget</code>,
+ serializing to an existing DOM instance requires quite a bit of work
+ from your side. You will need to set all the custom namespace mapping
+ attributes as well as the <code>schemaLocation</code> and/or
+ <code>noNamespaceSchemaLocation</code> attributes. The following
+ listing should give you an idea about what needs to be done:
+ </p>
+
+ <pre class="c++">
+// Obtain the object model.
+//
+std::auto_ptr&lt;type> r = ...
+
+using namespace xercesc;
+
+XMLPlatformUtils::Initialize ();
+
+{
+ // Create a DOM instance. Set custom namespace mapping and schema
+ // location attributes.
+ //
+ DOMDocument&amp; doc = ...
+
+ // Serialize to DOM.
+ //
+ name (doc, *r);
+
+ // Serialize the DOM document to XML.
+ //
+ ...
+}
+
+XMLPlatformUtils::Terminate ();
+ </pre>
+
+ <p>For more information on how to create and serialize a DOM instance
+ refer to the Xerces-C++ documentation. In addition, the
+ <a href="http://wiki.codesynthesis.com/Tree/FAQ">C++/Tree Mapping
+ FAQ</a> shows how to implement these operations using the XSD
+ runtime utilities.
+ </p>
+
+ <h1><a name="5">5 Additional Functionality</a></h1>
+
+ <p>The C++/Tree mapping provides a number of optional features
+ that can be useful in certain situations. They are described
+ in the following sections.</p>
+
+ <h2><a name="5.1">5.1 DOM Association</a></h2>
+
+ <p>Normally, after parsing is complete, the DOM document which
+ was used to extract the data is discarded. However, the parsing
+ functions can be instructed to preserve the DOM document
+ and create an association between the DOM nodes and object model
+ nodes. When there is an association between the DOM and
+ object model nodes, you can obtain the corresponding DOM element
+ or attribute node from an object model node as well as perform
+ the reverse transition: obtain the corresponding object model
+ from a DOM element or attribute node.</p>
+
+ <p>Maintaining DOM association is normally useful when the application
+ needs access to XML constructs that are not preserved in the
+ object model, for example, text in the mixed content model.
+ Another useful aspect of DOM association is the ability of the
+ application to navigate the document tree using the generic DOM
+ interface (for example, with the help of an XPath processor)
+ and then move back to the statically-typed object model. Note
+ also that while you can change the underlying DOM document,
+ these changes are not reflected in the object model and will
+ be ignored during serialization. If you need to not only access
+ but also modify some aspects of XML that are not preserved in
+ the object model, then type customization with custom parsing
+ constructs and serialization operators should be used instead.</p>
+
+ <p>To request DOM association you will need to pass the
+ <code>xml_schema::flags::keep_dom</code> flag to one of the
+ parsing functions (see <a href="#3.2">Section 3.2,
+ "Flags and Properties"</a> for more information). In this case the
+ DOM document is retained and will be released when the object model
+ is deleted. Note that since DOM nodes "out-live" the parsing function
+ call, you need to initialize the Xerces-C++ runtime before calling
+ one of the parsing functions with the <code>keep_dom</code> flag and
+ terminate it after the object model is destroyed (see
+ <a href="#3.1">Section 3.1, "Initializing the Xerces-C++ Runtime"</a>).
+ The DOM association is also maintained in complete copies of the
+ object model (that is, the DOM document is cloned and associations
+ are reestablished).</p>
+
+ <p>To obtain the corresponding DOM node from an object model node
+ you will need to call the <code>_node</code> accessor function
+ which returns a pointer to <code>DOMNode</code>. You can then query
+ this DOM node's type and cast it to either <code>DOMAttr*</code>
+ or <code>DOMElement*</code>. To obtain the corresponding object
+ model node from a DOM node, the DOM user data API is used. The
+ <code>xml_schema::dom::tree_node_key</code> variable contains
+ the key for object model nodes. The following schema and code
+ fragment show how to navigate from DOM to object model nodes
+ and in the opposite direction:</p>
+
+ <pre class="xml">
+&lt;complexType name="object">
+ &lt;sequence>
+ &lt;element name="a" type="string"/>
+ &lt;/sequence>
+&lt;/complexType>
+
+&lt;element name="root" type="object"/>
+ </pre>
+
+ <pre class="c++">
+using namespace xercesc;
+
+XMLPlatformUtils::Initialize ();
+
+{
+ // Parse XML to object model.
+ //
+ std::auto_ptr&lt;type> r = root (
+ "root.xml",
+ xml_schema::flags::keep_dom |
+ xml_schema::flags::dont_initialize);
+
+ DOMNode* n = root->_node ();
+ assert (n->getNodeType () != DOMNode::ELEMENT_NODE);
+ DOMElement* re = static_cast&lt;DOMElement*> (n);
+
+ // Get the 'a' element. Note that it is not necessarily the
+ // first child node of 'root' since there could be whitespace
+ // nodes before it.
+ //
+ DOMElement* ae;
+
+ for (n = re->getFirstChild (); n != 0; n = n->getNextSibling ())
+ {
+ if (n->getNodeType () == DOMNode::ELEMENT_NODE)
+ {
+ ae = static_cast&lt;DOMElement*> (n);
+ break;
+ }
+ }
+
+ // Get from the 'a' DOM element to xml_schema::string object model
+ // node.
+ //
+ xml_schema::type&amp; t (
+ *reinterpret_cast&lt;xml_schema::type*> (
+ ae->getUserData (xml_schema::dom::tree_node_key)));
+
+ xml_schema::string&amp; a (dynamic_cast&lt;xml_schema::string&amp;> (t));
+}
+
+XMLPlatformUtils::Terminate ();
+ </pre>
+
+ <p>The 'mixed' example which can be found in the XSD distribution
+ shows how to handle the mixed content using DOM association.</p>
+
+ <h2><a name="5.2">5.2 Binary Serialization</a></h2>
+
+ <p>Besides reading from and writing to XML, the C++/Tree mapping
+ also allows you to save the object model to and load it from a
+ number of predefined as well as custom data representation
+ formats. The predefined binary formats are CDR (Common Data
+ Representation) and XDR (eXternal Data Representation). A
+ custom format can easily be supported by providing
+ insertion and extraction operators for basic types.</p>
+
+ <p>Binary serialization saves only the data without any meta
+ information or markup. As a result, saving to and loading
+ from a binary representation can be an order of magnitude
+ faster than parsing and serializing the same data in XML.
+ Furthermore, the resulting representation is normally several
+ times smaller than the equivalent XML representation. These
+ properties make binary serialization ideal for internal data
+ exchange and storage. A typical application that uses this
+ facility stores the data and communicates within the
+ system using a binary format and reads/writes the data
+ in XML when communicating with the outside world.</p>
+
+ <p>In order to request the generation of insertion operators and
+ extraction constructors for a specific predefined or custom
+ data representation stream, you will need to use the
+ <code>--generate-insertion</code> and <code>--generate-extraction</code>
+ compiler options. See the
+ <a href="http://www.codesynthesis.com/projects/xsd/documentation/xsd.xhtml">XSD
+ Compiler Command Line Manual</a> for more information.</p>
+
+ <p>Once the insertion operators and extraction constructors are
+ generated, you can use the <code>xml_schema::istream</code>
+ and <code>xml_schema::ostream</code> wrapper stream templates
+ to save the object model to and load it from a specific format.
+ The following code fragment shows how to do this using ACE
+ (Adaptive Communication Environment) CDR streams as an example:</p>
+
+ <pre class="xml">
+&lt;complexType name="object">
+ &lt;sequence>
+ &lt;element name="a" type="string"/>
+ &lt;element name="b" type="int"/>
+ &lt;/sequence>
+&lt;/complexType>
+
+&lt;element name="root" type="object"/>
+ </pre>
+
+ <pre class="c++">
+// Parse XML to object model.
+//
+std::auto_ptr&lt;type> r = root ("root.xml");
+
+// Save to a CDR stream.
+//
+ACE_OutputCDR ace_ocdr;
+xml_schema::ostream&lt;ACE_OutputCDR> ocdr (ace_ocdr);
+
+ocdr &lt;&lt; *r;
+
+// Load from a CDR stream.
+//
+ACE_InputCDR ace_icdr (buf, size);
+xml_schema::istream&lt;ACE_InputCDR> icdr (ace_icdr);
+
+std::auto_ptr&lt;object> copy (new object (icdr));
+
+// Serialize to XML.
+//
+root (std::cout, *copy);
+ </pre>
+
+ <p>The XSD distribution contains a number of examples that
+ show how to save the object model to and load it from
+ CDR, XDR, and a custom format.</p>
+
+ <!-- Appendix A -->
+
+
+ <h1><a name="A">Appendix A &mdash; Default and Fixed Values</a></h1>
+
+ <p>The following table summarizes the effect of default and fixed
+ values (specified with the <code>default</code> and <code>fixed</code>
+ attributes, respectively) on attribute and element values. The
+ <code>default</code> and <code>fixed</code> attributes are mutually
+ exclusive. It is also worthwhile to note that the fixed value semantics
+ is a superset of the default value semantics.
+ </p>
+
+ <!-- border="1" is necessary for html2ps -->
+ <table id="default-fixed" border="1">
+ <tr>
+ <th></th>
+ <th></th>
+ <th colspan="2">default</th>
+ <th colspan="2">fixed</th>
+ </tr>
+
+ <!-- element -->
+
+ <tr>
+ <th rowspan="4">element</th>
+ <th rowspan="2">not present</th>
+ <th>optional</th>
+ <th>required</th>
+ <th>optional</th>
+ <th>required</th>
+ </tr>
+ <tr>
+ <td>not present</td>
+ <td>invalid instance</td>
+ <td>not present</td>
+ <td>invalid instance</td>
+ </tr>
+
+
+ <tr>
+ <th>empty</th>
+ <td colspan="2">default value is used</td>
+ <td colspan="2">fixed value is used</td>
+ </tr>
+
+ <tr>
+ <th>value</th>
+ <td colspan="2">value is used</td>
+ <td colspan="2">value is used provided it's the same as fixed</td>
+ </tr>
+
+ <!-- attribute -->
+
+ <!-- element -->
+
+ <tr>
+ <th rowspan="4">attribute</th>
+ <th rowspan="2">not present</th>
+ <th>optional</th>
+ <th>required</th>
+ <th>optional</th>
+ <th>required</th>
+ </tr>
+ <tr>
+ <td>default value is used</td>
+ <td>invalid schema</td>
+ <td>fixed value is used</td>
+ <td>invalid instance</td>
+ </tr>
+
+
+ <tr>
+ <th>empty</th>
+ <td colspan="2">empty value is used</td>
+ <td colspan="2">empty value is used provided it's the same as fixed</td>
+ </tr>
+
+ <tr>
+ <th>value</th>
+ <td colspan="2">value is used</td>
+ <td colspan="2">value is used provided it's the same as fixed</td>
+ </tr>
+
+ </table>
+
+ </div>
+</div>
+
+
+</body>
+</html>
diff --git a/documentation/cxx/tree/manual/makefile b/documentation/cxx/tree/manual/makefile
new file mode 100644
index 0000000..bfdd6d3
--- /dev/null
+++ b/documentation/cxx/tree/manual/makefile
@@ -0,0 +1,12 @@
+.PHONY: all
+all: cxx-tree-manual.ps cxx-tree-manual.pdf
+
+cxx-tree-manual.pdf: cxx-tree-manual.ps
+ ps2pdf14 $<
+
+cxx-tree-manual.ps: index.xhtml manual.html2ps
+ html2ps -f manual.html2ps -o $@ $<
+
+.PHONY: clean
+clean:
+ rm -f cxx-tree-manual.ps cxx-tree-manual.pdf
diff --git a/documentation/cxx/tree/manual/manual.html2ps b/documentation/cxx/tree/manual/manual.html2ps
new file mode 100644
index 0000000..d7477bf
--- /dev/null
+++ b/documentation/cxx/tree/manual/manual.html2ps
@@ -0,0 +1,66 @@
+@html2ps {
+ option {
+ toc: hb;
+ colour: 1;
+ hyphenate: 1;
+ titlepage: 1;
+ }
+
+ datefmt: "%B %Y";
+
+ titlepage {
+ content: "
+<div align=center>
+ <h1><big>C++/Tree Mapping User Manual</big></h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+ <h1>&nbsp;</h1>
+</div>
+ <p>Revision $[revision] &nbsp;&nbsp;&nbsp; $D</p>
+ <p>Copyright &copy; 2005-2009 CODE SYNTHESIS TOOLS CC</p>
+
+ <p>Permission is granted to copy, distribute and/or modify this
+ document under the terms of the
+ <a href='http://www.codesynthesis.com/licenses/fdl-1.2.txt'>GNU Free
+ Documentation License, version 1.2</a>; with no Invariant Sections,
+ no Front-Cover Texts and no Back-Cover Texts.
+ </p>
+
+ <p>This document is available in the following formats:
+ <a href='http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/index.xhtml'>XHTML</a>,
+ <a href='http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.pdf'>PDF</a>, and
+ <a href='http://www.codesynthesis.com/projects/xsd/documentation/cxx/tree/manual/cxx-tree-manual.ps'>PostScript</a>.</p>";
+ }
+
+ toc {
+ indent: 2em;
+ }
+
+ header {
+ odd-right: $H;
+ even-left: $H;
+ }
+
+ footer {
+ odd-left: $D;
+ odd-center: $T, v$[revision];
+ odd-right: $N;
+
+ even-left: $N;
+ even-center: $T, v$[revision];
+ even-right: $D;
+ }
+}
+
+body {
+ font-size: 12pt;
+ text-align: justify;
+}
+
+pre {
+ font-size: 10pt;
+}
diff --git a/documentation/cxx/tree/reference/footer.html b/documentation/cxx/tree/reference/footer.html
new file mode 100644
index 0000000..d4aeff6
--- /dev/null
+++ b/documentation/cxx/tree/reference/footer.html
@@ -0,0 +1,6 @@
+<hr size="1">
+<div style="text-align: center; font-size: 80%;">
+ Copyright &copy; 2005-2009 CODE SYNTHESIS TOOLS CC
+</div>
+</body>
+</html>
diff --git a/documentation/cxx/tree/reference/libxsd.doxygen b/documentation/cxx/tree/reference/libxsd.doxygen
new file mode 100644
index 0000000..3f524d1
--- /dev/null
+++ b/documentation/cxx/tree/reference/libxsd.doxygen
@@ -0,0 +1,1316 @@
+# Doxyfile 1.5.4
+
+# This file describes the settings to be used by the documentation system
+# doxygen (www.doxygen.org) for a project
+#
+# All text after a hash (#) is considered a comment and will be ignored
+# The format is:
+# TAG = value [value, ...]
+# For lists items can also be appended using:
+# TAG += value [value, ...]
+# Values that contain spaces should be placed between quotes (" ")
+
+#---------------------------------------------------------------------------
+# Project related configuration options
+#---------------------------------------------------------------------------
+
+# This tag specifies the encoding used for all characters in the config file that
+# follow. The default is UTF-8 which is also the encoding used for all text before
+# the first occurrence of this tag. Doxygen uses libiconv (or the iconv built into
+# libc) for the transcoding. See http://www.gnu.org/software/libiconv for the list of
+# possible encodings.
+
+DOXYFILE_ENCODING = UTF-8
+
+# The PROJECT_NAME tag is a single word (or a sequence of words surrounded
+# by quotes) that should identify the project.
+
+PROJECT_NAME = "C++/Tree Mapping Runtime Library"
+
+# The PROJECT_NUMBER tag can be used to enter a project or revision number.
+# This could be handy for archiving the generated documentation or
+# if some version control system is used.
+
+PROJECT_NUMBER =
+
+# The OUTPUT_DIRECTORY tag is used to specify the (relative or absolute)
+# base path where the generated documentation will be put.
+# If a relative path is entered, it will be relative to the location
+# where doxygen was started. If left blank the current directory will be used.
+
+OUTPUT_DIRECTORY =
+
+# If the CREATE_SUBDIRS tag is set to YES, then doxygen will create
+# 4096 sub-directories (in 2 levels) under the output directory of each output
+# format and will distribute the generated files over these directories.
+# Enabling this option can be useful when feeding doxygen a huge amount of
+# source files, where putting all generated files in the same directory would
+# otherwise cause performance problems for the file system.
+
+CREATE_SUBDIRS = NO
+
+# The OUTPUT_LANGUAGE tag is used to specify the language in which all
+# documentation generated by doxygen is written. Doxygen will use this
+# information to generate all constant output in the proper language.
+# The default language is English, other supported languages are:
+# Afrikaans, Arabic, Brazilian, Catalan, Chinese, Chinese-Traditional,
+# Croatian, Czech, Danish, Dutch, Finnish, French, German, Greek, Hungarian,
+# Italian, Japanese, Japanese-en (Japanese with English messages), Korean,
+# Korean-en, Lithuanian, Norwegian, Polish, Portuguese, Romanian, Russian,
+# Serbian, Slovak, Slovene, Spanish, Swedish, and Ukrainian.
+
+OUTPUT_LANGUAGE = English
+
+# If the BRIEF_MEMBER_DESC tag is set to YES (the default) Doxygen will
+# include brief member descriptions after the members that are listed in
+# the file and class documentation (similar to JavaDoc).
+# Set to NO to disable this.
+
+BRIEF_MEMBER_DESC = YES
+
+# If the REPEAT_BRIEF tag is set to YES (the default) Doxygen will prepend
+# the brief description of a member or function before the detailed description.
+# Note: if both HIDE_UNDOC_MEMBERS and BRIEF_MEMBER_DESC are set to NO, the
+# brief descriptions will be completely suppressed.
+
+REPEAT_BRIEF = YES
+
+# This tag implements a quasi-intelligent brief description abbreviator
+# that is used to form the text in various listings. Each string
+# in this list, if found as the leading text of the brief description, will be
+# stripped from the text and the result after processing the whole list, is
+# used as the annotated text. Otherwise, the brief description is used as-is.
+# If left blank, the following values are used ("$name" is automatically
+# replaced with the name of the entity): "The $name class" "The $name widget"
+# "The $name file" "is" "provides" "specifies" "contains"
+# "represents" "a" "an" "the"
+
+ABBREVIATE_BRIEF =
+
+# If the ALWAYS_DETAILED_SEC and REPEAT_BRIEF tags are both set to YES then
+# Doxygen will generate a detailed section even if there is only a brief
+# description.
+
+ALWAYS_DETAILED_SEC = NO
+
+# If the INLINE_INHERITED_MEMB tag is set to YES, doxygen will show all
+# inherited members of a class in the documentation of that class as if those
+# members were ordinary class members. Constructors, destructors and assignment
+# operators of the base classes will not be shown.
+
+INLINE_INHERITED_MEMB = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then Doxygen will prepend the full
+# path before files name in the file list and in the header files. If set
+# to NO the shortest path that makes the file name unique will be used.
+
+FULL_PATH_NAMES = NO
+
+# If the FULL_PATH_NAMES tag is set to YES then the STRIP_FROM_PATH tag
+# can be used to strip a user-defined part of the path. Stripping is
+# only done if one of the specified strings matches the left-hand part of
+# the path. The tag can be used to show relative paths in the file list.
+# If left blank the directory from which doxygen is run is used as the
+# path to strip.
+
+STRIP_FROM_PATH =
+
+# The STRIP_FROM_INC_PATH tag can be used to strip a user-defined part of
+# the path mentioned in the documentation of a class, which tells
+# the reader which header file to include in order to use a class.
+# If left blank only the name of the header file containing the class
+# definition is used. Otherwise one should specify the include paths that
+# are normally passed to the compiler using the -I flag.
+
+STRIP_FROM_INC_PATH =
+
+# If the SHORT_NAMES tag is set to YES, doxygen will generate much shorter
+# (but less readable) file names. This can be useful is your file systems
+# doesn't support long names like on DOS, Mac, or CD-ROM.
+
+SHORT_NAMES = NO
+
+# If the JAVADOC_AUTOBRIEF tag is set to YES then Doxygen
+# will interpret the first line (until the first dot) of a JavaDoc-style
+# comment as the brief description. If set to NO, the JavaDoc
+# comments will behave just like regular Qt-style comments
+# (thus requiring an explicit @brief command for a brief description.)
+
+JAVADOC_AUTOBRIEF = NO
+
+# If the QT_AUTOBRIEF tag is set to YES then Doxygen will
+# interpret the first line (until the first dot) of a Qt-style
+# comment as the brief description. If set to NO, the comments
+# will behave just like regular Qt-style comments (thus requiring
+# an explicit \brief command for a brief description.)
+
+QT_AUTOBRIEF = NO
+
+# The MULTILINE_CPP_IS_BRIEF tag can be set to YES to make Doxygen
+# treat a multi-line C++ special comment block (i.e. a block of //! or ///
+# comments) as a brief description. This used to be the default behaviour.
+# The new default is to treat a multi-line C++ comment block as a detailed
+# description. Set this tag to YES if you prefer the old behaviour instead.
+
+MULTILINE_CPP_IS_BRIEF = NO
+
+# If the DETAILS_AT_TOP tag is set to YES then Doxygen
+# will output the detailed description near the top, like JavaDoc.
+# If set to NO, the detailed description appears after the member
+# documentation.
+
+DETAILS_AT_TOP = NO
+
+# If the INHERIT_DOCS tag is set to YES (the default) then an undocumented
+# member inherits the documentation from any documented member that it
+# re-implements.
+
+INHERIT_DOCS = YES
+
+# If the SEPARATE_MEMBER_PAGES tag is set to YES, then doxygen will produce
+# a new page for each member. If set to NO, the documentation of a member will
+# be part of the file/class/namespace that contains it.
+
+SEPARATE_MEMBER_PAGES = NO
+
+# The TAB_SIZE tag can be used to set the number of spaces in a tab.
+# Doxygen uses this value to replace tabs by spaces in code fragments.
+
+TAB_SIZE = 8
+
+# This tag can be used to specify a number of aliases that acts
+# as commands in the documentation. An alias has the form "name=value".
+# For example adding "sideeffect=\par Side Effects:\n" will allow you to
+# put the command \sideeffect (or @sideeffect) in the documentation, which
+# will result in a user-defined paragraph with heading "Side Effects:".
+# You can put \n's in the value part of an alias to insert newlines.
+
+ALIASES =
+
+# Set the OPTIMIZE_OUTPUT_FOR_C tag to YES if your project consists of C
+# sources only. Doxygen will then generate output that is more tailored for C.
+# For instance, some of the names that are used will be different. The list
+# of all members will be omitted, etc.
+
+OPTIMIZE_OUTPUT_FOR_C = NO
+
+# Set the OPTIMIZE_OUTPUT_JAVA tag to YES if your project consists of Java
+# sources only. Doxygen will then generate output that is more tailored for Java.
+# For instance, namespaces will be presented as packages, qualified scopes
+# will look different, etc.
+
+OPTIMIZE_OUTPUT_JAVA = NO
+
+# If you use STL classes (i.e. std::string, std::vector, etc.) but do not want to
+# include (a tag file for) the STL sources as input, then you should
+# set this tag to YES in order to let doxygen match functions declarations and
+# definitions whose arguments contain STL classes (e.g. func(std::string); v.s.
+# func(std::string) {}). This also make the inheritance and collaboration
+# diagrams that involve STL classes more complete and accurate.
+
+BUILTIN_STL_SUPPORT = YES
+
+# If you use Microsoft's C++/CLI language, you should set this option to YES to
+# enable parsing support.
+
+CPP_CLI_SUPPORT = NO
+
+# Set the SIP_SUPPORT tag to YES if your project consists of sip sources only.
+# Doxygen will parse them like normal C++ but will assume all classes use public
+# instead of private inheritance when no explicit protection keyword is present.
+
+SIP_SUPPORT = NO
+
+# If member grouping is used in the documentation and the DISTRIBUTE_GROUP_DOC
+# tag is set to YES, then doxygen will reuse the documentation of the first
+# member in the group (if any) for the other members of the group. By default
+# all members of a group must be documented explicitly.
+
+DISTRIBUTE_GROUP_DOC = NO
+
+# Set the SUBGROUPING tag to YES (the default) to allow class member groups of
+# the same type (for instance a group of public functions) to be put as a
+# subgroup of that type (e.g. under the Public Functions section). Set it to
+# NO to prevent subgrouping. Alternatively, this can be done per class using
+# the \nosubgrouping command.
+
+SUBGROUPING = YES
+
+# When TYPEDEF_HIDES_STRUCT is enabled, a typedef of a struct (or union) is
+# documented as struct with the name of the typedef. So
+# typedef struct TypeS {} TypeT, will appear in the documentation as a struct
+# with name TypeT. When disabled the typedef will appear as a member of a file,
+# namespace, or class. And the struct will be named TypeS. This can typically
+# be useful for C code where the coding convention is that all structs are
+# typedef'ed and only the typedef is referenced never the struct's name.
+
+TYPEDEF_HIDES_STRUCT = NO
+
+#---------------------------------------------------------------------------
+# Build related configuration options
+#---------------------------------------------------------------------------
+
+# If the EXTRACT_ALL tag is set to YES doxygen will assume all entities in
+# documentation are documented, even if no documentation was available.
+# Private class members and static file members will be hidden unless
+# the EXTRACT_PRIVATE and EXTRACT_STATIC tags are set to YES
+
+EXTRACT_ALL = NO
+
+# If the EXTRACT_PRIVATE tag is set to YES all private members of a class
+# will be included in the documentation.
+
+EXTRACT_PRIVATE = NO
+
+# If the EXTRACT_STATIC tag is set to YES all static members of a file
+# will be included in the documentation.
+
+EXTRACT_STATIC = NO
+
+# If the EXTRACT_LOCAL_CLASSES tag is set to YES classes (and structs)
+# defined locally in source files will be included in the documentation.
+# If set to NO only classes defined in header files are included.
+
+EXTRACT_LOCAL_CLASSES = YES
+
+# This flag is only useful for Objective-C code. When set to YES local
+# methods, which are defined in the implementation section but not in
+# the interface are included in the documentation.
+# If set to NO (the default) only methods in the interface are included.
+
+EXTRACT_LOCAL_METHODS = NO
+
+# If this flag is set to YES, the members of anonymous namespaces will be extracted
+# and appear in the documentation as a namespace called 'anonymous_namespace{file}',
+# where file will be replaced with the base name of the file that contains the anonymous
+# namespace. By default anonymous namespace are hidden.
+
+EXTRACT_ANON_NSPACES = NO
+
+# If the HIDE_UNDOC_MEMBERS tag is set to YES, Doxygen will hide all
+# undocumented members of documented classes, files or namespaces.
+# If set to NO (the default) these members will be included in the
+# various overviews, but no documentation section is generated.
+# This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_MEMBERS = NO
+
+# If the HIDE_UNDOC_CLASSES tag is set to YES, Doxygen will hide all
+# undocumented classes that are normally visible in the class hierarchy.
+# If set to NO (the default) these classes will be included in the various
+# overviews. This option has no effect if EXTRACT_ALL is enabled.
+
+HIDE_UNDOC_CLASSES = NO
+
+# If the HIDE_FRIEND_COMPOUNDS tag is set to YES, Doxygen will hide all
+# friend (class|struct|union) declarations.
+# If set to NO (the default) these declarations will be included in the
+# documentation.
+
+HIDE_FRIEND_COMPOUNDS = NO
+
+# If the HIDE_IN_BODY_DOCS tag is set to YES, Doxygen will hide any
+# documentation blocks found inside the body of a function.
+# If set to NO (the default) these blocks will be appended to the
+# function's detailed documentation block.
+
+HIDE_IN_BODY_DOCS = NO
+
+# The INTERNAL_DOCS tag determines if documentation
+# that is typed after a \internal command is included. If the tag is set
+# to NO (the default) then the documentation will be excluded.
+# Set it to YES to include the internal documentation.
+
+INTERNAL_DOCS = NO
+
+# If the CASE_SENSE_NAMES tag is set to NO then Doxygen will only generate
+# file names in lower-case letters. If set to YES upper-case letters are also
+# allowed. This is useful if you have classes or files whose names only differ
+# in case and if your file system supports case sensitive file names. Windows
+# and Mac users are advised to set this option to NO.
+
+CASE_SENSE_NAMES = YES
+
+# If the HIDE_SCOPE_NAMES tag is set to NO (the default) then Doxygen
+# will show members with their full class and namespace scopes in the
+# documentation. If set to YES the scope will be hidden.
+
+HIDE_SCOPE_NAMES = YES
+
+# If the SHOW_INCLUDE_FILES tag is set to YES (the default) then Doxygen
+# will put a list of the files that are included by a file in the documentation
+# of that file.
+
+SHOW_INCLUDE_FILES = NO
+
+# If the INLINE_INFO tag is set to YES (the default) then a tag [inline]
+# is inserted in the documentation for inline members.
+
+INLINE_INFO = YES
+
+# If the SORT_MEMBER_DOCS tag is set to YES (the default) then doxygen
+# will sort the (detailed) documentation of file and class members
+# alphabetically by member name. If set to NO the members will appear in
+# declaration order.
+
+SORT_MEMBER_DOCS = NO
+
+# If the SORT_BRIEF_DOCS tag is set to YES then doxygen will sort the
+# brief documentation of file, namespace and class members alphabetically
+# by member name. If set to NO (the default) the members will appear in
+# declaration order.
+
+SORT_BRIEF_DOCS = NO
+
+# If the SORT_BY_SCOPE_NAME tag is set to YES, the class list will be
+# sorted by fully-qualified names, including namespaces. If set to
+# NO (the default), the class list will be sorted only by class name,
+# not including the namespace part.
+# Note: This option is not very useful if HIDE_SCOPE_NAMES is set to YES.
+# Note: This option applies only to the class list, not to the
+# alphabetical list.
+
+SORT_BY_SCOPE_NAME = NO
+
+# The GENERATE_TODOLIST tag can be used to enable (YES) or
+# disable (NO) the todo list. This list is created by putting \todo
+# commands in the documentation.
+
+GENERATE_TODOLIST = YES
+
+# The GENERATE_TESTLIST tag can be used to enable (YES) or
+# disable (NO) the test list. This list is created by putting \test
+# commands in the documentation.
+
+GENERATE_TESTLIST = YES
+
+# The GENERATE_BUGLIST tag can be used to enable (YES) or
+# disable (NO) the bug list. This list is created by putting \bug
+# commands in the documentation.
+
+GENERATE_BUGLIST = YES
+
+# The GENERATE_DEPRECATEDLIST tag can be used to enable (YES) or
+# disable (NO) the deprecated list. This list is created by putting
+# \deprecated commands in the documentation.
+
+GENERATE_DEPRECATEDLIST= YES
+
+# The ENABLED_SECTIONS tag can be used to enable conditional
+# documentation sections, marked by \if sectionname ... \endif.
+
+ENABLED_SECTIONS =
+
+# The MAX_INITIALIZER_LINES tag determines the maximum number of lines
+# the initial value of a variable or define consists of for it to appear in
+# the documentation. If the initializer consists of more lines than specified
+# here it will be hidden. Use a value of 0 to hide initializers completely.
+# The appearance of the initializer of individual variables and defines in the
+# documentation can be controlled using \showinitializer or \hideinitializer
+# command in the documentation regardless of this setting.
+
+MAX_INITIALIZER_LINES = 30
+
+# Set the SHOW_USED_FILES tag to NO to disable the list of files generated
+# at the bottom of the documentation of classes and structs. If set to YES the
+# list will mention the files that were used to generate the documentation.
+
+SHOW_USED_FILES = YES
+
+# If the sources in your project are distributed over multiple directories
+# then setting the SHOW_DIRECTORIES tag to YES will show the directory hierarchy
+# in the documentation. The default is NO.
+
+SHOW_DIRECTORIES = NO
+
+# The FILE_VERSION_FILTER tag can be used to specify a program or script that
+# doxygen should invoke to get the current version for each file (typically from the
+# version control system). Doxygen will invoke the program by executing (via
+# popen()) the command <command> <input-file>, where <command> is the value of
+# the FILE_VERSION_FILTER tag, and <input-file> is the name of an input file
+# provided by doxygen. Whatever the program writes to standard output
+# is used as the file version. See the manual for examples.
+
+FILE_VERSION_FILTER =
+
+#---------------------------------------------------------------------------
+# configuration options related to warning and progress messages
+#---------------------------------------------------------------------------
+
+# The QUIET tag can be used to turn on/off the messages that are generated
+# by doxygen. Possible values are YES and NO. If left blank NO is used.
+
+QUIET = NO
+
+# The WARNINGS tag can be used to turn on/off the warning messages that are
+# generated by doxygen. Possible values are YES and NO. If left blank
+# NO is used.
+
+WARNINGS = YES
+
+# If WARN_IF_UNDOCUMENTED is set to YES, then doxygen will generate warnings
+# for undocumented members. If EXTRACT_ALL is set to YES then this flag will
+# automatically be disabled.
+
+WARN_IF_UNDOCUMENTED = YES
+
+# If WARN_IF_DOC_ERROR is set to YES, doxygen will generate warnings for
+# potential errors in the documentation, such as not documenting some
+# parameters in a documented function, or documenting parameters that
+# don't exist or using markup commands wrongly.
+
+WARN_IF_DOC_ERROR = YES
+
+# This WARN_NO_PARAMDOC option can be abled to get warnings for
+# functions that are documented, but have no documentation for their parameters
+# or return value. If set to NO (the default) doxygen will only warn about
+# wrong or incomplete parameter documentation, but not about the absence of
+# documentation.
+
+WARN_NO_PARAMDOC = NO
+
+# The WARN_FORMAT tag determines the format of the warning messages that
+# doxygen can produce. The string should contain the $file, $line, and $text
+# tags, which will be replaced by the file and line number from which the
+# warning originated and the warning text. Optionally the format may contain
+# $version, which will be replaced by the version of the file (if it could
+# be obtained via FILE_VERSION_FILTER)
+
+WARN_FORMAT = "$file:$line: $text"
+
+# The WARN_LOGFILE tag can be used to specify a file to which warning
+# and error messages should be written. If left blank the output is written
+# to stderr.
+
+WARN_LOGFILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the input files
+#---------------------------------------------------------------------------
+
+# The INPUT tag can be used to specify the files and/or directories that contain
+# documented source files. You may enter file names like "myfile.cpp" or
+# directories like "/usr/src/myproject". Separate the files or directories
+# with spaces.
+
+INPUT = \
+../../../../libxsd/xsd/cxx/tree/buffer.hxx \
+../../../../libxsd/xsd/cxx/tree/types.hxx \
+../../../../libxsd/xsd/cxx/tree/date-time.hxx \
+../../../../libxsd/xsd/cxx/tree/elements.hxx \
+../../../../libxsd/xsd/cxx/tree/element-map.hxx \
+../../../../libxsd/xsd/cxx/tree/exceptions.hxx
+
+# This tag can be used to specify the character encoding of the source files that
+# doxygen parses. Internally doxygen uses the UTF-8 encoding, which is also the default
+# input encoding. Doxygen uses libiconv (or the iconv built into libc) for the transcoding.
+# See http://www.gnu.org/software/libiconv for the list of possible encodings.
+
+INPUT_ENCODING = UTF-8
+
+# If the value of the INPUT tag contains directories, you can use the
+# FILE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank the following patterns are tested:
+# *.c *.cc *.cxx *.cpp *.c++ *.java *.ii *.ixx *.ipp *.i++ *.inl *.h *.hh *.hxx
+# *.hpp *.h++ *.idl *.odl *.cs *.php *.php3 *.inc *.m *.mm *.py *.f90
+
+FILE_PATTERNS =
+
+# The RECURSIVE tag can be used to turn specify whether or not subdirectories
+# should be searched for input files as well. Possible values are YES and NO.
+# If left blank NO is used.
+
+RECURSIVE = NO
+
+# The EXCLUDE tag can be used to specify files and/or directories that should
+# excluded from the INPUT source files. This way you can easily exclude a
+# subdirectory from a directory tree whose root is specified with the INPUT tag.
+
+EXCLUDE =
+
+# The EXCLUDE_SYMLINKS tag can be used select whether or not files or
+# directories that are symbolic links (a Unix filesystem feature) are excluded
+# from the input.
+
+EXCLUDE_SYMLINKS = NO
+
+# If the value of the INPUT tag contains directories, you can use the
+# EXCLUDE_PATTERNS tag to specify one or more wildcard patterns to exclude
+# certain files from those directories. Note that the wildcards are matched
+# against the file with absolute path, so to exclude all test directories
+# for example use the pattern */test/*
+
+EXCLUDE_PATTERNS =
+
+# The EXCLUDE_SYMBOLS tag can be used to specify one or more symbol names
+# (namespaces, classes, functions, etc.) that should be excluded from the output.
+# The symbol name can be a fully qualified name, a word, or if the wildcard * is used,
+# a substring. Examples: ANamespace, AClass, AClass::ANamespace, ANamespace::*Test
+
+EXCLUDE_SYMBOLS =
+
+# The EXAMPLE_PATH tag can be used to specify one or more files or
+# directories that contain example code fragments that are included (see
+# the \include command).
+
+EXAMPLE_PATH =
+
+# If the value of the EXAMPLE_PATH tag contains directories, you can use the
+# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp
+# and *.h) to filter out the source-files in the directories. If left
+# blank all files are included.
+
+EXAMPLE_PATTERNS =
+
+# If the EXAMPLE_RECURSIVE tag is set to YES then subdirectories will be
+# searched for input files to be used with the \include or \dontinclude
+# commands irrespective of the value of the RECURSIVE tag.
+# Possible values are YES and NO. If left blank NO is used.
+
+EXAMPLE_RECURSIVE = NO
+
+# The IMAGE_PATH tag can be used to specify one or more files or
+# directories that contain image that are included in the documentation (see
+# the \image command).
+
+IMAGE_PATH =
+
+# The INPUT_FILTER tag can be used to specify a program that doxygen should
+# invoke to filter for each input file. Doxygen will invoke the filter program
+# by executing (via popen()) the command <filter> <input-file>, where <filter>
+# is the value of the INPUT_FILTER tag, and <input-file> is the name of an
+# input file. Doxygen will then use the output that the filter program writes
+# to standard output. If FILTER_PATTERNS is specified, this tag will be
+# ignored.
+
+INPUT_FILTER =
+
+# The FILTER_PATTERNS tag can be used to specify filters on a per file pattern
+# basis. Doxygen will compare the file name with each pattern and apply the
+# filter if there is a match. The filters are a list of the form:
+# pattern=filter (like *.cpp=my_cpp_filter). See INPUT_FILTER for further
+# info on how filters are used. If FILTER_PATTERNS is empty, INPUT_FILTER
+# is applied to all files.
+
+FILTER_PATTERNS =
+
+# If the FILTER_SOURCE_FILES tag is set to YES, the input filter (if set using
+# INPUT_FILTER) will be used to filter the input files when producing source
+# files to browse (i.e. when SOURCE_BROWSER is set to YES).
+
+FILTER_SOURCE_FILES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to source browsing
+#---------------------------------------------------------------------------
+
+# If the SOURCE_BROWSER tag is set to YES then a list of source files will
+# be generated. Documented entities will be cross-referenced with these sources.
+# Note: To get rid of all source code in the generated output, make sure also
+# VERBATIM_HEADERS is set to NO. If you have enabled CALL_GRAPH or CALLER_GRAPH
+# then you must also enable this option. If you don't then doxygen will produce
+# a warning and turn it on anyway
+
+SOURCE_BROWSER = NO
+
+# Setting the INLINE_SOURCES tag to YES will include the body
+# of functions and classes directly in the documentation.
+
+INLINE_SOURCES = NO
+
+# Setting the STRIP_CODE_COMMENTS tag to YES (the default) will instruct
+# doxygen to hide any special comment blocks from generated source code
+# fragments. Normal C and C++ comments will always remain visible.
+
+STRIP_CODE_COMMENTS = YES
+
+# If the REFERENCED_BY_RELATION tag is set to YES (the default)
+# then for each documented function all documented
+# functions referencing it will be listed.
+
+REFERENCED_BY_RELATION = YES
+
+# If the REFERENCES_RELATION tag is set to YES (the default)
+# then for each documented function all documented entities
+# called/used by that function will be listed.
+
+REFERENCES_RELATION = YES
+
+# If the REFERENCES_LINK_SOURCE tag is set to YES (the default)
+# and SOURCE_BROWSER tag is set to YES, then the hyperlinks from
+# functions in REFERENCES_RELATION and REFERENCED_BY_RELATION lists will
+# link to the source code. Otherwise they will link to the documentstion.
+
+REFERENCES_LINK_SOURCE = YES
+
+# If the USE_HTAGS tag is set to YES then the references to source code
+# will point to the HTML generated by the htags(1) tool instead of doxygen
+# built-in source browser. The htags tool is part of GNU's global source
+# tagging system (see http://www.gnu.org/software/global/global.html). You
+# will need version 4.8.6 or higher.
+
+USE_HTAGS = NO
+
+# If the VERBATIM_HEADERS tag is set to YES (the default) then Doxygen
+# will generate a verbatim copy of the header file for each class for
+# which an include is specified. Set to NO to disable this.
+
+VERBATIM_HEADERS = YES
+
+#---------------------------------------------------------------------------
+# configuration options related to the alphabetical class index
+#---------------------------------------------------------------------------
+
+# If the ALPHABETICAL_INDEX tag is set to YES, an alphabetical index
+# of all compounds will be generated. Enable this if the project
+# contains a lot of classes, structs, unions or interfaces.
+
+ALPHABETICAL_INDEX = NO
+
+# If the alphabetical index is enabled (see ALPHABETICAL_INDEX) then
+# the COLS_IN_ALPHA_INDEX tag can be used to specify the number of columns
+# in which this list will be split (can be a number in the range [1..20])
+
+COLS_IN_ALPHA_INDEX = 5
+
+# In case all classes in a project start with a common prefix, all
+# classes will be put under the same header in the alphabetical index.
+# The IGNORE_PREFIX tag can be used to specify one or more prefixes that
+# should be ignored while generating the index headers.
+
+IGNORE_PREFIX =
+
+#---------------------------------------------------------------------------
+# configuration options related to the HTML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_HTML tag is set to YES (the default) Doxygen will
+# generate HTML output.
+
+GENERATE_HTML = YES
+
+# The HTML_OUTPUT tag is used to specify where the HTML docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `html' will be used as the default path.
+
+HTML_OUTPUT = html
+
+# The HTML_FILE_EXTENSION tag can be used to specify the file extension for
+# each generated HTML page (for example: .htm,.php,.asp). If it is left blank
+# doxygen will generate files with .html extension.
+
+HTML_FILE_EXTENSION = .html
+
+# The HTML_HEADER tag can be used to specify a personal HTML header for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard header.
+
+HTML_HEADER =
+
+# The HTML_FOOTER tag can be used to specify a personal HTML footer for
+# each generated HTML page. If it is left blank doxygen will generate a
+# standard footer.
+
+HTML_FOOTER = footer.html
+
+# The HTML_STYLESHEET tag can be used to specify a user-defined cascading
+# style sheet that is used by each HTML page. It can be used to
+# fine-tune the look of the HTML output. If the tag is left blank doxygen
+# will generate a default style sheet. Note that doxygen will try to copy
+# the style sheet file to the HTML output directory, so don't put your own
+# stylesheet in the HTML output directory as well, or it will be erased!
+
+HTML_STYLESHEET =
+
+# If the HTML_ALIGN_MEMBERS tag is set to YES, the members of classes,
+# files or namespaces will be aligned in HTML using tables. If set to
+# NO a bullet list will be used.
+
+HTML_ALIGN_MEMBERS = YES
+
+# If the GENERATE_HTMLHELP tag is set to YES, additional index files
+# will be generated that can be used as input for tools like the
+# Microsoft HTML help workshop to generate a compressed HTML help file (.chm)
+# of the generated HTML documentation.
+
+GENERATE_HTMLHELP = NO
+
+# If the HTML_DYNAMIC_SECTIONS tag is set to YES then the generated HTML
+# documentation will contain sections that can be hidden and shown after the
+# page has loaded. For this to work a browser that supports
+# JavaScript and DHTML is required (for instance Mozilla 1.0+, Firefox
+# Netscape 6.0+, Internet explorer 5.0+, Konqueror, or Safari).
+
+HTML_DYNAMIC_SECTIONS = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the CHM_FILE tag can
+# be used to specify the file name of the resulting .chm file. You
+# can add a path in front of the file if the result should not be
+# written to the html output directory.
+
+CHM_FILE =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the HHC_LOCATION tag can
+# be used to specify the location (absolute path including file name) of
+# the HTML help compiler (hhc.exe). If non-empty doxygen will try to run
+# the HTML help compiler on the generated index.hhp.
+
+HHC_LOCATION =
+
+# If the GENERATE_HTMLHELP tag is set to YES, the GENERATE_CHI flag
+# controls if a separate .chi index file is generated (YES) or that
+# it should be included in the master .chm file (NO).
+
+GENERATE_CHI = NO
+
+# If the GENERATE_HTMLHELP tag is set to YES, the BINARY_TOC flag
+# controls whether a binary table of contents is generated (YES) or a
+# normal table of contents (NO) in the .chm file.
+
+BINARY_TOC = NO
+
+# The TOC_EXPAND flag can be set to YES to add extra items for group members
+# to the contents of the HTML help documentation and to the tree view.
+
+TOC_EXPAND = NO
+
+# The DISABLE_INDEX tag can be used to turn on/off the condensed index at
+# top of each HTML page. The value NO (the default) enables the index and
+# the value YES disables it.
+
+DISABLE_INDEX = NO
+
+# This tag can be used to set the number of enum values (range [1..20])
+# that doxygen will group on one line in the generated HTML documentation.
+
+ENUM_VALUES_PER_LINE = 4
+
+# If the GENERATE_TREEVIEW tag is set to YES, a side panel will be
+# generated containing a tree-like index structure (just like the one that
+# is generated for HTML Help). For this to work a browser that supports
+# JavaScript, DHTML, CSS and frames is required (for instance Mozilla 1.0+,
+# Netscape 6.0+, Internet explorer 5.0+, or Konqueror). Windows users are
+# probably better off using the HTML help feature.
+
+GENERATE_TREEVIEW = NO
+
+# If the treeview is enabled (see GENERATE_TREEVIEW) then this tag can be
+# used to set the initial width (in pixels) of the frame in which the tree
+# is shown.
+
+TREEVIEW_WIDTH = 250
+
+#---------------------------------------------------------------------------
+# configuration options related to the LaTeX output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_LATEX tag is set to YES (the default) Doxygen will
+# generate Latex output.
+
+GENERATE_LATEX = NO
+
+# The LATEX_OUTPUT tag is used to specify where the LaTeX docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `latex' will be used as the default path.
+
+LATEX_OUTPUT = latex
+
+# The LATEX_CMD_NAME tag can be used to specify the LaTeX command name to be
+# invoked. If left blank `latex' will be used as the default command name.
+
+LATEX_CMD_NAME = latex
+
+# The MAKEINDEX_CMD_NAME tag can be used to specify the command name to
+# generate index for LaTeX. If left blank `makeindex' will be used as the
+# default command name.
+
+MAKEINDEX_CMD_NAME = makeindex
+
+# If the COMPACT_LATEX tag is set to YES Doxygen generates more compact
+# LaTeX documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_LATEX = NO
+
+# The PAPER_TYPE tag can be used to set the paper type that is used
+# by the printer. Possible values are: a4, a4wide, letter, legal and
+# executive. If left blank a4wide will be used.
+
+PAPER_TYPE = a4wide
+
+# The EXTRA_PACKAGES tag can be to specify one or more names of LaTeX
+# packages that should be included in the LaTeX output.
+
+EXTRA_PACKAGES =
+
+# The LATEX_HEADER tag can be used to specify a personal LaTeX header for
+# the generated latex document. The header should contain everything until
+# the first chapter. If it is left blank doxygen will generate a
+# standard header. Notice: only use this tag if you know what you are doing!
+
+LATEX_HEADER =
+
+# If the PDF_HYPERLINKS tag is set to YES, the LaTeX that is generated
+# is prepared for conversion to pdf (using ps2pdf). The pdf file will
+# contain links (just like the HTML output) instead of page references
+# This makes the output suitable for online browsing using a pdf viewer.
+
+PDF_HYPERLINKS = NO
+
+# If the USE_PDFLATEX tag is set to YES, pdflatex will be used instead of
+# plain latex in the generated Makefile. Set this option to YES to get a
+# higher quality PDF documentation.
+
+USE_PDFLATEX = NO
+
+# If the LATEX_BATCHMODE tag is set to YES, doxygen will add the \\batchmode.
+# command to the generated LaTeX files. This will instruct LaTeX to keep
+# running if errors occur, instead of asking the user for help.
+# This option is also used when generating formulas in HTML.
+
+LATEX_BATCHMODE = NO
+
+# If LATEX_HIDE_INDICES is set to YES then doxygen will not
+# include the index chapters (such as File Index, Compound Index, etc.)
+# in the output.
+
+LATEX_HIDE_INDICES = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the RTF output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_RTF tag is set to YES Doxygen will generate RTF output
+# The RTF output is optimized for Word 97 and may not look very pretty with
+# other RTF readers or editors.
+
+GENERATE_RTF = NO
+
+# The RTF_OUTPUT tag is used to specify where the RTF docs will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `rtf' will be used as the default path.
+
+RTF_OUTPUT = rtf
+
+# If the COMPACT_RTF tag is set to YES Doxygen generates more compact
+# RTF documents. This may be useful for small projects and may help to
+# save some trees in general.
+
+COMPACT_RTF = NO
+
+# If the RTF_HYPERLINKS tag is set to YES, the RTF that is generated
+# will contain hyperlink fields. The RTF file will
+# contain links (just like the HTML output) instead of page references.
+# This makes the output suitable for online browsing using WORD or other
+# programs which support those fields.
+# Note: wordpad (write) and others do not support links.
+
+RTF_HYPERLINKS = NO
+
+# Load stylesheet definitions from file. Syntax is similar to doxygen's
+# config file, i.e. a series of assignments. You only have to provide
+# replacements, missing definitions are set to their default value.
+
+RTF_STYLESHEET_FILE =
+
+# Set optional variables used in the generation of an rtf document.
+# Syntax is similar to doxygen's config file.
+
+RTF_EXTENSIONS_FILE =
+
+#---------------------------------------------------------------------------
+# configuration options related to the man page output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_MAN tag is set to YES (the default) Doxygen will
+# generate man pages
+
+GENERATE_MAN = NO
+
+# The MAN_OUTPUT tag is used to specify where the man pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `man' will be used as the default path.
+
+MAN_OUTPUT = man
+
+# The MAN_EXTENSION tag determines the extension that is added to
+# the generated man pages (default is the subroutine's section .3)
+
+MAN_EXTENSION = .3
+
+# If the MAN_LINKS tag is set to YES and Doxygen generates man output,
+# then it will generate one additional man file for each entity
+# documented in the real man page(s). These additional files
+# only source the real man page, but without them the man command
+# would be unable to find the correct page. The default is NO.
+
+MAN_LINKS = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the XML output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_XML tag is set to YES Doxygen will
+# generate an XML file that captures the structure of
+# the code including all documentation.
+
+GENERATE_XML = NO
+
+# The XML_OUTPUT tag is used to specify where the XML pages will be put.
+# If a relative path is entered the value of OUTPUT_DIRECTORY will be
+# put in front of it. If left blank `xml' will be used as the default path.
+
+XML_OUTPUT = xml
+
+# The XML_SCHEMA tag can be used to specify an XML schema,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_SCHEMA =
+
+# The XML_DTD tag can be used to specify an XML DTD,
+# which can be used by a validating XML parser to check the
+# syntax of the XML files.
+
+XML_DTD =
+
+# If the XML_PROGRAMLISTING tag is set to YES Doxygen will
+# dump the program listings (including syntax highlighting
+# and cross-referencing information) to the XML output. Note that
+# enabling this will significantly increase the size of the XML output.
+
+XML_PROGRAMLISTING = YES
+
+#---------------------------------------------------------------------------
+# configuration options for the AutoGen Definitions output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_AUTOGEN_DEF tag is set to YES Doxygen will
+# generate an AutoGen Definitions (see autogen.sf.net) file
+# that captures the structure of the code including all
+# documentation. Note that this feature is still experimental
+# and incomplete at the moment.
+
+GENERATE_AUTOGEN_DEF = NO
+
+#---------------------------------------------------------------------------
+# configuration options related to the Perl module output
+#---------------------------------------------------------------------------
+
+# If the GENERATE_PERLMOD tag is set to YES Doxygen will
+# generate a Perl module file that captures the structure of
+# the code including all documentation. Note that this
+# feature is still experimental and incomplete at the
+# moment.
+
+GENERATE_PERLMOD = NO
+
+# If the PERLMOD_LATEX tag is set to YES Doxygen will generate
+# the necessary Makefile rules, Perl scripts and LaTeX code to be able
+# to generate PDF and DVI output from the Perl module output.
+
+PERLMOD_LATEX = NO
+
+# If the PERLMOD_PRETTY tag is set to YES the Perl module output will be
+# nicely formatted so it can be parsed by a human reader. This is useful
+# if you want to understand what is going on. On the other hand, if this
+# tag is set to NO the size of the Perl module output will be much smaller
+# and Perl will parse it just the same.
+
+PERLMOD_PRETTY = YES
+
+# The names of the make variables in the generated doxyrules.make file
+# are prefixed with the string contained in PERLMOD_MAKEVAR_PREFIX.
+# This is useful so different doxyrules.make files included by the same
+# Makefile don't overwrite each other's variables.
+
+PERLMOD_MAKEVAR_PREFIX =
+
+#---------------------------------------------------------------------------
+# Configuration options related to the preprocessor
+#---------------------------------------------------------------------------
+
+# If the ENABLE_PREPROCESSING tag is set to YES (the default) Doxygen will
+# evaluate all C-preprocessor directives found in the sources and include
+# files.
+
+ENABLE_PREPROCESSING = YES
+
+# If the MACRO_EXPANSION tag is set to YES Doxygen will expand all macro
+# names in the source code. If set to NO (the default) only conditional
+# compilation will be performed. Macro expansion can be done in a controlled
+# way by setting EXPAND_ONLY_PREDEF to YES.
+
+MACRO_EXPANSION = NO
+
+# If the EXPAND_ONLY_PREDEF and MACRO_EXPANSION tags are both set to YES
+# then the macro expansion is limited to the macros specified with the
+# PREDEFINED and EXPAND_AS_DEFINED tags.
+
+EXPAND_ONLY_PREDEF = NO
+
+# If the SEARCH_INCLUDES tag is set to YES (the default) the includes files
+# in the INCLUDE_PATH (see below) will be search if a #include is found.
+
+SEARCH_INCLUDES = YES
+
+# The INCLUDE_PATH tag can be used to specify one or more directories that
+# contain include files that are not input files but should be processed by
+# the preprocessor.
+
+INCLUDE_PATH =
+
+# You can use the INCLUDE_FILE_PATTERNS tag to specify one or more wildcard
+# patterns (like *.h and *.hpp) to filter out the header-files in the
+# directories. If left blank, the patterns specified with FILE_PATTERNS will
+# be used.
+
+INCLUDE_FILE_PATTERNS =
+
+# The PREDEFINED tag can be used to specify one or more macro names that
+# are defined before the preprocessor is started (similar to the -D option of
+# gcc). The argument of the tag is a list of macros of the form: name
+# or name=definition (no spaces). If the definition and the = are
+# omitted =1 is assumed. To prevent a macro definition from being
+# undefined via #undef or recursively expanded use the := operator
+# instead of the = operator.
+
+PREDEFINED =
+
+# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
+# this tag can be used to specify a list of macro names that should be expanded.
+# The macro definition that is found in the sources will be used.
+# Use the PREDEFINED tag if you want to use a different macro definition.
+
+EXPAND_AS_DEFINED =
+
+# If the SKIP_FUNCTION_MACROS tag is set to YES (the default) then
+# doxygen's preprocessor will remove all function-like macros that are alone
+# on a line, have an all uppercase name, and do not end with a semicolon. Such
+# function macros are typically used for boiler-plate code, and will confuse
+# the parser if not removed.
+
+SKIP_FUNCTION_MACROS = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to external references
+#---------------------------------------------------------------------------
+
+# The TAGFILES option can be used to specify one or more tagfiles.
+# Optionally an initial location of the external documentation
+# can be added for each tagfile. The format of a tag file without
+# this location is as follows:
+# TAGFILES = file1 file2 ...
+# Adding location for the tag files is done as follows:
+# TAGFILES = file1=loc1 "file2 = loc2" ...
+# where "loc1" and "loc2" can be relative or absolute paths or
+# URLs. If a location is present for each tag, the installdox tool
+# does not have to be run to correct the links.
+# Note that each tag file must have a unique name
+# (where the name does NOT include the path)
+# If a tag file is not located in the directory in which doxygen
+# is run, you must also specify the path to the tagfile here.
+
+TAGFILES =
+
+# When a file name is specified after GENERATE_TAGFILE, doxygen will create
+# a tag file that is based on the input files it reads.
+
+GENERATE_TAGFILE = libxsd.doxytag
+
+# If the ALLEXTERNALS tag is set to YES all external classes will be listed
+# in the class index. If set to NO only the inherited external classes
+# will be listed.
+
+ALLEXTERNALS = NO
+
+# If the EXTERNAL_GROUPS tag is set to YES all external groups will be listed
+# in the modules index. If set to NO, only the current project's groups will
+# be listed.
+
+EXTERNAL_GROUPS = YES
+
+# The PERL_PATH should be the absolute path and name of the perl script
+# interpreter (i.e. the result of `which perl').
+
+PERL_PATH = /usr/bin/perl
+
+#---------------------------------------------------------------------------
+# Configuration options related to the dot tool
+#---------------------------------------------------------------------------
+
+# If the CLASS_DIAGRAMS tag is set to YES (the default) Doxygen will
+# generate a inheritance diagram (in HTML, RTF and LaTeX) for classes with base
+# or super classes. Setting the tag to NO turns the diagrams off. Note that
+# this option is superseded by the HAVE_DOT option below. This is only a
+# fallback. It is recommended to install and use dot, since it yields more
+# powerful graphs.
+
+CLASS_DIAGRAMS = YES
+
+# You can define message sequence charts within doxygen comments using the \msc
+# command. Doxygen will then run the mscgen tool (see http://www.mcternan.me.uk/mscgen/) to
+# produce the chart and insert it in the documentation. The MSCGEN_PATH tag allows you to
+# specify the directory where the mscgen tool resides. If left empty the tool is assumed to
+# be found in the default search path.
+
+MSCGEN_PATH =
+
+# If set to YES, the inheritance and collaboration graphs will hide
+# inheritance and usage relations if the target is undocumented
+# or is not a class.
+
+HIDE_UNDOC_RELATIONS = YES
+
+# If you set the HAVE_DOT tag to YES then doxygen will assume the dot tool is
+# available from the path. This tool is part of Graphviz, a graph visualization
+# toolkit from AT&T and Lucent Bell Labs. The other options in this section
+# have no effect if this option is set to NO (the default)
+
+HAVE_DOT = NO
+
+# If the CLASS_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect inheritance relations. Setting this tag to YES will force the
+# the CLASS_DIAGRAMS tag to NO.
+
+CLASS_GRAPH = YES
+
+# If the COLLABORATION_GRAPH and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for each documented class showing the direct and
+# indirect implementation dependencies (inheritance, containment, and
+# class references variables) of the class with other documented classes.
+
+COLLABORATION_GRAPH = YES
+
+# If the GROUP_GRAPHS and HAVE_DOT tags are set to YES then doxygen
+# will generate a graph for groups, showing the direct groups dependencies
+
+GROUP_GRAPHS = YES
+
+# If the UML_LOOK tag is set to YES doxygen will generate inheritance and
+# collaboration diagrams in a style similar to the OMG's Unified Modeling
+# Language.
+
+UML_LOOK = NO
+
+# If set to YES, the inheritance and collaboration graphs will show the
+# relations between templates and their instances.
+
+TEMPLATE_RELATIONS = NO
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDE_GRAPH, and HAVE_DOT
+# tags are set to YES then doxygen will generate a graph for each documented
+# file showing the direct and indirect include dependencies of the file with
+# other documented files.
+
+INCLUDE_GRAPH = YES
+
+# If the ENABLE_PREPROCESSING, SEARCH_INCLUDES, INCLUDED_BY_GRAPH, and
+# HAVE_DOT tags are set to YES then doxygen will generate a graph for each
+# documented header file showing the documented files that directly or
+# indirectly include this file.
+
+INCLUDED_BY_GRAPH = YES
+
+# If the CALL_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
+# generate a call dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable call graphs for selected
+# functions only using the \callgraph command.
+
+CALL_GRAPH = NO
+
+# If the CALLER_GRAPH, SOURCE_BROWSER and HAVE_DOT tags are set to YES then doxygen will
+# generate a caller dependency graph for every global function or class method.
+# Note that enabling this option will significantly increase the time of a run.
+# So in most cases it will be better to enable caller graphs for selected
+# functions only using the \callergraph command.
+
+CALLER_GRAPH = NO
+
+# If the GRAPHICAL_HIERARCHY and HAVE_DOT tags are set to YES then doxygen
+# will graphical hierarchy of all classes instead of a textual one.
+
+GRAPHICAL_HIERARCHY = YES
+
+# If the DIRECTORY_GRAPH, SHOW_DIRECTORIES and HAVE_DOT tags are set to YES
+# then doxygen will show the dependencies a directory has on other directories
+# in a graphical way. The dependency relations are determined by the #include
+# relations between the files in the directories.
+
+DIRECTORY_GRAPH = YES
+
+# The DOT_IMAGE_FORMAT tag can be used to set the image format of the images
+# generated by dot. Possible values are png, jpg, or gif
+# If left blank png will be used.
+
+DOT_IMAGE_FORMAT = png
+
+# The tag DOT_PATH can be used to specify the path where the dot tool can be
+# found. If left blank, it is assumed the dot tool can be found in the path.
+
+DOT_PATH =
+
+# The DOTFILE_DIRS tag can be used to specify one or more directories that
+# contain dot files that are included in the documentation (see the
+# \dotfile command).
+
+DOTFILE_DIRS =
+
+# The MAX_DOT_GRAPH_MAX_NODES tag can be used to set the maximum number of
+# nodes that will be shown in the graph. If the number of nodes in a graph
+# becomes larger than this value, doxygen will truncate the graph, which is
+# visualized by representing a node as a red box. Note that doxygen if the number
+# of direct children of the root node in a graph is already larger than
+# MAX_DOT_GRAPH_NOTES then the graph will not be shown at all. Also note
+# that the size of a graph can be further restricted by MAX_DOT_GRAPH_DEPTH.
+
+DOT_GRAPH_MAX_NODES = 50
+
+# The MAX_DOT_GRAPH_DEPTH tag can be used to set the maximum depth of the
+# graphs generated by dot. A depth value of 3 means that only nodes reachable
+# from the root by following a path via at most 3 edges will be shown. Nodes
+# that lay further from the root node will be omitted. Note that setting this
+# option to 1 or 2 may greatly reduce the computation time needed for large
+# code bases. Also note that the size of a graph can be further restricted by
+# DOT_GRAPH_MAX_NODES. Using a depth of 0 means no depth restriction.
+
+MAX_DOT_GRAPH_DEPTH = 0
+
+# Set the DOT_TRANSPARENT tag to YES to generate images with a transparent
+# background. This is disabled by default, which results in a white background.
+# Warning: Depending on the platform used, enabling this option may lead to
+# badly anti-aliased labels on the edges of a graph (i.e. they become hard to
+# read).
+
+DOT_TRANSPARENT = YES
+
+# Set the DOT_MULTI_TARGETS tag to YES allow dot to generate multiple output
+# files in one run (i.e. multiple -o and -T options on the command line). This
+# makes dot run faster, but since only newer versions of dot (>1.8.10)
+# support this, this feature is disabled by default.
+
+DOT_MULTI_TARGETS = NO
+
+# If the GENERATE_LEGEND tag is set to YES (the default) Doxygen will
+# generate a legend page explaining the meaning of the various boxes and
+# arrows in the dot generated graphs.
+
+GENERATE_LEGEND = YES
+
+# If the DOT_CLEANUP tag is set to YES (the default) Doxygen will
+# remove the intermediate dot files that are used to generate
+# the various graphs.
+
+DOT_CLEANUP = YES
+
+#---------------------------------------------------------------------------
+# Configuration::additions related to the search engine
+#---------------------------------------------------------------------------
+
+# The SEARCHENGINE tag specifies whether or not a search engine should be
+# used. If set to NO the values of all tags below this one will be ignored.
+
+SEARCHENGINE = NO
diff --git a/documentation/cxx/tree/reference/makefile b/documentation/cxx/tree/reference/makefile
new file mode 100644
index 0000000..5df62c9
--- /dev/null
+++ b/documentation/cxx/tree/reference/makefile
@@ -0,0 +1,18 @@
+.PHONY: all
+all: libxsd.doxytag
+
+headers := \
+../../../../libxsd/xsd/cxx/tree/buffer.hxx \
+../../../../libxsd/xsd/cxx/tree/types.hxx \
+../../../../libxsd/xsd/cxx/tree/date-time.hxx \
+../../../../libxsd/xsd/cxx/tree/elements.hxx \
+../../../../libxsd/xsd/cxx/tree/exceptions.hxx
+
+libxsd.doxytag: libxsd.doxygen footer.html $(headers)
+ doxygen $<
+
+.PHONY: clean
+clean:
+ rm -f libxsd.doxytag
+ rm -rf html
+
diff --git a/documentation/default.css b/documentation/default.css
new file mode 100644
index 0000000..bb3805b
--- /dev/null
+++ b/documentation/default.css
@@ -0,0 +1,319 @@
+html {
+ margin : 0;
+ padding : 0;
+ background : white;
+}
+
+body {
+ font-family : "Lucida Grande", Verdana, "Bitstream Vera Sans", sans-serif;
+ font-weight : normal;
+ font-size : 13px;
+ line-height : 19px;
+
+ color : black;
+
+ margin : 0 2em 0 2em;
+ padding : 0;
+}
+
+
+body {
+ min-width: 40em;
+}
+
+#container {
+ max-width : 46em;
+ margin : 0 auto;
+ padding : 0 1em 0 1em;
+}
+
+
+
+/*
+ * Footer
+ *
+ */
+#footer {
+ color : #3a84a7;
+
+ padding : 1em 0 0.5em 0;
+
+ font-size : 10px;
+ line-height : 15px;
+
+ text-align: center;
+}
+
+#footer a:link, #footer a:visited {
+
+ color:#1d6699;
+ text-decoration: underline;
+}
+
+#footer a {
+ margin-left: 0.7em;
+ margin-right: 0.7em;
+}
+
+#footer p {
+ padding: 0;
+ margin: 0.3em 0 0 0;
+}
+
+/* Distribution terms. */
+#footer #terms {
+ text-align: justify;
+
+ font-size : 110%;
+ font-family : monospace;
+
+ padding : 1em 0 0.5em 0;
+}
+
+
+/*
+ * Content
+ *
+ */
+
+#content {
+ padding : 0em 0.1em 0 1.3em;
+ margin : 1.4em 0 0 0;
+}
+
+#content p,
+#content ol,
+#content ul,
+#content dl {
+ text-align: justify;
+}
+
+#content h1 {
+ margin-left: -0.89em;
+}
+
+a:link {
+ color:#0536d2;
+}
+
+
+/*
+ * Headings
+ *
+ */
+
+h1, h2, h3, h4, h5, h6 {
+ font-weight : 500;
+}
+
+h1 { font-size : 155%; }
+h2 { font-size : 130%; }
+h3 { font-size : 125%; }
+h4 { font-size : 110%; }
+h5 { font-size : 106%; }
+h6 { font-size : 100%; }
+
+h1 { margin : 1.8em 0 0.8em 0;}
+h2 { margin-top : 1.4em;}
+h3 { margin-top : 1em;}
+
+p.indent {
+ margin-left : 1.5em;
+}
+
+
+/*
+ * Fix for IE 5.5 table font problem
+ *
+ */
+
+table {
+ font-size : 13px;
+}
+
+
+/*
+ * table of content
+ *
+ */
+
+ul.toc li {
+ padding : .4em 0em 0em 0em;
+}
+
+
+/* Toc links don't need to show when they are visited. */
+.toc a:visited {
+ color:#0536d2;
+}
+
+
+/*
+ * lists
+ *
+ */
+
+
+/* list of links */
+ul.menu {
+ list-style-type : none;
+}
+
+ul.menu li {
+ padding-top : 0.3em;
+ padding-bottom : 0.3em;
+}
+
+
+
+/* @@ I should probably use child selector here */
+/* list with multiline list-elements */
+ul.multiline li, ol.multiline li, dl.multiline dd {
+ padding-top : 0.16em;
+ padding-bottom : 0.16em;
+
+ font-size : 11px;
+ line-height : 15px;
+}
+
+
+
+/* C++ code snippet */
+pre.cxx {
+ margin-top : 0em;
+ margin-bottom : 2em;
+
+ margin-left : 1em;
+}
+
+
+
+/* make code snippet */
+pre.make {
+ margin-top : 0em;
+ margin-bottom : 2em;
+
+ margin-left : 1em;
+}
+
+
+
+/* terminal output */
+pre.term {
+ margin-top : 0em;
+ margin-bottom : 2em;
+
+ margin-left : 1em;
+}
+
+
+/* Images */
+div.center {
+ text-align: center;
+}
+
+/* Document info. */
+#docinfo {
+ margin-top: 4em;
+ border-top: 1px dashed #000000;
+ font-size: 70%;
+}
+
+
+/* Footnote */
+
+#footnote {
+ margin-top : 2.5em;
+}
+
+#footnote hr, hr.footnote {
+ margin-left: 0;
+ margin-bottom: 0.6em;
+ width: 8em;
+ border-top: 1px solid #000000;
+ border-right: none;
+ border-bottom: none;
+ border-left: none;
+
+}
+
+#footnote ol {
+ margin-left: 0;
+ padding-left: 1.45em;
+}
+
+#footnote li {
+ text-align : left;
+ font-size : 11px;
+ line-height : 15px;
+
+ padding : .4em 0 .4em 0;
+}
+
+
+/* Normal table with borders, etc. */
+
+table.std {
+ margin: 2em 0 2em 0;
+
+ border-collapse : collapse;
+ border : 1px solid;
+ border-color : #000000;
+
+ font-size : 11px;
+ line-height : 14px;
+}
+
+table.std th, table.std td {
+ border : 1px solid;
+ padding : 0.6em 0.8em 0.6em 0.8em;
+}
+
+table.std th {
+ background : #cde8f6;
+}
+
+table.std td {
+ text-align: left;
+}
+
+
+/*
+ * "item | description" table.
+ *
+ */
+
+table.description {
+ border-style : none;
+ border-collapse : separate;
+ border-spacing : 0;
+
+ font-size : 13px;
+
+ margin : 0.6em 0 0.6em 0;
+ padding : 0 0 0 0;
+}
+
+table.description tr {
+ padding : 0 0 0 0;
+ margin : 0 0 0 0;
+}
+
+table.description * td, table.description * th {
+ border-style : none;
+ margin : 0 0 0 0;
+ vertical-align : top;
+}
+
+table.description * th {
+ font-weight : normal;
+ padding : 0.4em 1em 0.4em 0;
+ text-align : left;
+ white-space : nowrap;
+ background : none;
+}
+
+table.description * td {
+ padding : 0.4em 0 0.4em 1em;
+ text-align : justify;
+}
diff --git a/documentation/future.xhtml b/documentation/future.xhtml
new file mode 100644
index 0000000..14d9b9f
--- /dev/null
+++ b/documentation/future.xhtml
@@ -0,0 +1,103 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+
+<head>
+ <title>XSD Planned Features List</title>
+
+ <meta name="copyright" content="&copy; 2005-2009 Code Synthesis Tools CC"/>
+ <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,code,generator,future,features,plan"/>
+ <meta name="description" content="List of features planned for XSD."/>
+
+ <link rel="stylesheet" type="text/css" href="default.css" />
+</head>
+
+<body>
+<div id="container">
+ <div id="content">
+
+ <p>Below is the list of features that we plan to implement in the
+ future. They are divided into two sections: ones that will
+ likely appear in the forthcoming releases and those that we
+ have no definite time-line for. Send an email to
+ <a href="mailto:xsd-users@codesynthesis.com">xsd-users@codesynthesis.com</a>
+ if you are interested in a particular feature or would like to suggest
+ one.</p>
+
+ <h1>Forthcoming Releases</h1>
+
+ <h2>C++/Serializer</h2>
+
+ <ul class="multiline">
+ <li>New mapping that will support event-driven XML serialization.</li>
+ </ul>
+
+ <h2>C++/Hybrid</h2>
+
+ <ul class="multiline">
+ <li>New mapping that will support hybrid, event-driven/in-memory
+ XML processing.</li>
+ </ul>
+
+ <h1>No Definite Time-line</h1>
+
+ <h2>IDL</h2>
+
+ <ul class="multiline">
+ <li>New mapping that will produce CORBA IDL from XML Schema.</li>
+ </ul>
+
+ <h2>IDL/C++</h2>
+
+ <ul class="multiline">
+ <li>New co-mapping that will produce C++ parsing/serialization
+ code for the C++ types produced from CORBA IDL.</li>
+ </ul>
+
+ <h2>C++/Tree</h2>
+
+ <ul class="multiline">
+ <li>Mapping for <code>xsd:unique</code>, <code>xsd:key</code>,
+ and <code>xsd:keyref</code>.</li>
+
+ <li>Option to select between <code>std::vector</code> and
+ <code>std::list</code> as an underlying sequence type.</li>
+
+ <li>Special attribute in XML Schema definition that would
+ instruct code generators to use a different container type
+ such as associative containers (<code>std::set</code> and
+ <code>std::multiset</code>). This will allow you to
+ construct a light-weight, object-oriented database with XML Schema
+ as a specification language and XML as an underlying
+ representation.
+ </li>
+
+ <li>Make dependency generator.</li>
+
+ <li>Generate typedef instead of inheritance for some cases of
+ inheritance from fundamental types.</li>
+
+ <li>Option to suppress the generation of enum mapping.</li>
+
+ <li>Map arbitrary-length integers to a suitable user-defined types.</li>
+
+ <li>Option to map <code>xsd:long</code> to C++ <code>long</code> instead
+ of <code>long long</code> for 64-bit architectures (can be achieved
+ now with --custom-type).</li>
+ </ul>
+
+ </div>
+ <div id="footer">
+ &copy;2005-2009 <a href="http://codesynthesis.com">CODE SYNTHESIS TOOLS CC</a>
+
+ <div id="terms">
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the
+ <a href="http://codesynthesis.com/licenses/fdl-1.2.txt">GNU Free
+ Documentation License, version 1.2</a>; with no Invariant Sections,
+ no Front-Cover Texts and no Back-Cover Texts.
+ </div>
+ </div>
+</div>
+</body>
+</html>
diff --git a/documentation/makefile b/documentation/makefile
new file mode 100644
index 0000000..3fd6133
--- /dev/null
+++ b/documentation/makefile
@@ -0,0 +1,20 @@
+# file : documentation/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
+
+install := $(out_base)/.install
+
+.PHONY: $(install)
+
+$(install):
+ $(call install-dir,$(src_base)/cxx,$(install_doc_dir)/xsd/cxx)
+ $(call install-data,$(src_base)/default.css,$(install_doc_dir)/xsd/default.css)
+ $(call install-data,$(src_base)/future.xhtml,$(install_doc_dir)/xsd/future.xhtml)
+ $(call install-data,$(src_base)/schema-authoring-guide.xhtml,$(install_doc_dir)/xsd/schema-authoring-guide.xhtml)
+ $(call install-data,$(src_base)/xsd.xhtml,$(install_doc_dir)/xsd/xsd.xhtml)
+ $(call install-data,$(src_base)/xsd.1,$(install_man_dir)/man1/xsd.1)
+
+$(call include,$(bld_root)/install.make)
diff --git a/documentation/schema-authoring-guide.xhtml b/documentation/schema-authoring-guide.xhtml
new file mode 100644
index 0000000..10a0a90
--- /dev/null
+++ b/documentation/schema-authoring-guide.xhtml
@@ -0,0 +1,187 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+
+<head>
+ <title>XML Schema Authoring Guide</title>
+
+ <meta name="copyright" content="&copy; 2005-2009 Code Synthesis Tools CC"/>
+ <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,authoring,guide"/>
+ <meta name="description" content="XML Schema Authoring Guide"/>
+
+ <link rel="stylesheet" type="text/css" href="default.css" />
+
+<style type="text/css">
+ pre {
+ background : #cde8f6;
+
+ padding : 0 0 0 1em;
+ margin : 2em 0em 2em 0;
+
+ font-size : 95%
+ }
+
+ body {
+ min-width: 46em;
+ }
+
+ ul.toc li {
+ padding : .4em 0em 0em 0em;
+ list-style : none;
+ }
+
+</style>
+
+
+</head>
+
+<body>
+<div id="container">
+ <div id="content">
+
+ <h1>Table of Contents</h1>
+
+ <ul class="toc">
+ <li>1. <a href="#intro">Introduction</a></li>
+
+ <li>2. <a href="#global_element">Don't define a global element which
+ is not a valid document root</a></li>
+
+ <li>3. <a href="#same_local">Don't name a type and an element/attribute
+ of this type with the same name</a></li>
+
+ <li>3. <a href="#integer">Don't use <code>xsd:integer</code> and
+ friends</a></li>
+
+ <li>4. <a href="#int">Use <code>xsd:int/xsd:unsignedInt</code> for 32 bit
+ integers</a></li>
+ </ul>
+
+ <h1><a name="intro">Introduction</a></h1>
+
+ <p>Making it possible to cleanly map W3C XML Schema to programming languages
+ was never a goal of the XML Schema Working Group. As a result there
+ is a number of Schema constructs, techniques, and styles that don't
+ have appropriate counterparts in C++. This document presents a list
+ of do's and don'ts that will help ensure your schemas, when translated
+ by XSD, result in C++ code that is enjoyable to work with.</p>
+
+
+ <h1><a name="global_element">Don't define a global element which is not
+ a valid document root</a></h1>
+
+ <p>Instead of</p>
+
+ <pre>
+&lt;xsd:element name="author" type="Author"/>
+
+&lt;xsd:complexType name="Book">
+ &lt;xsd:sequence>
+ &lt;xsd:element ref="author"/>
+ &lt;/xsd:sequence>
+&lt;/xsd:complexType>
+ </pre>
+
+ <p>Write</p>
+
+ <pre>
+&lt;xsd:complexType name="Book">
+ &lt;xsd:sequence>
+ &lt;xsd:element name="author" type="Author"/>
+ &lt;/xsd:sequence>
+&lt;/xsd:complexType>
+ </pre>
+
+ <p>Any globally-defined element is a potential document root. For every
+ such element XSD generates a set of overloaded parsing
+ functions. If you cannot change your schema, consider using the
+ <code>--root-element-*</code> options to specify which global
+ element(s) are actual document root(s).</p>
+
+
+
+ <h1><a name="same_local">Don't name a type and an element/attribute of
+ this type with the same name</a></h1>
+
+ <p>Instead of</p>
+
+ <pre>
+&lt;xsd:complexType name="name">
+ &lt;xsd:sequence>
+ &lt;xsd:element name="name" type="xsd:string"/>
+ &lt;/xsd:sequence>
+ &lt;xsd:attribute name="lang" type="xsd:language"/>
+&lt;/xsd:complexType>
+ </pre>
+
+ <p>Write</p>
+
+ <pre>
+&lt;xsd:complexType name="Name">
+ &lt;xsd:sequence>
+ &lt;xsd:element name="name" type="xsd:string"/>
+ &lt;/xsd:sequence>
+ &lt;xsd:attribute name="lang" type="xsd:language"/>
+&lt;/xsd:complexType>
+ </pre>
+
+ <p>Use of a class name as a member function name within this class is
+ illegal in C++. XSD will resolve such conflicts by renaming
+ the conflicting member function. In the example above, you will end
+ up with the following generated code:</p>
+
+ <pre>
+ class name
+ {
+ public:
+ string
+ name1 () const;
+
+ language
+ lang () const;
+
+ ...
+
+ };
+ </pre>
+
+ <h1><a name="integer">Don't use <code>xsd:integer</code> and
+ friends</a></h1>
+
+ <p>XML Schema built-in types <code>integer</code>,
+ <code>nonPositiveInteger</code>, <code>nonNegativeInteger</code>,
+ <code>positiveInteger</code>, and <code>negativeInteger</code>
+ are arbitrary-length integral types. XSD maps them to the
+ <code>long long</code> and <code>unsigned long long</code> C++
+ types. In most cases you would prefer to use either
+ <code>xsd:int/xsd:unsignedInt</code> (32 bit, maps to C++
+ <code>int/unsigned int</code>) or
+ <code>xsd:long/xsd:unsignedLong</code> (64 bit, maps to C++
+ <code>long long/unsigned long long</code>).
+ </p>
+
+ <h1><a name="int">Use <code>xsd:int/xsd:unsignedInt</code> for 32 bit
+ integers</a></h1>
+
+ <p>XML Schema built-in types <code>long</code> and
+ <code>unsignedLong</code> are 64 bit wide so use 32 bit <code>int</code>
+ and <code>unsignedInt</code> unless you meant 64 bit.</p>
+
+ </div>
+ <div id="footer">
+ &copy;2005-2009 <a href="http://codesynthesis.com">CODE SYNTHESIS TOOLS CC</a>
+
+ <div id="terms">
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the
+ <a href="http://codesynthesis.com/licenses/fdl-1.2.txt">GNU Free
+ Documentation License, version 1.2</a>; with no Invariant Sections,
+ no Front-Cover Texts and no Back-Cover Texts.
+ </div>
+ </div>
+
+</div>
+
+
+</body>
+</html>
diff --git a/documentation/xsd.1 b/documentation/xsd.1
new file mode 100644
index 0000000..cebdc0e
--- /dev/null
+++ b/documentation/xsd.1
@@ -0,0 +1,1770 @@
+.\" Process this file with
+.\" groff -man -Tascii xsd.1
+.\"
+.TH XSD 1 "November 2008" "XSD 3.3.0"
+.SH NAME
+xsd \- W3C XML Schema to C++ Compiler
+.\"
+.\"
+.\"
+.\"--------------------------------------------------------------------
+.SH SYNOPSIS
+.\"--------------------------------------------------------------------
+.B xsd
+.I command
+.B [
+.I options
+.B ]
+.I file
+.B [
+.I file
+.B ...]
+.in
+.B xsd help
+.B [
+.I command
+.B ]
+.in
+.B xsd version
+.\"
+.\"
+.\"
+.\"--------------------------------------------------------------------
+.SH DESCRIPTION
+.\"--------------------------------------------------------------------
+.B xsd
+generates vocabulary-specific, statically-typed C++ mapping from W3C XML
+Schema definitions. Particular mapping to produce is selected by a
+.IR command .
+Each mapping has a number of mapping-specific
+.I options
+that should appear, if any, after the
+.IR command .
+Input files should be W3C XML Schema definitions. The exact set of the
+generated files depends on the selected mapping and options.
+.\"
+.\"
+.\"
+.\"--------------------------------------------------------------------
+.SH COMMANDS
+.\"--------------------------------------------------------------------
+.IP \fBcxx-tree\fR
+Generate the C++/Tree mapping. For each input file in the form
+.B name.xsd
+the following C++ files are generated:
+.B name.hxx
+(header file),
+.B name.ixx
+(inline file, generated only if the
+.B --generate-inline
+option is specified),
+.B name.cxx
+(source file), and
+.B name-fwd.hxx
+(forward declaration file, generated only if the
+.B --generate-forward
+option is specified).
+
+.IP \fBcxx-parser\fR
+Generate the C++/Parser mapping. For each input file in the form
+.B name.xsd
+the following C++ files are generated:
+.B name-pskel.hxx
+(parser skeleton header file),
+.B name-pskel.ixx
+(parser skeleton inline file, generated only if the
+.B --generate-inline
+option is specified), and
+.B name-pskel.cxx
+(parser skeleton source file). If the
+.B --generate-noop-impl
+or
+.B --generate-print-impl
+option is specified, the following additional sample implementation files
+are generated:
+.B name-pimpl.hxx
+(parser implementation header file) and
+.B name-pimpl.cxx
+(parser implementation source file). If the
+.B --generate-test-driver
+option is specified, the additional
+.B name-driver.cxx
+test driver file is generated.
+
+.IP \fBhelp\fR
+Print usage information and exit. Use
+.PP
+.RS
+.RS 3
+.B xsd help
+.I command
+.RE
+.PP
+for command-specific help.
+.RE
+.IP \fBversion\fR
+Print version and exit.
+.\"--------------------------------------------------------------------
+.SH OPTIONS
+.\"--------------------------------------------------------------------
+Command-specific
+.IR options ,
+if any, should appear after the corresponding
+.IR command .
+
+.\"
+.\" Common options.
+.\"
+.SS common options
+.
+.IP "\fB\--char-type \fItype\fR"
+Generate code using the provided character
+.I type
+instead of the default
+.BR char .
+Valid values are
+.B char
+and
+.BR wchar_t .
+.
+.IP "\fB\--output-dir \fIdir\fR"
+Write generated files to
+.I dir
+instead of the current directory.
+
+.IP "\fB\--namespace-map \fIxns\fB=\fIcns"
+Map XML Schema namespace
+.I xns
+to C++ namespace
+.IR cns .
+Repeat this option to specify mapping for more than one XML Schema namespace.
+For example, the following option:
+
+.B --namespace-map http://example.com/foo/bar=foo::bar
+
+will map the
+.B http://example.com/foo/bar
+XML Schema namespace to the
+.B foo::bar
+C++ namespace.
+.
+.IP "\fB\--namespace-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema namespace
+names to C++ namespace names.
+.I regex
+is a perl-like regular expression in the form
+.BI / pattern / replacement /\fR.
+Any character can be used as a delimiter instead of
+.BR / .
+Escaping of the delimiter character in
+.I pattern
+or
+.I replacement
+is not supported.
+
+All regular expressions are pushed into a stack with the last specified
+expression considered first. The first match that succeeds is used. Regular
+expressions are applied to a string in the form
+
+.I filename namespace
+
+For example,
+
+.B XMLSchema.xsd http://www.w3.org/2001/XMLSchema
+
+The
+.I filename
+for the current translation unit is empty. For example, if you have file
+.B hello.xsd
+with namespace
+.B http://example.com/hello
+and you run
+.B xsd
+on this file, then the string in question would be:
+
+.B \ http://example.com/hello
+
+Note the leading space.
+
+The following three steps are performed for each regular expression until
+the match is found:
+.RS
+.RS 3
+.TP 3
+1.
+The expression is applied and if the result is empty the next expression
+is considered.
+.TP 3
+2.
+All
+.B /
+are replaced with
+.BR :: .
+.TP 3
+3.
+The result is verified to be a valid C++ scope name (e.g.,
+.BR foo::bar ).
+If this test succeeds, the result is used as a C++ namespace name.
+.RE
+.PP
+As an example, the following expression maps XML Schema namespaces in the
+form
+.B http://example.com/foo/bar
+to C++ namespaces in the form
+.BR foo::bar :
+.PP
+.B "%.* http://example.com/(.+)%$1%"
+
+See also the REGEX AND SHELL QUOTING section below.
+.RE
+
+.IP "\fB\--namespace-regex-trace\fR"
+Trace the process of applying regular expressions specified with
+the
+.B --namespace-regex
+option. Use this option to find out why your regular expressions
+don't do what you expected them to do.
+
+\"
+\" Reserved names.
+\"
+
+.IP "\fB\--reserved-name \fIname\fR[\fB=\fIrep\fR]"
+Add
+.I name
+to the list of names that should not be used as identifiers. The name
+can optionally be followed by
+.B =
+and the replacement name that should be used instead. All C++ keywords
+are already in this list.
+
+\"
+\" Include
+\"
+
+.IP "\fB\--include-with-brackets\fR"
+Use angle brackets (<>) instead of quotes ("") in generated
+.B #include
+directives.
+
+.IP "\fB\--include-prefix \fIprefix\fR"
+Add
+.I prefix
+to generated
+.B #include
+directive paths.
+
+For example, if you had the following import element in your schema
+
+.B <import namespace="..." schemaLocation="base.xsd"/>
+
+and compiled this fragment with
+.B --include-prefix schemas/\fR,
+then the include directive in the generated code would be:
+
+.B #include "schemas/base.hxx"
+
+.IP "\fB\--include-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to transform
+.B #include
+directive paths.
+.I regex
+is a perl-like regular expression in the form
+.BI / pattern / replacement /\fR.
+Any character can be used as a delimiter instead of
+.BR / .
+Escaping of the delimiter character in
+.I pattern
+or
+.I replacement
+is not supported.
+
+All regular expressions are pushed into a stack with the last specified
+expression considered first. The first match that succeeds is used.
+
+As an example, the following expression transforms paths in the form
+.B schemas/foo/bar
+to paths in the form
+.BR generated/foo/bar :
+
+.B "%schemas/(.+)%generated/$1%"
+
+See also the REGEX AND SHELL QUOTING section below.
+
+.IP "\fB\--include-regex-trace\fR"
+Trace the process of applying regular expressions specified with
+the
+.B --include-regex
+option. Use this option to find out why your regular expressions
+don't do what you expected them to do.
+
+.IP "\fB\--guard-prefix \fIprefix\fR"
+Add
+.I prefix
+to generated header inclusion guards. The prefix is transformed to upper
+case and all characters that are illegal in a preprocessor macro name are
+replaced with underscores. If this option is not specified then the
+directory part of the input schema file is used as a prefix.
+
+.\"
+.\" Suffixes.
+.\"
+
+.IP "\fB\--hxx-suffix \fIsuffix\fR"
+Use the provided
+.I suffix
+instead of the default
+.B .hxx
+to construct the name of the header file. Note that this suffix is also
+used to construct names for included/imported schemas.
+
+.IP "\fB\--ixx-suffix \fIsuffix\fR"
+Use the provided
+.I suffix
+instead of the default
+.B .ixx
+to construct the name of the inline file.
+
+.IP "\fB\--cxx-suffix \fIsuffix\fR"
+Use the provided
+.I suffix
+instead of the default
+.B .cxx
+to construct the name of the source file.
+
+.IP "\fB\--hxx-regex \fIregex\fR"
+Use the provided expression to construct the name of the header file.
+.I regex
+is a perl-like regular expression in the form
+.BI / pattern / replacement /\fR.
+Note that this expression is also used to construct names for
+included/imported schemas. See also the REGEX AND SHELL QUOTING section
+below.
+
+.IP "\fB\--ixx-regex \fIregex\fR"
+Use the provided expression to construct the name of the inline file.
+.I regex
+is a perl-like regular expression in the form
+.BI / pattern / replacement /\fR.
+See also the REGEX AND SHELL QUOTING section below.
+
+.IP "\fB\--cxx-regex \fIregex\fR"
+Use the provided expression to construct the name of the source file.
+.I regex
+is a perl-like regular expression in the form
+.BI / pattern / replacement /\fR.
+See also the REGEX AND SHELL QUOTING section below.
+
+.IP "\fB\--hxx-prologue \fItext\fR"
+Insert
+.I text
+at the beginning of the header file.
+
+.IP "\fB\--ixx-prologue \fItext\fR"
+Insert
+.I text
+at the beginning of the inline file.
+
+.IP "\fB\--cxx-prologue \fItext\fR"
+Insert
+.I text
+at the beginning of the source file.
+
+.IP "\fB\--prologue \fItext\fR"
+Insert
+.I text
+at the beginning of each generated file for which there is no file-specific
+prologue.
+
+.IP "\fB\--hxx-epilogue \fItext\fR"
+Insert
+.I text
+at the end of the header file.
+
+.IP "\fB\--ixx-epilogue \fItext\fR"
+Insert
+.I text
+at the end of the inline file.
+
+.IP "\fB\--cxx-epilogue \fItext\fR"
+Insert
+.I text
+at the end of the source file.
+
+.IP "\fB\--epilogue \fItext\fR"
+Insert
+.I text
+at the end of each generated file for which there is no file-specific
+epilogue.
+
+.IP "\fB\--hxx-prologue-file \fIfile\fR"
+Insert the content of the
+.I file
+at the beginning of the header file.
+
+.IP "\fB\--ixx-prologue-file \fIfile\fR"
+Insert the content of the
+.I file
+at the beginning of the inline file.
+
+.IP "\fB\--cxx-prologue-file \fIfile\fR"
+Insert the content of the
+.I file
+at the beginning of the source file.
+
+.IP "\fB\--prologue-file \fIfile\fR"
+Insert the content of the
+.I file
+at the beginning of each generated file for which there is no file-specific
+prologue file.
+
+.IP "\fB\--hxx-epilogue-file \fIfile\fR"
+Insert the content of the
+.I file
+at the end of the header file.
+
+.IP "\fB\--ixx-epilogue-file \fIfile\fR"
+Insert the content of the
+.I file
+at the end of the inline file.
+
+.IP "\fB\--cxx-epilogue-file \fIfile\fR"
+Insert the content of the
+.I file
+at the end of the source file.
+
+.IP "\fB\--epilogue-file \fIfile\fR"
+Insert the content of the
+.I file
+at the end of each generated file for which there is no file-specific
+epilogue file.
+
+.IP "\fB\--export-symbol \fIsymbol\fR"
+Insert
+.I symbol
+in places where DLL export/import control statements (
+.BR __declspec(dllexport/dllimport) )
+are necessary.
+
+.IP "\fB\--export-xml-schema\fR"
+Export/import types in the XML Schema namespace using the export
+symbol provided with the
+.B --export-symbol
+option.
+
+.IP "\fB\--export-maps\fR"
+Export polymorphism support maps from a Win32 DLL into which this generated
+code is linked. This is necessary when your type hierarchy is split across
+several DLLs since otherwise each DLL will have its own set of maps. In
+this situation the generated code for the DLL which contains base types
+and/or substitution group heads should be compiled with this option and
+the generated code for all other DLLs should be compiled with
+.BR --import-maps .
+This option is only valid together with
+.BR --generate-polymorphic.
+
+.IP "\fB\--import-maps\fR"
+Import polymorphism support maps to a Win32 DLL or executable into which
+this generated code is linked. See the
+.B --export-maps
+option documentation for details. This option is only valid together with
+.BR --generate-polymorphic.
+
+.IP "\fB\--disable-warning \fIwarn\fR"
+Disable printing warning with id
+.IR warn .
+If
+.B all
+is specified for the warning id then all warnings are disabled.
+
+.IP "\fB\--show-sloc\fR"
+Show the number of generated physical source lines of code (SLOC).
+
+.IP "\fB\--sloc-limit \fInum\fR"
+Check that the number of generated physical source lines of code (SLOC)
+does not exceed
+.I num.
+
+.IP "\fB\--options-file \fIfile\fR"
+Read additional options from
+.IR file .
+Each option should appear on a separate line optionally followed by
+space and an argument. Empty lines and lines starting with
+.B #
+are ignored. The semantics of providing options in a file is equivalent
+to providing the same set of options in the same order in the command
+line at the point where the
+.B --options-file
+option is specified except that shell escaping and quoting is not
+required. Repeat this option to specify more than one options files.
+
+.IP "\fB\--proprietary-license\fR"
+Indicate that the generated code is licensed under a proprietary license
+instead of the GPL.
+
+.IP "\fB\--preserve-anonymous\fR"
+Preserve anonymous types. By default anonymous types are
+automatically named with names derived from the enclosing
+elements/attributes. Because mappings implemented by this
+compiler require all types to be named, this option is only
+useful if you want to make sure your schemas don't have
+anonymous types.
+
+.IP "\fB\--show-anonymous\fR"
+Show elements and attributes that are of anonymous types. This option
+only makes sense together with the
+.B --preserve-anonymous
+option.
+
+.IP "\fB\--anonymous-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to derive names for anonymous
+types from the enclosing attributes/elements.
+.I regex
+is a perl-like regular expression in the form
+.BI / pattern / replacement /\fR.
+Any character can be used as a delimiter instead of
+.BR / .
+Escaping of the delimiter character in
+.I pattern
+or
+.I replacement
+is not supported.
+
+All regular expressions are pushed into a stack with the last
+specified expression considered first. The first match that
+succeeds is used. Regular expressions are applied to a string
+in the form
+
+.I filename namespace xpath
+
+For example,
+
+.B hello.xsd http://example.com/hello element
+
+.B hello.xsd http://example.com/hello type/element
+
+The
+.I filename
+for the current translation unit is empty. For example, if you have file
+.B hello.xsd
+with namespace
+.B http://example.com/hello
+and you run
+.B xsd
+on this file, then the string in question would be:
+
+.B \ http://example.com/hello element
+
+Note the leading space.
+
+As an example, the following expression makes all the derived
+names start with capital letters. This could be useful when
+your naming convention requires type names to start with
+capital letters:
+
+.B %.* .* (.+/)*(.+)%\\\\u$2%
+
+See also the REGEX AND SHELL QUOTING section below.
+
+.IP "\fB\--anonymous-regex-trace\fR"
+Trace the process of applying regular expressions specified with
+the
+.B --anonymous-regex
+option. Use this option to find out why your regular expressions
+don't do what you expected them to do.
+
+.IP "\fB\--location-map \fIol\fB=\fInl"
+Map the original schema location
+.I ol
+that is specified in the XML Schema include or import elements to new
+schema location
+.IR nl .
+Repeat this option to map more than one schema location. For example,
+the following option maps the
+.B http://example.com/foo.xsd
+URL to the
+.B foo.xsd
+local file.
+
+.B --location-map http://example.com/foo.xsd=foo.xsd
+
+.IP "\fB\--location-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to map schema locations that are
+specified in the XML Schema include or import elements.
+.I regex
+is a perl-like regular expression in the form
+.BI / pattern / replacement /\fR.
+Any character can be used as a delimiter instead of
+.BR / .
+Escaping of the delimiter character in
+.I pattern
+or
+.I replacement
+is not supported. All regular expressions are pushed into a stack with the
+last specified expression considered first. The first match that succeeds
+is used.
+
+For example, the following expression maps URL locations in the form
+.B http://example.com/foo/bar.xsd
+to local files in the form
+.BR bar.xsd :
+
+.B %http://.+/(.+)%$1%
+
+See also the REGEX AND SHELL QUOTING section below.
+
+.IP "\fB\--location-regex-trace\fR"
+Trace the process of applying regular expressions specified with
+the
+.B --location-regex
+option. Use this option to find out why your regular expressions
+don't do what you expected them to do.
+
+.IP "\fB\--file-per-type\fR"
+Generate a separate set of C++ files for each type defined in XML Schema.
+Note that in this mode you only need to compile the root schema(s) and the
+code will be generated for all included and imported schemas. This
+compilation mode is primarily useful when some of your schemas cannot be
+compiled separately or have cyclic dependencies which involve type
+inheritance.
+
+.IP "\fB\--type-file-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate type names to file
+names when the
+.B --type-per-file
+option is specified.
+.I regex
+is a perl-like regular expression in the form
+.BI / pattern / replacement /\fR.
+Any character can be used as a delimiter instead of
+.BR / .
+Escaping of the delimiter character in
+.I pattern
+or
+.I replacement
+is not supported. All regular expressions are pushed into a stack with
+the last specified expression considered first. The first match that
+succeeds is used. Regular expressions are applied to a string
+in the form
+
+.I namespace type-name
+
+For example, the following expression maps type
+.B foo
+that is defined in the
+.B http://example.com/bar
+namespace to file name
+.BR bar-foo :
+
+.B %http://example.com/(.+) (.+)%$1-$2%
+
+See also the REGEX AND SHELL QUOTING section below.
+
+.IP "\fB\--type-file-regex-trace\fR"
+Trace the process of applying regular expressions specified with
+the
+.B --type-file-regex
+option. Use this option to find out why your regular expressions
+don't do what you expected them to do.
+
+.IP "\fB\--file-list \fIfile\fR"
+Write a list of generated C++ files to
+.IR file .
+This option is primarily useful in the file-per-type compilation mode
+.RB ( --file-per-type )
+to create a list of generated C++ files, for example, as a makefile fragment.
+
+.IP "\fB\--file-list-prologue \fItext\fR"
+Insert
+.I text
+at the beginning of the file list. As a convenience, all occurrences of the
+\\n character sequence in
+.I text
+are replaced with new lines. This option can, for example, be used to assign
+the generated file list to a makefile variable.
+
+.IP "\fB\--file-list-epilogue \fItext\fR"
+Insert
+.I text
+at the end of the file list. As a convenience, all occurrences of the
+\\n character sequence in
+.I text
+are replaced with new lines.
+
+.IP "\fB\--file-list-delim \fItext\fR"
+Delimit file names written to the file list with
+.I text
+instead of new lines. As a convenience, all occurrences of the \\n character
+sequence in
+.I text
+are replaced with new lines.
+
+.\"
+.\" C++/Tree options.
+.\"
+.SS cxx-tree command options
+
+.IP "\fB\--generate-polymorphic\fR"
+Generate polymorphism-aware code. Specify this option if you use substitution
+groups or
+.BR xsi:type .
+
+.IP "\fB\--generate-serialization\fR"
+Generate serialization functions. Serialization functions convert
+the object model back to XML.
+
+.IP "\fB\--generate-inline\fR"
+Generate simple functions inline. This option triggers creation of the
+inline file.
+
+.IP "\fB\--generate-ostream\fR"
+Generate ostream insertion operators
+.RB ( operator<< )
+for generated types. This allows to easily print a fragment or the whole
+object model for debugging or logging.
+
+.IP "\fB\--generate-doxygen\fR"
+Generate documentation comments suitable for extraction by the Doxygen
+documentation system. Documentation from annotations is added to the
+comments if present in the schema.
+
+.IP "\fB\--generate-comparison\fR"
+Generate comparison operators
+.RB ( operator==
+and
+.BR operator!= )
+for complex types. Comparison is performed memberwise.
+
+.IP "\fB\--generate-default-ctor\fR"
+Generate default constructors even for types that have required members.
+Required members of an instance constructed using such a constructor are
+not initialized and accessing them results in undefined behavior.
+
+.IP "\fB\--generate-from-base-ctor\fR"
+Generate constructors that expect an instance of a base type followed by all
+required members.
+
+.IP "\fB\--generate-wildcard\fR"
+Generate accessors and modifiers as well as parsing and serialization code
+for XML Schema wildcards
+.RB ( any
+and
+.BR anyAttribute ).
+XML content matched by wildcards is presented as DOM fragments. Note that
+you need to initialize the Xerces-C++ runtime if you are using this option.
+
+.IP "\fB\--generate-insertion \fIos\fR"
+Generate data representation stream insertion operators for the
+.I os
+output stream type. Repeat this option to specify more than one stream
+type. The ACE CDR stream
+.RB ( ACE_OutputCDR )
+and RPC XDR are recognized by the compiler and the necessary
+.B #include
+directives are automatically generated. For custom stream types use the
+.B --hxx-prologue*
+options to provide the necessary declarations.
+
+.IP "\fB\--generate-extraction \fIis\fR"
+Generate data representation stream extraction constructors for the
+.I is
+input stream type. Repeat this option to specify more than one stream
+type. The ACE CDR stream
+.RB ( ACE_InputCDR )
+and RPC XDR are recognized by the compiler and the necessary
+.B #include
+directives are automatically generated. For custom stream types use the
+.B --hxx-prologue*
+options to provide the necessary declarations.
+
+.IP "\fB\--generate-forward\fR"
+Generate a separate header file with forward declarations for the types
+being generated.
+
+.IP "\fB\--generate-xml-schema\fR"
+Generate a C++ header file as if the schema being compiled defines the
+XML Schema namespace. In particular, the resulting file will have
+definitions for all XML Schema built-in types. The schema file provided
+to the compiler need not exist and is only used to derive the name of the
+resulting header file. Use the
+.B --extern-xml-schema
+option to include this file in the generated files for other schemas.
+
+.IP "\fB\--extern-xml-schema \fIfile\fR"
+Include a header file derived from
+.I file
+instead of generating the XML Schema namespace mapping inline. The provided
+file need not exist and is only used to derive the name of the included
+header file. Use the
+.B --generate-xml-schema
+option to generate this header file.
+
+.IP "\fB\--suppress-parsing\fR"
+Suppress the generation of the parsing functions and constructors. Use this
+option to reduce the generated code size when parsing from XML is not
+needed.
+
+.IP "\fB\--generate-element-type\fR"
+Generate types instead of parsing and serialization functions for root
+elements. This is primarily useful to distinguish object models with the
+same root type but with different root elements.
+
+.IP "\fB\--generate-element-map\fR"
+Generate a root element map that allows uniform parsing and serialization
+of multiple root elements. This option is only valid together with
+.BR --generate-element-type .
+
+.IP "\fB\--generate-intellisense\fR"
+Generate workarounds for IntelliSense bugs in Visual Studio 2005 (8.0). When
+this option is used, the resulting code is slightly more verbose. IntelliSense
+in Visual Studio 2008 (9.0) does not require these workarounds. Support for
+IntelliSense in Visual Studio 2003 (7.1) is improved with this option but
+is still incomplete.
+
+.IP "\fB\--omit-default-attributes\fR"
+Omit attributes with default and fixed values from serialized XML
+documents.
+
+\"
+\" Naming
+\"
+
+.IP "\fB\--type-naming \fIstyle\fR"
+Specify the type naming convention that should be used in the generated code.
+Valid styles are
+.B knr
+(default),
+.BR ucc ,
+and
+.BR java .
+See the NAMING CONVENTION section below for more information.
+
+.IP "\fB\--function-naming \fIstyle\fR"
+Specify the function naming convention that should be used in the generated
+code. Valid styles are
+.B knr
+(default),
+.BR lcc ,
+and
+.BR java.
+See the NAMING CONVENTION section below for more information.
+
+.IP "\fB\--type-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema
+type names to C++ type names. See the NAMING CONVENTION section below for
+more information.
+
+.IP "\fB\--accessor-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema
+names of elements/attributes to C++ accessor function names. See the NAMING
+CONVENTION section below for more information.
+
+.IP "\fB\--one-accessor-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema
+names of elements/attributes with cardinality one to C++ accessor function
+names. See the NAMING CONVENTION section below for more information.
+
+.IP "\fB\--opt-accessor-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema
+names of elements/attributes with cardinality optional to C++ accessor
+function names. See the NAMING CONVENTION section below for more information.
+
+.IP "\fB\--seq-accessor-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema
+names of elements/attributes with cardinality sequence to C++ accessor
+function names. See the NAMING CONVENTION section below for more information.
+
+.IP "\fB\--modifier-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema
+names of elements/attributes to C++ modifier function names. See the NAMING
+CONVENTION section below for more information.
+
+.IP "\fB\--one-modifier-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema
+names of elements/attributes with cardinality one to C++ modifier function
+names. See the NAMING CONVENTION section below for more information.
+
+.IP "\fB\--opt-modifier-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema
+names of elements/attributes with cardinality optional to C++ modifier
+function names. See the NAMING CONVENTION section below for more information.
+
+.IP "\fB\--seq-modifier-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema
+names of elements/attributes with cardinality sequence to C++ modifier
+function names. See the NAMING CONVENTION section below for more information.
+
+.IP "\fB\--parser-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema
+element names to C++ parsing function names. See the NAMING CONVENTION
+section below for more information.
+
+.IP "\fB\--serializer-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema
+element names to C++ serialization function names. See the NAMING
+CONVENTION section below for more information.
+
+.IP "\fB\--enumerator-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema
+enumeration values to C++ enumerator names. See the NAMING CONVENTION
+section below for more information.
+
+.IP "\fB\--element-type-regex \fIregex\fR"
+Add
+.I regex
+to the list of regular expressions used to translate XML Schema
+element names to C++ element type names. See the NAMING CONVENTION section
+below for more information.
+
+.IP "\fB\--name-regex-trace\fR"
+Trace the process of applying regular expressions specified with the name
+transformation options. Use this option to find out why your regular
+expressions don't do what you expected them to do.
+
+\"
+\" Root element.
+\"
+
+.IP "\fB\--root-element-first\fR"
+Treat only the first global element as a document root. By default all
+global elements are considered document roots.
+
+.IP "\fB\--root-element-last\fR"
+Treat only the last global element as a document root. By default all
+global elements are considered document roots.
+
+.IP "\fB\--root-element-all\fR"
+Treat all global elements as document roots. This is the default behavior.
+By explicitly specifying this option you can suppress the warning that is
+issued if more than one global element is defined.
+
+.IP "\fB\--root-element-none\fR"
+Do not treat any global elements as document roots. By default all global
+elements are considered document roots.
+
+.IP "\fB\--root-element \fIelement\fR"
+Treat only
+.I element
+as a document root. Repeat this option to specify more than one root element.
+
+\"
+\" Custom type.
+\"
+
+.IP "\fB\--custom-type \fIname\fR[\fB=\fItype\fR[\fB/\fIbase\fR]]"
+Use a custom C++ type
+.I type
+instead of the generated class for XML Schema type
+.IR name .
+If
+.I type
+is not present or empty then the custom type is assumed to have the same name
+and be defined in the same namespace as the generated class would have. If
+.I base
+is specified then the generated class is still generated but with that name.
+
+.IP "\fB\--custom-type-regex \fB/\fIname-pat\fB/\fR[\fItype-sub\fB/\fR[\fIbase-sub\fB/\fR]]"
+For each type defined in XML Schema that matches the
+.I name-pat
+pattern use a custom C++ type instead of the generated class. The
+name of the custom type is obtained by substituting
+.IR type-sub .
+If
+.I type-sub
+is not present or its substitution results in an empty string then the
+custom type is assumed to have the same name and be defined in the same
+namespace as the generated class would have. If
+.I base-sub
+is present and its substitution results in a non-empty string then the
+generated class is still generated but with the result of substitution
+as its name. See also the REGEX AND SHELL QUOTING section below.
+
+\"
+\" Suffixes.
+\"
+
+.IP "\fB\--fwd-suffix \fIsuffix\fR"
+Use the provided
+.I suffix
+instead of the default
+.B -fwd.hxx
+to construct the name of the forward declaration file.
+
+.IP "\fB\--fwd-regex \fIregex\fR"
+Use the provided expression to construct the name of the forward
+declaration file.
+.I regex
+is a perl-like regular expression in the form
+.BI / pattern / replacement /\fR.
+See also the REGEX AND SHELL QUOTING section below.
+
+.IP "\fB\--fwd-prologue \fItext\fR"
+Insert
+.I text
+at the beginning of the forward declaration file.
+
+.IP "\fB\--fwd-epilogue \fItext\fR"
+Insert
+.I text
+at the end of the forward declaration file.
+
+.IP "\fB\--fwd-prologue-file \fIfile\fR"
+Insert the content of the
+.I file
+at the beginning of the forward declaration file.
+
+.IP "\fB\--fwd-epilogue-file \fIfile\fR"
+Insert the content of the
+.I file
+at the end of the forward declaration file.
+
+\"
+\" Parts.
+\"
+
+.IP "\fB\--parts \fInum\fR"
+Split generated source code into
+.I num
+parts. This is useful when translating large, monolithic schemas and a C++
+compiler is not able to compile the resulting source code at once (usually
+due to insufficient memory).
+
+.IP "\fB\--parts-suffix \fIsuffix\fR"
+Use
+.I suffix
+instead of the default '\fB-\fR' to separate the file name from the part
+number.
+
+\"
+\" C++/Parser
+\"
+
+.SS cxx-parser command options
+
+.IP "\fB\--type-map \fImapfile\fR"
+Read XML Schema to C++ type mapping information from
+.I mapfile
+Repeat this option to specify several type maps. Type maps are
+considered in order of appearance and the first match is used.
+By default all user-defined types are mapped to
+.BR void .
+See the TYPE MAP section below for more information.
+
+.IP "\fB\--xml-parser \fIparser\fR"
+Use
+.I parser
+as the underlying XML parser. Valid values are
+.B xerces
+for Xerces-C++ (default) and
+.B expat
+for Expat.
+
+.IP "\fB\--generate-inline\fR"
+Generate simple functions inline. This option triggers creation of the
+inline file.
+
+.IP "\fB\--generate-validation\fR"
+Generate validation code ("perfect" parser) which ensures that instance
+documents conform to the schema. Validation code is generated by default
+when the selected underlying XML parser is non-validating (\fBexpat\fR).
+
+.IP "\fB\--suppress-validation\fR"
+Suppress the generation of validation code ("perfect" parser). Validation is
+suppressed by default when the selected underlying XML parser is
+validating (\fBxerces\fR).
+
+.IP "\fB\--generate-polymorphic\fR"
+Generate polymorphism-aware code. Specify this option if you use substitution
+groups or
+.BR xsi:type .
+
+.IP "\fB\--generate-noop-impl\fR"
+Generate a sample parser implementation that does nothing (no operation).
+The sample implementation can then be filled with the application-specific
+code. For an input file in the form
+.B name.xsd
+this option triggers the generation of the two additional C++ files in the form:
+.B name-pimpl.hxx
+(parser implementation header file) and
+.B name-pimpl.cxx
+(parser implementation source file).
+
+.IP "\fB\--generate-print-impl\fR"
+Generate a sample parser implementation that prints the XML data to STDOUT.
+For an input file in the form
+.B name.xsd
+this option triggers the generation of the two additional C++ files in the form:
+.B name-pimpl.hxx
+(parser implementation header file) and
+.B name-pimpl.cxx
+(parser implementation source file).
+
+.IP "\fB\--generate-test-driver\fR"
+Generate a test driver for the sample parser implementation. For an input
+file in the form
+.B name.xsd
+this option triggers the generation of an additional C++ file in the form
+.BR name-driver.cxx .
+
+.IP "\fB\--force-overwrite\fR"
+Force overwriting of the existing implementation and test driver files.
+Use this option only if you do not mind loosing the changes you have made
+in the sample implementation or test driver files.
+
+.IP "\fB\--root-element-first\fR"
+Indicate that the first global element is the document root. This information
+is used to generate the test driver for the sample implementation.
+
+.IP "\fB\--root-element-last\fR"
+Indicate that the last global element is the document root. This information
+is used to generate the test driver for the sample implementation.
+
+.IP "\fB\--root-element \fIelement\fR"
+Indicate that
+.I element
+is the document root. This information is used to generate the test driver
+for the sample implementation.
+
+.IP "\fB\--generate-xml-schema\fR"
+Generate a C++ header file as if the schema being compiled defines the
+XML Schema namespace. In particular, the resulting file will have
+definitions for all parser skeletons and implementations corresponding
+to the XML Schema built-in types. The schema file provided to the compiler
+need not exist and is only used to derive the name of the resulting header
+file. Use the
+.B --extern-xml-schema
+option to include this file in the generated files for other schemas.
+
+.IP "\fB\--extern-xml-schema \fIfile\fR"
+Include a header file derived from
+.I file
+instead of generating the XML Schema namespace mapping inline. The provided
+file need not exist and is only used to derive the name of the included
+header file. Use the
+.B --generate-xml-schema
+option to generate this header file.
+
+.IP "\fB\--skel-type-suffix \fIsuffix\fR"
+Use the provided
+.I suffix
+instead of the default
+.B _pskel
+to construct the names of generated parser skeletons.
+
+.IP "\fB\--skel-file-suffix \fIsuffix\fR"
+Use the provided
+.I suffix
+instead of the default
+.B -pskel
+to construct the names of generated parser skeleton files.
+
+.IP "\fB\--impl-type-suffix \fIsuffix\fR"
+Use the provided
+.I suffix
+instead of the default
+.B _pimpl
+to construct the names of parser implementations for the built-in XML
+Schema types and sample parser implementations.
+
+.IP "\fB\--impl-file-suffix \fIsuffix\fR"
+Use the provided
+.I suffix
+instead of the default
+.B -pimpl
+to construct the names of generated sample parser implementation files.
+
+\"
+\" NAMING CONVENTION
+\"
+
+.SH NAMING CONVENTION
+The compiler can be instructed to use a particular naming convention in
+the generated code. A number of widely-used conventions can be selected
+using the
+.B --type-naming
+and
+.B --function-naming
+options. A custom naming convention can be achieved using the
+.BR --type-regex ,
+.BR --accessor-regex ,
+.BR --one-accessor-regex ,
+.BR --opt-accessor-regex ,
+.BR --seq-accessor-regex ,
+.BR --modifier-regex ,
+.BR --one-modifier-regex ,
+.BR --opt-modifier-regex ,
+.BR --seq-modifier-regex ,
+.BR --parser-regex ,
+.BR --serializer-regex ,
+.BR --enumerator-regex ,
+and
+.B --element-type-regex
+options.
+
+The
+.B --type-naming
+option specifies the convention that should be used for naming C++ types.
+Possible values for this option are
+.B knr
+(default),
+.BR ucc ,
+and
+.BR java .
+The
+.B knr
+value (stands for K&R) signifies the standard, lower-case naming convention
+with the underscore used as a word delimiter, for example: foo, foo_bar.
+The
+.B ucc
+(stands for upper-camel-case) and
+.B java
+values a synonyms for the same naming convention where the first letter
+of each word in the name is capitalized, for example: Foo, FooBar.
+
+Similarly, the
+.B --function-naming
+option specifies the convention that should be used for naming C++ functions.
+Possible values for this option are
+.B knr
+(default),
+.BR lcc ,
+and
+.BR java .
+The
+.B knr
+value (stands for K&R) signifies the standard, lower-case naming convention
+with the underscore used as a word delimiter, for example: foo(), foo_bar().
+The
+.B lcc
+value (stands for lower-camel-case) signifies a naming convention where the
+first letter of each word except the first is capitalized, for example: foo(),
+fooBar(). The
+.B java
+naming convention is similar to the lower-camel-case one except that accessor
+functions are prefixed with get, modifier functions are prefixed with set,
+parsing functions are prefixed with parse, and serialization functions are
+prefixed with serialize, for example: getFoo(), setFooBar(), parseRoot(),
+serializeRoot().
+
+Note that the naming conventions specified with the
+.B --type-naming
+and
+.B --function-naming
+options perform only limited transformations on the
+names that come from the schema in the form of type, attribute, and element
+names. In other words, to get consistent results, your schemas should follow
+a similar naming convention as the one you would like to have in the generated
+code. Alternatively, you can use the
+.B --*-regex
+options (discussed below) to perform further transformations on the names
+that come from the schema.
+
+The
+.BR --type-regex ,
+.BR --accessor-regex ,
+.BR --one-accessor-regex ,
+.BR --opt-accessor-regex ,
+.BR --seq-accessor-regex ,
+.BR --modifier-regex ,
+.BR --one-modifier-regex ,
+.BR --opt-modifier-regex ,
+.BR --seq-modifier-regex ,
+.BR --parser-regex ,
+.BR --serializer-regex ,
+.BR --enumerator-regex ,
+and
+.B --element-type-regex
+options allow you to specify extra regular expressions for each name
+category in addition to the predefined set that is added depending on
+the
+.B --type-naming
+and
+.B --function-naming
+options. Expressions that are provided with the
+.B --*-regex
+options are evaluated prior to any predefined expressions. This allows
+you to selectively override some or all of the predefined transformations.
+When debugging your own expressions, it is often useful to see which
+expressions match which names. The
+.B --name-regex-trace
+option allows you to trace the process of applying
+regular expressions to names.
+
+The value for the
+.B --*-regex
+options should be a perl-like regular expression in the form
+.BI / pattern / replacement /\fR.
+Any character can be used as a delimiter instead of
+.BR / .
+Escaping of the delimiter character in
+.I pattern
+or
+.I replacement
+is not supported. All regular expressions for each category are pushed
+into a category-specific stack with the last specified expression
+considered first. The first match that succeeds is used. For the
+.B --one-accessor-regex
+(accessors with cardinality one),
+.B --opt-accessor-regex
+(accessors with cardinality optional), and
+.B --seq-accessor-regex
+(accessors with cardinality sequence) categories the
+.B --accessor-regex
+expressions are used as a fallback. For the
+.BR --one-modifier-regex ,
+.BR --opt-modifier-regex ,
+and
+.B --seq-modifier-regex
+categories the
+.B --modifier-regex
+expressions are used as a fallback. For the
+.B --element-type-regex
+category the
+.B --type-regex
+expressions are used as a fallback.
+
+The type name expressions
+.RB ( --type-regex )
+are evaluated on the name string that has the following format:
+
+[\fInamespace \fR]\fIname\fR[\fB,\fIname\fR][\fB,\fIname\fR][\fB,\fIname\fR]
+
+The element type name expressions
+.RB ( --element-type-regex ),
+effective only when the
+.B --generate-element-type
+option is specified, are evaluated on the name string that has the following
+format:
+
+.I namespace name
+
+In the type name format the
+.I namespace
+part followed by a space is only present for global type names. For global
+types and elements defined in schemas without a target namespace, the
+.I namespace
+part is empty but the space is still present. In the type name format after
+the initial
+.I name
+component, up to three additional
+.I name
+components can be present, separated by commas. For example:
+
+.B http://example.com/hello type
+
+.B foo
+
+.B foo,iterator
+
+.B foo,const,iterator
+
+The following set of predefined regular expressions is used to transform
+type names when the upper-camel-case naming convention is selected:
+
+.B /(?:[^ ]* )?([^,]+)/\\\\u$1/
+
+.B /(?:[^ ]* )?([^,]+),([^,]+)/\\\\u$1\\\\u$2/
+
+.B /(?:[^ ]* )?([^,]+),([^,]+),([^,]+)/\\\\u$1\\\\u$2\\\\u$3/
+
+.B /(?:[^ ]* )?([^,]+),([^,]+),([^,]+),([^,]+)/\\\\u$1\\\\u$2\\\\u$3\\\\u$4/
+
+The accessor and modifier expressions
+.RB ( --*accessor-regex
+and
+.BR --*modifier-regex )
+are evaluated on the name string that has the following format:
+
+\fIname\fR[\fB,\fIname\fR][\fB,\fIname\fR]
+
+After the initial
+.I name
+component, up to two additional
+.I name
+components can be present, separated by commas. For example:
+
+.B foo
+
+.B dom,document
+
+.B foo,default,value
+
+The following set of predefined regular expressions is used to transform
+accessor names when the
+.B java
+naming convention is selected:
+
+.B /([^,]+)/get\\\\u$1/
+
+.B /([^,]+),([^,]+)/get\\\\u$1\\\\u$2/
+
+.B /([^,]+),([^,]+),([^,]+)/get\\\\u$1\\\\u$2\\\\u$3/
+
+For the parser, serializer, and enumerator categories, the corresponding
+regular expressions are evaluated on local names of elements and on
+enumeration values, respectively. For example, the following predefined
+regular expression is used to transform parsing function names when the
+.B java
+naming convention is selected:
+
+.B /(.+)/parse\\\\u$1/
+
+See also the REGEX AND SHELL QUOTING section below.
+
+\"
+\" TYPE MAP
+\"
+.SH TYPE MAP
+Type map files are used in C++/Parser to define a mapping between XML
+Schema and C++ types. The compiler uses this information to determine
+the return types of
+.B post_*
+functions in parser skeletons corresponding to XML Schema types
+as well as argument types for callbacks corresponding to elements
+and attributes of these types.
+
+The compiler has a set of predefined mapping rules that map built-in
+XML Schema types to suitable C++ types (discussed below) and all
+other types to
+.BR void .
+By providing your own type maps you can override these predefined rules.
+The format of the type map file is presented below:
+
+.RS
+.B namespace
+.I schema-namespace
+[
+.I cxx-namespace
+]
+.br
+.B {
+.br
+ (
+.B include
+.IB file-name ;
+)*
+.br
+ ([
+.B type
+]
+.I schema-type cxx-ret-type
+[
+.I cxx-arg-type
+.RB ] ;
+)*
+.br
+.B }
+.br
+.RE
+
+Both
+.I schema-namespace
+and
+.I schema-type
+are regex patterns while
+.IR cxx-namespace ,
+.IR cxx-ret-type ,
+and
+.I cxx-arg-type
+are regex pattern substitutions. All names can be optionally enclosed
+in \fR" "\fR, for example, to include white-spaces.
+
+.I schema-namespace
+determines XML Schema namespace. Optional
+.I cxx-namespace
+is prefixed to every C++ type name in this namespace declaration.
+.I cxx-ret-type
+is a C++ type name that is used as a return type for the
+.B post_*
+functions. Optional
+.I cxx-arg-type
+is an argument type for callback functions corresponding to elements and
+attributes of this type. If
+.I cxx-arg-type
+is not specified, it defaults to
+.I cxx-ret-type
+if
+.I cxx-ret-type
+ends with
+.B *
+or
+.B &
+(that is, it is a pointer or a reference) and
+.B const
+\fIcxx-ret-type\fB&\fR otherwise.
+.I file-name
+is a file name either in the \fR" "\fR or < > format and is added with the
+.B #include
+directive to the generated code.
+
+The \fB#\fR character starts a comment that ends with a new line or end of
+file. To specify a name that contains \fB#\fR enclose it in \fR" "\fR. For
+example:
+
+.RS
+namespace http://www.example.com/xmlns/my my
+.br
+{
+.br
+ include "my.hxx";
+.br
+
+ # Pass apples by value.
+ #
+ apple apple;
+.br
+
+ # Pass oranges as pointers.
+ #
+ orange orange_t*;
+.br
+}
+.br
+.RE
+
+In the example above, for the
+.B http://www.example.com/xmlns/my#orange
+XML Schema type, the
+.B my::orange_t*
+C++ type will be used as both return and argument types.
+
+Several namespace declarations can be specified in a single file.
+The namespace declaration can also be completely omitted to map
+types in a schema without a namespace. For instance:
+
+.RS
+include "my.hxx";
+.br
+apple apple;
+.br
+
+namespace http://www.example.com/xmlns/my
+.br
+{
+.br
+ orange "const orange_t*";
+.br
+}
+.br
+.RE
+
+
+The compiler has a number of predefined mapping rules that can be
+presented as the following map files. The string-based XML Schema
+built-in types are mapped to either
+.B std::string
+or
+.B std::wstring
+depending on the character type selected with the
+.B --char-type
+option
+.RB ( char
+by default).
+
+.RS
+namespace http://www.w3.org/2001/XMLSchema
+.br
+{
+.br
+ boolean bool bool;
+.br
+
+ byte "signed char" "signed char";
+.br
+ unsignedByte "unsigned char" "unsigned char";
+.br
+
+ short short short;
+.br
+ unsignedShort "unsigned short" "unsigned short";
+.br
+
+ int int int;
+.br
+ unsignedInt "unsigned int" "unsigned int";
+.br
+
+ long "long long" "long long";
+.br
+ unsignedLong "unsigned long long" "unsigned long long";
+.br
+
+ integer "long long" "long long";
+.br
+
+ negativeInteger "long long" "long long";
+.br
+ nonPositiveInteger "long long" "long long";
+.br
+
+ positiveInteger "unsigned long long" "unsigned long long";
+.br
+ nonNegativeInteger "unsigned long long" "unsigned long long";
+.br
+
+ float float float;
+.br
+ double double double;
+.br
+ decimal double double;
+.br
+
+ string std::string;
+.br
+ normalizedString std::string;
+.br
+ token std::string;
+.br
+ Name std::string;
+.br
+ NMTOKEN std::string;
+.br
+ NCName std::string;
+.br
+ ID std::string;
+.br
+ IDREF std::string;
+.br
+ language std::string;
+.br
+ anyURI std::string;
+.br
+
+ NMTOKENS xml_schema::string_sequence;
+.br
+ IDREFS xml_schema::string_sequence;
+.br
+
+ QName xml_schema::qname;
+.br
+
+ base64Binary std::auto_ptr<xml_schema::buffer>
+.br
+ std::auto_ptr<xml_schema::buffer>;
+.br
+ hexBinary std::auto_ptr<xml_schema::buffer>
+.br
+ std::auto_ptr<xml_schema::buffer>;
+.br
+
+ date xml_schema::date;
+.br
+ dateTime xml_schema::date_time;
+.br
+ duration xml_schema::duration;
+.br
+ gDay xml_schema::gday;
+.br
+ gMonth xml_schema::gmonth;
+.br
+ gMonthDay xml_schema::gmonth_day;
+.br
+ gYear xml_schema::gyear;
+.br
+ gYearMonth xml_schema::gyear_month;
+.br
+ time xml_schema::time;
+.br
+}
+.br
+.RE
+
+
+The last predefined rule maps anything that wasn't mapped by previous
+rules to
+.BR void :
+
+.RS
+namespace .*
+.br
+{
+.br
+ .* void void;
+.br
+}
+.br
+.RE
+
+When you provide your own type maps with the
+.B --type-map
+option, they are evaluated first. This allows you to selectively override
+predefined rules.
+
+.\"
+.\" REGEX AND SHELL QUOTING
+.\"
+.SH REGEX AND SHELL QUOTING
+When entering a regular expression argument in the shell command line
+it is often necessary to use quoting (enclosing the argument in " "
+or ' ') in order to prevent the shell from interpreting certain
+characters, for example, spaces as argument separators and $ as
+variable expansions.
+
+Unfortunately it is hard to achieve this in a manner that is portable
+across POSIX shells, such as those found on GNU/Linux and UNIX, and
+Windows shell. For example, if you use " " for quoting you will get
+a wrong result with POSIX shells if your expression contains $. The
+standard way of dealing with this on POSIX systems is to use ' '
+instead. Unfortunately, Windows shell does not remove ' ' from
+arguments when they are passed to applications. As a result you may
+have to use ' ' for POSIX and " " for Windows ($ is not treated as
+a special character on Windows).
+
+Alternatively, you can save regular expression options into a file,
+one option per line, and use this file with the
+.B --options-file
+option. With this approach you don't need to worry about shell quoting.
+
+.\"
+.\" DIAGNOSTICS
+.\"
+.SH DIAGNOSTICS
+If the input file is not a valid W3C XML Schema definition,
+.B xsd
+will issue diagnostic messages to
+.B STDERR
+and exit with non-zero exit code.
+.SH BUGS
+Send bug reports to the xsd-users@codesynthesis.com mailing list.
+.SH COPYRIGHT
+Copyright (c) 2005-2009 Code Synthesis Tools CC.
+
+Permission is granted to copy, distribute and/or modify this
+document under the terms of the GNU Free Documentation License,
+version 1.2; with no Invariant Sections, no Front-Cover Texts and
+no Back-Cover Texts. Copy of the license can be obtained from
+http://codesynthesis.com/licenses/fdl-1.2.txt
diff --git a/documentation/xsd.xhtml b/documentation/xsd.xhtml
new file mode 100644
index 0000000..b85e896
--- /dev/null
+++ b/documentation/xsd.xhtml
@@ -0,0 +1,1508 @@
+<?xml version="1.0" encoding="iso-8859-1"?>
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
+
+<head>
+ <title>XSD 3.3.0 Compiler Command Line Manual</title>
+
+ <meta name="copyright" content="&copy; 2005-2009 Code Synthesis Tools CC"/>
+ <meta name="keywords" content="xsd,xml,schema,c++,mapping,data,binding,code,generator,manual,man,page"/>
+ <meta name="description" content="XSD Compiler Command Line Manual"/>
+
+ <link rel="stylesheet" type="text/css" href="default.css" />
+
+<style type="text/css">
+
+ #synopsis {
+ list-style-type: none;
+ }
+
+ #synopsis li {
+ padding-top : 0.0em;
+ padding-bottom : 0.0em;
+ }
+
+ #commands dt {
+ padding-top : 0.4em;
+ }
+
+ #commands dd {
+ padding-bottom : 0.4em;
+ padding-left : 2em;
+ }
+
+ .options dt {
+ padding-top : 0.4em;
+ }
+
+ .options dd {
+ padding-top : 0.1em;
+ padding-bottom : 0.4em;
+ padding-left : 1.4em;
+ }
+
+</style>
+</head>
+
+<body>
+<div id="container">
+ <div id="content">
+
+ <h1>NAME</h1>
+
+ <p>xsd - W3C XML Schema to C++ Compiler</p>
+
+ <h1>SYNOPSIS</h1>
+
+ <dl id="synopsis">
+ <dt><code><b>xsd</b> <i>command</i> [<i>options</i>] <i>file</i> [<i>file</i> ...]</code></dt>
+ <dt><code><b>xsd help</b> [<i>command</i>]</code></dt>
+ <dt><code><b>xsd version</b></code></dt>
+ </dl>
+
+ <h1>DESCRIPTION</h1>
+
+ <p><code><b>xsd</b></code> generates vocabulary-specific, statically-typed
+ C++ mapping from W3C XML Schema definitions. Particular mapping to
+ produce is selected by a <code><i>command</i></code>. Each mapping has
+ a number of mapping-specific <code><i>options</i></code> that should
+ appear, if any, after the <code><i>command</i></code>. Input files should
+ be W3C XML Schema definitions. The exact set of the generated files depends
+ on the selected mapping and options.</p>
+
+ <h1>COMMANDS</h1>
+
+ <dl id="commands">
+ <dt><code><b>cxx-tree</b></code></dt>
+ <dd>Generate the C++/Tree mapping. For each input file in the form
+ <code><b>name.xsd</b></code> the following C++ files are generated:
+ <code><b>name.hxx</b></code> (header file),
+ <code><b>name.ixx</b></code> (inline file, generated only if the
+ <code><b>--generate-inline</b></code> option is specified),
+ <code><b>name.cxx</b></code> (source file), and
+ <code><b>name-fwd.hxx</b></code> (forward declaration file, generated
+ only if the <code><b>--generate-forward</b></code> option is
+ specified).</dd>
+
+ <dt><code><b>cxx-parser</b></code></dt>
+ <dd>Generate the C++/Parser mapping. For each input file in the form
+ <code><b>name.xsd</b></code> the following C++ files are generated:
+ <code><b>name-pskel.hxx</b></code> (parser skeleton header file),
+ <code><b>name-pskel.ixx</b></code> (parser skeleton inline file,
+ generated only if the <code><b>--generate-inline</b></code>
+ option is specified), and
+ <code><b>name-pskel.cxx</b></code> (parser skeleton source file).
+ If the <code><b>--generate-noop-impl</b></code> or
+ <code><b>--generate-print-impl</b></code> option is specified,
+ the following additional sample implementation files are generated:
+ <code><b>name-pimpl.hxx</b></code> (parser implementation header
+ file) and
+ <code><b>name-pimpl.cxx</b></code> (parser implementation source
+ file). If the <code><b>--generate-test-driver</b></code> option
+ is specified, the additional <code><b>name-driver.cxx</b></code>
+ test driver file is generated.</dd>
+
+ <dt><code><b>help</b></code></dt>
+ <dd>Print usage information and exit. Use
+ <p><code><b>xsd help</b> <i>command</i></code></p>
+ for command-specific help.
+ </dd>
+
+ <dt><code><b>version</b></code></dt>
+ <dd>Print version and exit.</dd>
+ </dl>
+
+ <h1>OPTIONS</h1>
+
+ <p>Command-specific <code><i>options</i></code>, if any, should appear
+ after the corresponding <code><i>command</i></code>.</p>
+
+ <h2>COMMON OPTIONS</h2>
+
+ <dl class="options">
+ <dt><code><b>--char-type</b> <i>type</i></code></dt>
+ <dd>Generate code using the provided character <code><i>type</i></code>
+ instead of the default <code><b>char</b></code>. Valid values
+ are <code><b>char</b></code> and <code><b>wchar_t</b></code>.</dd>
+
+ <dt><code><b>--output-dir</b> <i>dir</i></code></dt>
+ <dd>Write generated files to <code><i>dir</i></code> instead of
+ the current directory.</dd>
+
+ <dt><code><b>--namespace-map</b> <i>xns</i><b>=</b><i>cns</i></code></dt>
+ <dd>Map XML Schema namespace <i>xns</i> to C++ namespace <i>cns</i>.
+ Repeat this option to specify mapping for more than one XML Schema
+ namespace. For example, the following option:
+
+ <p><code><b>--namespace-map http://example.com/foo/bar=foo::bar</b></code></p>
+
+ <p>will map the <code><b>http://example.com/foo/bar</b></code>
+ XML Schema namespace to the <code><b>foo::bar</b></code> C++
+ namespace.</p>
+ </dd>
+
+ <dt><code><b>--namespace-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema namespace names to C++ namespace
+ names. <code><i>regex</i></code> is a perl-like regular expression in
+ the form <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>.
+ Any character can be used as a delimiter instead of <code><b>/</b></code>.
+ Escaping of the delimiter character in <code><i>pattern</i></code> or
+ <code><i>replacement</i></code> is not supported.
+
+ <p>All regular expressions are pushed into a stack with the last
+ specified expression considered first. The first match that
+ succeeds is used. Regular expressions are applied to a string
+ in the form</p>
+
+ <p><code><i>filename</i> <i>namespace</i></code></p>
+
+ <p>For example,</p>
+
+ <p><code><b>XMLSchema.xsd http://www.w3.org/2001/XMLSchema</b></code></p>
+
+ <p>The <code><i>filename</i></code> for the current translation unit
+ is empty. For example, if you have file <code><b>hello.xsd</b></code>
+ with namespace <code><b>http://example.com/hello</b></code> and you run
+ <code><b>xsd</b></code> on this file, then the string in question
+ would be:</p>
+
+ <p><code>&nbsp;<b>http://example.com/hello</b></code></p>
+
+ <p>Note the leading space.</p>
+
+ <p>The following three steps are performed for each regular expression
+ until the match is found:</p>
+
+ <ol>
+ <li>The expression is applied and if the result is empty the
+ next expression is considered.</li>
+
+ <li>All <code><b>/</b></code> are replaced with
+ <code><b>::</b></code>.</li>
+
+ <li>The result is verified to be a valid C++ scope name (e.g.,
+ <code><b>foo::bar</b></code>). If this test succeeds, the
+ result is used as a C++ namespace name.</li>
+ </ol>
+
+ <p>As an example, the following expression maps XML Schema
+ namespaces in the form
+ <code><b>http://example.com/foo/bar</b></code> to C++
+ namespaces in the form <code><b>foo::bar</b></code>:</p>
+
+ <p><code><b>%.* http://example.com/(.+)%$1%</b></code></p>
+
+ <p>See also the REGEX AND SHELL QUOTING section below.</p>
+ </dd>
+
+ <dt><code><b>--namespace-regex-trace</b></code></dt>
+ <dd>Trace the process of applying regular expressions specified with
+ the <code><b>--namespace-regex</b></code> option. Use this option
+ to find out why your regular expressions don't do what you expected
+ them to do.
+ </dd>
+
+ <!-- Reserved names -->
+
+ <dt><code><b>--reserved-name</b> <i>name</i>[<b>=</b><i>rep</i>]</code></dt>
+ <dd>Add <code><i>name</i></code> to the list of names that should not
+ be used as identifiers. The name can optionally be followed by
+ <code><b>=</b></code> and the replacement name that should be
+ used instead. All C++ keywords are already in this list.
+ </dd>
+
+ <!-- Include -->
+
+ <dt><code><b>--include-with-brackets</b></code></dt>
+ <dd>Use angle brackets (&lt;&gt;) instead of quotes ("") in
+ generated <code><b>#include</b></code> directives.
+ </dd>
+
+ <dt><code><b>--include-prefix</b> <i>prefix</i></code></dt>
+ <dd>Add <code><i>prefix</i></code> to generated <code><b>#include</b></code>
+ directive paths.
+
+ <p>For example, if you had the following import element in your
+ schema</p>
+
+ <p><code><b>&lt;import namespace="..." schemaLocation="base.xsd"/&gt;</b></code></p>
+
+ <p>and compiled this fragment with <code><b>--include-prefix schemas/</b></code>,
+ then the include directive in the generated code would be:</p>
+
+ <p><code><b>#include "schemas/base.hxx"</b></code></p>
+ </dd>
+
+ <dt><code><b>--include-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to transform <code><b>#include</b></code> directive paths.
+ <code><i>regex</i></code> is a perl-like regular expression in
+ the form <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>.
+ Any character can be used as a delimiter instead of <code><b>/</b></code>.
+ Escaping of the delimiter character in <code><i>pattern</i></code> or
+ <code><i>replacement</i></code> is not supported.
+
+ <p>All regular expressions are pushed into a stack with the last
+ specified expression considered first. The first match that
+ succeeds is used.</p>
+
+ <p>As an example, the following expression transforms paths
+ in the form <code><b>schemas/foo/bar</b></code> to paths
+ in the form <code><b>generated/foo/bar</b></code>:</p>
+
+ <p><code><b>%schemas/(.+)%generated/$1%</b></code></p>
+
+ <p>See also the REGEX AND SHELL QUOTING section below.</p>
+ </dd>
+
+ <dt><code><b>--include-regex-trace</b></code></dt>
+ <dd>Trace the process of applying regular expressions specified with
+ the <code><b>--include-regex</b></code> option. Use this option
+ to find out why your regular expressions don't do what you expected
+ them to do.
+ </dd>
+
+ <dt><code><b>--guard-prefix</b> <i>prefix</i></code></dt>
+ <dd>Add <code><i>prefix</i></code> to generated header inclusion guards.
+ The prefix is transformed to upper case and all characters that are
+ illegal in a preprocessor macro name are replaced with underscores.
+ If this option is not specified then the directory part of the
+ input schema file is used as a prefix.
+ </dd>
+
+ <!-- Suffixes. -->
+
+ <dt><code><b>--hxx-suffix</b> <i>suffix</i></code></dt>
+ <dd>Use the provided <code><i>suffix</i></code> instead of the default
+ <code><b>.hxx</b></code> to construct the name of the header file.
+ Note that this suffix is also used to construct names for
+ included/imported schemas.
+ </dd>
+
+ <dt><code><b>--ixx-suffix</b> <i>suffix</i></code></dt>
+ <dd>Use the provided <code><i>suffix</i></code> instead of the default
+ <code><b>.ixx</b></code> to construct the name of the inline file.
+ </dd>
+
+ <dt><code><b>--cxx-suffix</b> <i>suffix</i></code></dt>
+ <dd>Use the provided <code><i>suffix</i></code> instead of the default
+ <code><b>.cxx</b></code> to construct the name of the source file.
+ </dd>
+
+ <dt><code><b>--hxx-regex</b> <i>regex</i></code></dt>
+ <dd>Use the provided expression to construct the name of the header
+ file. <code><i>regex</i></code> is a perl-like regular expression
+ in the form
+ <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>.
+ Note that this expression is also used to construct names for
+ included/imported schemas. See also the REGEX AND SHELL QUOTING
+ section below.
+ </dd>
+
+ <dt><code><b>--ixx-regex</b> <i>regex</i></code></dt>
+ <dd>Use the provided expression to construct the name of the inline
+ file. <code><i>regex</i></code> is a perl-like regular expression
+ in the form
+ <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>.
+ See also the REGEX AND SHELL QUOTING section below.
+ </dd>
+
+ <dt><code><b>--cxx-regex</b> <i>regex</i></code></dt>
+ <dd>Use the provided expression to construct the name of the source
+ file. <code><i>regex</i></code> is a perl-like regular expression
+ in the form
+ <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>.
+ See also the REGEX AND SHELL QUOTING section below.
+ </dd>
+
+
+ <dt><code><b>--hxx-prologue</b> <i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the header file.
+ </dd>
+
+ <dt><code><b>--ixx-prologue</b> <i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the inline file.
+ </dd>
+
+ <dt><code><b>--cxx-prologue</b> <i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the source file.
+ </dd>
+
+ <dt><code><b>--prologue</b> <i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of each generated
+ file for which there is no file-specific prologue.
+ </dd>
+
+ <dt><code><b>--hxx-epilogue</b> <i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the header file.
+ </dd>
+
+ <dt><code><b>--ixx-epilogue</b> <i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the inline file.
+ </dd>
+
+ <dt><code><b>--cxx-epilogue</b> <i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the source file.
+ </dd>
+
+ <dt><code><b>--epilogue</b> <i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of each generated
+ file for which there is no file-specific epilogue.
+ </dd>
+
+
+ <dt><code><b>--hxx-prologue-file</b> <i>file</i></code></dt>
+ <dd>Insert the content of the <code><i>file</i></code> at the beginning
+ of the header file.
+ </dd>
+
+ <dt><code><b>--ixx-prologue-file</b> <i>file</i></code></dt>
+ <dd>Insert the content of the <code><i>file</i></code> at the beginning
+ of the inline file.
+ </dd>
+
+ <dt><code><b>--cxx-prologue-file</b> <i>file</i></code></dt>
+ <dd>Insert the content of the <code><i>file</i></code> at the beginning
+ of the source file.
+ </dd>
+
+ <dt><code><b>--prologue-file</b> <i>file</i></code></dt>
+ <dd>Insert the content of the <code><i>file</i></code> at the beginning
+ of each generated file for which there is no file-specific prologue
+ file.
+ </dd>
+
+ <dt><code><b>--hxx-epilogue-file</b> <i>file</i></code></dt>
+ <dd>Insert the content of the <code><i>file</i></code> at the end of the
+ header file.
+ </dd>
+
+ <dt><code><b>--ixx-epilogue-file</b> <i>file</i></code></dt>
+ <dd>Insert the content of the <code><i>file</i></code> at the end of the
+ inline file.
+ </dd>
+
+ <dt><code><b>--cxx-epilogue-file</b> <i>file</i></code></dt>
+ <dd>Insert the content of the <code><i>file</i></code> at the end of the
+ source file.
+ </dd>
+
+ <dt><code><b>--epilogue-file</b> <i>file</i></code></dt>
+ <dd>Insert the content of the <code><i>file</i></code> at the end of each
+ generated file for which there is no file-specific epilogue file.
+ </dd>
+
+ <dt><code><b>--export-symbol</b> <i>symbol</i></code></dt>
+ <dd>Insert <code><i>symbol</i></code> in places where DLL
+ export/import control statements
+ (<code><b>__declspec(dllexport/dllimport)</b></code>) are necessary.
+ </dd>
+
+ <dt><code><b>--export-xml-schema</b></code></dt>
+ <dd>Export/import types in the XML Schema namespace using the export
+ symbol provided with the <code><b>--export-symbol</b></code> option.
+ </dd>
+
+ <dt><code><b>--export-maps</b></code></dt>
+ <dd>Export polymorphism support maps from a Win32 DLL into which this
+ generated code is linked. This is necessary when your type hierarchy
+ is split across several DLLs since otherwise each DLL will have its
+ own set of maps. In this situation the generated code for the DLL
+ which contains base types and/or substitution group heads should be
+ compiled with this option and the generated code for all other
+ DLLs should be compiled with <code><b>--import-maps</b></code>.
+ This option is only valid together with
+ <code><b>--generate-polymorphic</b></code>.
+ </dd>
+
+ <dt><code><b>--import-maps</b></code></dt>
+ <dd>Import polymorphism support maps to a Win32 DLL or executable into
+ which this generated code is linked. See the <code><b>--export-maps</b></code>
+ option documentation for details. This options is only valid together
+ with <code><b>--generate-polymorphic</b></code>.
+ </dd>
+
+ <dt><code><b>--disable-warning</b> <i>warn</i></code></dt>
+ <dd>Disable printing warning with id <i>warn</i>. If <code><b>all</b></code>
+ is specified for the warning id then all warnings are disabled.
+ </dd>
+
+ <!-- misc options -->
+
+ <dt><code><b>--show-sloc</b></code></dt>
+ <dd>Show the number of generated physical source lines of code (SLOC).
+ </dd>
+
+ <dt><code><b>--sloc-limit</b> <i>num</i></code></dt>
+ <dd>Check that the number of generated physical source lines of code
+ (SLOC) does not exceed <code><i>num</i></code>.
+ </dd>
+
+ <dt><code><b>--options-file</b> <i>file</i></code></dt>
+ <dd>Read additional options from <code><i>file</i></code>. Each option
+ should appear on a separate line optionally followed by space and
+ an argument. Empty lines and lines starting with <code><b>#</b></code>
+ are ignored. The semantics of providing options in a
+ file is equivalent to providing the same set of options in
+ the same order in the command line at the point where the
+ <code><b>--options-file</b></code> option is specified
+ except that shell escaping and quoting is not required.
+ Repeat this option to specify more than one options files.
+ </dd>
+
+ <dt><code><b>--proprietary-license</b></code></dt>
+ <dd>Indicate that the generated code is licensed under a proprietary
+ license instead of the GPL.
+ </dd>
+
+ <!-- Anonymous options. -->
+
+ <dt><code><b>--preserve-anonymous</b></code></dt>
+ <dd>Preserve anonymous types. By default anonymous types are
+ automatically named with names derived from the enclosing
+ elements/attributes. Because mappings implemented by this
+ compiler require all types to be named, this option is only
+ useful if you want to make sure your schemas don't have
+ anonymous types.
+ </dd>
+
+ <dt><code><b>--show-anonymous</b></code></dt>
+ <dd>Show elements and attributes that are of anonymous types.
+ This option only makes sense together with the
+ <code><b>--preserve-anonymous</b></code> option.
+ </dd>
+
+ <dt><code><b>--anonymous-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to derive names for anonymous types from the enclosing
+ attributes/elements. <code><i>regex</i></code> is a perl-like regular
+ expression in the form
+ <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>.
+ Any character can be used as a delimiter instead of <code><b>/</b></code>.
+ Escaping of the delimiter character in <code><i>pattern</i></code> or
+ <code><i>replacement</i></code> is not supported.
+
+ <p>All regular expressions are pushed into a stack with the last
+ specified expression considered first. The first match that
+ succeeds is used. Regular expressions are applied to a string
+ in the form</p>
+
+ <p><code><i>filename</i> <i>namespace</i> <i>xpath</i></code></p>
+
+ <p>For example,</p>
+
+ <p><code><b>hello.xsd http://example.com/hello element</b></code></p>
+ <p><code><b>hello.xsd http://example.com/hello type/element</b></code></p>
+
+ <p>The <code><i>filename</i></code> for the current translation unit
+ is empty. For example, if you have file <code><b>hello.xsd</b></code>
+ with namespace <code><b>http://example.com/hello</b></code> and you run
+ <code><b>xsd</b></code> on this file, then the string in question
+ would be:</p>
+
+ <p><code>&nbsp;<b>http://example.com/hello element</b></code></p>
+
+ <p>Note the leading space.</p>
+
+ <p>As an example, the following expression makes all the derived
+ names start with capital letters. This could be useful when
+ your naming convention requires type names to start with
+ capital letters:</p>
+
+ <p><code><b>%.* .* (.+/)*(.+)%\u$2%</b></code></p>
+
+ <p>See also the REGEX AND SHELL QUOTING section below.</p>
+ </dd>
+
+ <dt><code><b>--anonymous-regex-trace</b></code></dt>
+ <dd>Trace the process of applying regular expressions specified with
+ the <code><b>--anonymous-regex</b></code> option. Use this option
+ to find out why your regular expressions don't do what you expected
+ them to do.
+ </dd>
+
+ <!-- Location mapping options. -->
+
+ <dt><code><b>--location-map</b> <i>ol</i><b>=</b><i>nl</i></code></dt>
+ <dd>Map the original schema location <i>ol</i> that is specified in
+ the XML Schema include or import elements to new schema
+ location <i>nl</i>. Repeat this option to map more than one
+ schema location. For example, the following option maps the
+ <code><b>http://example.com/foo.xsd</b></code> URL to the
+ <code><b>foo.xsd</b></code> local file.
+
+ <p><code><b>--location-map http://example.com/foo.xsd=foo.xsd</b></code></p>
+ </dd>
+
+ <dt><code><b>--location-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to map schema locations that are specified in the XML Schema
+ include or import elements. <code><i>regex</i></code> is a perl-like
+ regular expression in the form
+ <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>.
+ Any character can be used as a delimiter instead of <code><b>/</b></code>.
+ Escaping of the delimiter character in <code><i>pattern</i></code> or
+ <code><i>replacement</i></code> is not supported. All regular
+ expressions are pushed into a stack with the last specified
+ expression considered first. The first match that succeeds is used.
+
+ <p>For example, the following expression maps URL locations in the form
+ <code><b>http://example.com/foo/bar.xsd</b></code> to local files
+ in the form <code><b>bar.xsd</b></code>:</p>
+
+ <p><code><b>%http://.+/(.+)%$1%</b></code></p>
+
+ <p>See also the REGEX AND SHELL QUOTING section below.</p>
+ </dd>
+
+ <dt><code><b>--location-regex-trace</b></code></dt>
+ <dd>Trace the process of applying regular expressions specified with
+ the <code><b>--location-regex</b></code> option. Use this option
+ to find out why your regular expressions don't do what you expected
+ them to do.
+ </dd>
+
+ <!-- File-per-type compilation mode options. -->
+
+ <dt><code><b>--file-per-type</b></code></dt>
+ <dd>Generate a separate set of C++ files for each type defined in XML
+ Schema. Note that in this mode you only need to compile the root
+ schema(s) and the code will be generated for all included and
+ imported schemas. This compilation mode is primarily useful when
+ some of your schemas cannot be compiled separately or have cyclic
+ dependencies which involve type inheritance.
+ </dd>
+
+
+ <dt><code><b>--type-file-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate type names to file names when the
+ <code><b>--type-per-file</b></code> option is specified.
+ <code><i>regex</i></code> is a perl-like regular expression in the form
+ <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>.
+ Any character can be used as a delimiter instead of <code><b>/</b></code>.
+ Escaping of the delimiter character in <code><i>pattern</i></code> or
+ <code><i>replacement</i></code> is not supported. All regular
+ expressions are pushed into a stack with the last specified
+ expression considered first. The first match that succeeds is used.
+ Regular expressions are applied to a string in the form
+
+ <p><code><i>namespace</i> <i>type-name</i></code></p>
+
+ <p>For example, the following expression maps type <code><b>foo</b></code>
+ that is defined in the <code><b>http://example.com/bar</b></code>
+ namespace to file name <code><b>bar-foo</b></code>:</p>
+
+ <p><code><b>%http://example.com/(.+) (.+)%$1-$2%</b></code></p>
+
+ <p>See also the REGEX AND SHELL QUOTING section below.</p>
+ </dd>
+
+ <dt><code><b>--type-file-regex-trace</b></code></dt>
+ <dd>Trace the process of applying regular expressions specified with
+ the <code><b>--type-file-regex</b></code> option. Use this option
+ to find out why your regular expressions don't do what you expected
+ them to do.
+ </dd>
+
+ <!-- File list options. -->
+
+ <dt><code><b>--file-list</b> <i>file</i></code></dt>
+ <dd>Write a list of generated C++ files to <code><i>file</i></code>.
+ This option is primarily useful in the file-per-type compilation
+ mode (<code><b>--file-per-type</b></code>) to create a list of
+ generated C++ files, for example, as a makefile fragment.
+ </dd>
+
+ <dt><code><b>--file-list-prologue</b> <i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the file list.
+ As a convenience, all occurrences of the \n character sequence in
+ <code><i>text</i></code> are replaced with new lines. This option
+ can, for example, be used to assign the generated file list to a
+ makefile variable.
+ </dd>
+
+ <dt><code><b>--file-list-epilogue</b> <i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the file list.
+ As a convenience, all occurrences of the \n character sequence in
+ <code><i>text</i></code> are replaced with new lines.
+ </dd>
+
+ <dt><code><b>--file-list-delim</b> <i>text</i></code></dt>
+ <dd>Delimit file names written to the file list with
+ <code><i>text</i></code> instead of new lines. As a convenience,
+ all occurrences of the \n character sequence in
+ <code><i>text</i></code> are replaced with new lines.
+ </dd>
+
+ </dl>
+
+ <h2>CXX-TREE COMMAND OPTIONS</h2>
+
+ <dl class="options">
+ <dt><code><b>--generate-polymorphic</b></code></dt>
+ <dd>Generate polymorphism-aware code. Specify this option if you use
+ substitution groups or <code><b>xsi:type</b></code>.</dd>
+
+ <dt><code><b>--generate-serialization</b></code></dt>
+ <dd>Generate serialization functions. Serialization functions
+ convert the object model back to XML.</dd>
+
+ <dt><code><b>--generate-inline</b></code></dt>
+ <dd>Generate simple functions inline. This option triggers creation
+ of the inline file.</dd>
+
+ <dt><code><b>--generate-ostream</b></code></dt>
+ <dd>Generate ostream insertion operators
+ (<code><b>operator&lt;&lt;</b></code>) for generated types. This
+ allows to easily print a fragment or the whole object model
+ for debugging or logging.</dd>
+
+ <dt><code><b>--generate-doxygen</b></code></dt>
+ <dd>Generate documentation comments suitable for extraction by the
+ Doxygen documentation system. Documentation from annotations
+ is added to the comments if present in the schema.</dd>
+
+ <dt><code><b>--generate-comparison</b></code></dt>
+ <dd>Generate comparison operators
+ (<code><b>operator==</b></code> and <code><b>operator!=</b></code>)
+ for complex types. Comparison is performed memberwise.</dd>
+
+ <dt><code><b>--generate-default-ctor</b></code></dt>
+ <dd>Generate default constructors even for types that have required
+ members. Required members of an instance constructed using such a
+ constructor are not initialized and accessing them results in
+ undefined behavior.</dd>
+
+ <dt><code><b>--generate-from-base-ctor</b></code></dt>
+ <dd>Generate constructors that expect an instance of a base type
+ followed by all required members.</dd>
+
+ <dt><code><b>--generate-wildcard</b></code></dt>
+ <dd>Generate accessors and modifiers as well as parsing and serialization
+ code for XML Schema wildcards (<code><b>any</b></code> and
+ <code><b>anyAttribute</b></code>). XML content matched by wildcards
+ is presented as DOM fragments. Note that you need to initialize the
+ Xerces-C++ runtime if you are using this option.</dd>
+
+ <dt><code><b>--generate-insertion</b> <i>os</i></code></dt>
+ <dd>Generate data representation stream insertion operators for
+ the <code><i>os</i></code> output stream type. Repeat this
+ option to specify more than one stream type. The ACE CDR stream
+ (<code><b>ACE_OutputCDR</b></code>) and RPC XDR are recognized
+ by the compiler and the necessary <code><b>#include</b></code>
+ directives are automatically generated. For custom stream
+ types use the <code><b>--hxx-prologue*</b></code> options
+ to provide the necessary declarations.</dd>
+
+ <dt><code><b>--generate-extraction</b> <i>is</i></code></dt>
+ <dd>Generate data representation stream extraction constructors for
+ the <code><i>is</i></code> input stream type. Repeat this
+ option to specify more than one stream type. The ACE CDR stream
+ (<code><b>ACE_InputCDR</b></code>) and RPC XDR are recognized by
+ the compiler and the necessary <code><b>#include</b></code>
+ directives are automatically generated. For custom stream
+ types use the <code><b>--hxx-prologue*</b></code> options
+ to provide the necessary declarations.</dd>
+
+ <dt><code><b>--generate-forward</b></code></dt>
+ <dd>Generate a separate header file with forward declarations for the
+ types being generated.</dd>
+
+ <dt><code><b>--generate-xml-schema</b></code></dt>
+ <dd>Generate a C++ header file as if the schema being compiled defines
+ the XML Schema namespace. In particular, the resulting file will
+ have definitions for all XML Schema built-in types. The schema file
+ provided to the compiler need not exist and is only used to derive
+ the name of the resulting header file. Use the
+ <code><b>--extern-xml-schema</b></code> option to include this file
+ in the generated files for other schemas.</dd>
+
+ <dt><code><b>--extern-xml-schema</b> <i>file</i></code></dt>
+ <dd>Include a header file derived from <i>file</i> instead of
+ generating the XML Schema namespace mapping inline. The provided
+ file need not exist and is only used to derive the name of the
+ included header file. Use the <code><b>--generate-xml-schema</b></code>
+ option to generate this header file.</dd>
+
+ <dt><code><b>--suppress-parsing</b></code></dt>
+ <dd>Suppress the generation of the parsing functions and constructors.
+ Use this option to reduce the generated code size when parsing
+ from XML is not needed.</dd>
+
+ <dt><code><b>--generate-element-type</b></code></dt>
+ <dd>Generate types instead of parsing and serialization functions
+ for root elements. This is primarily useful to distinguish
+ object models with the same root type but with different root
+ elements.</dd>
+
+ <dt><code><b>--generate-element-map</b></code></dt>
+ <dd>Generate a root element map that allows uniform parsing and
+ serialization of multiple root elements. This option is only
+ valid together with <code><b>--generate-element-type</b></code>.
+ </dd>
+
+ <dt><code><b>--generate-intellisense</b></code></dt>
+ <dd>Generate workarounds for IntelliSense bugs in Visual Studio
+ 2005 (8.0). When this option is used, the resulting code is
+ slightly more verbose. IntelliSense in Visual Studio 2008 (9.0)
+ does not require these workarounds. Support for IntelliSense in
+ Visual Studio 2003 (7.1) is improved with this option but is
+ still incomplete.</dd>
+
+ <dt><code><b>--omit-default-attributes</b></code></dt>
+ <dd>Omit attributes with default and fixed values from serialized
+ XML documents.</dd>
+
+ <!-- Naming -->
+
+ <dt><code><b>--type-naming</b> <i>style</i></code></dt>
+ <dd>Specify the type naming convention that should be used in the
+ generated code. Valid styles are <code><b>knr</b></code>
+ (default), <code><b>ucc</b></code>, and <code><b>java</b></code>.
+ See the NAMING CONVENTION section below for more information.
+ </dd>
+
+ <dt><code><b>--function-naming</b> <i>style</i></code></dt>
+ <dd>Specify the function naming convention that should be used in the
+ generated code. Valid styles are <code><b>knr</b></code>
+ (default), <code><b>lcc</b></code>, and <code><b>java</b></code>.
+ See the NAMING CONVENTION section below for more information.
+ </dd>
+
+ <dt><code><b>--type-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema type names to C++ type names. See the
+ NAMING CONVENTION section below for more information.
+ </dd>
+
+ <dt><code><b>--accessor-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema names of elements/attributes to C++
+ accessor function names. See the NAMING CONVENTION section below
+ for more information.
+ </dd>
+
+ <dt><code><b>--one-accessor-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema names of elements/attributes with
+ cardinality one to C++ accessor function names. See the NAMING
+ CONVENTION section below for more information.
+ </dd>
+
+ <dt><code><b>--opt-accessor-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema names of elements/attributes with
+ cardinality optional to C++ accessor function names. See the
+ NAMING CONVENTION section below for more information.
+ </dd>
+
+ <dt><code><b>--seq-accessor-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema names of elements/attributes with
+ cardinality sequence to C++ accessor function names. See the
+ NAMING CONVENTION section below for more information.
+ </dd>
+
+ <dt><code><b>--modifier-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema names of elements/attributes to C++
+ modifier function names. See the NAMING CONVENTION section below
+ for more information.
+ </dd>
+
+ <dt><code><b>--one-modifier-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema names of elements/attributes with
+ cardinality one to C++ modifier function names. See the NAMING
+ CONVENTION section below for more information.
+ </dd>
+
+ <dt><code><b>--opt-modifier-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema names of elements/attributes with
+ cardinality optional to C++ modifier function names. See the
+ NAMING CONVENTION section below for more information.
+ </dd>
+
+ <dt><code><b>--seq-modifier-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema names of elements/attributes with
+ cardinality sequence to C++ modifier function names. See the
+ NAMING CONVENTION section below for more information.
+ </dd>
+
+ <dt><code><b>--parser-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema element names to C++ parsing function
+ names. See the NAMING CONVENTION section below for more information.
+ </dd>
+
+ <dt><code><b>--serializer-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema element names to C++ serialization
+ function names. See the NAMING CONVENTION section below for more
+ information.
+ </dd>
+
+ <dt><code><b>--enumerator-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema enumeration values to C++ enumerator
+ names. See the NAMING CONVENTION section below for more information.
+ </dd>
+
+ <dt><code><b>--element-type-regex</b> <i>regex</i></code></dt>
+ <dd>Add <code><i>regex</i></code> to the list of regular expressions
+ used to translate XML Schema element names to C++ element type
+ names. See the NAMING CONVENTION section below for more information.
+ </dd>
+
+ <dt><code><b>--name-regex-trace</b></code></dt>
+ <dd>Trace the process of applying regular expressions specified with
+ the name transformation options. Use this option to find out why
+ your regular expressions don't do what you expected them to do.
+ </dd>
+
+ <!-- Root element. -->
+
+ <dt><code><b>--root-element-first</b></code></dt>
+ <dd>Treat only the first global element as a document root. By default
+ all global elements are considered document roots.
+ </dd>
+
+ <dt><code><b>--root-element-last</b></code></dt>
+ <dd>Treat only the last global element as a document root. By default
+ all global elements are considered document roots.
+ </dd>
+
+ <dt><code><b>--root-element-all</b></code></dt>
+ <dd>Treat all global elements as document roots. This is the default
+ behavior. By explicitly specifying this option you can suppress
+ the warning that is issued if more than one global element is defined.
+ </dd>
+
+ <dt><code><b>--root-element-none</b></code></dt>
+ <dd>Do not treat any global elements as document roots. By default
+ all global elements are considered document roots.
+ </dd>
+
+ <dt><code><b>--root-element</b> <i>element</i></code></dt>
+ <dd>Treat only <code><i>element</i></code> as a document root. Repeat this
+ option to specify more than one root element.
+ </dd>
+
+ <!-- Custom type. -->
+
+ <dt><code><b>--custom-type</b>
+ <i>name</i>[<b>=</b><i>type</i>[<b>/</b><i>base</i>]]</code></dt>
+ <dd>Use a custom C++ type <i>type</i> instead of the generated class for
+ XML Schema type <i>name</i>. If <i>type</i> is not present
+ or empty then the custom type is assumed to have the same name and
+ be defined in the same namespace as the generated class would have.
+ If <i>base</i> is specified then the generated class is still
+ generated but with that name.
+ </dd>
+
+ <dt><code><b>--custom-type-regex</b>
+ <b>/</b><i>name-pat</i><b>/</b>[<i>type-sub</i><b>/</b>[<i>base-sub</i><b>/</b>]]</code></dt>
+ <dd>For each type defined in XML Schema that matches the <i>name-pat</i>
+ pattern use a custom C++ type instead of the generated class. The
+ name of the custom type is obtained by substituting <i>type-sub</i>.
+ If <i>type-sub</i> is not present or its substitution results in an
+ empty string then the custom type is assumed to have the same name
+ and be defined in the same namespace as the generated class would
+ have. If <i>base-sub</i> is present and its substitution results
+ in a non-empty string then the generated class is still generated
+ but with the result of substitution as its name. See also the
+ REGEX AND SHELL QUOTING section below.
+ </dd>
+
+ <!-- Suffixes. -->
+
+ <dt><code><b>--fwd-suffix</b> <i>suffix</i></code></dt>
+ <dd>Use the provided <code><i>suffix</i></code> instead of the default
+ <code><b>-fwd.hxx</b></code> to construct the name of the forward
+ declaration file.
+ </dd>
+
+ <dt><code><b>--fwd-regex</b> <i>regex</i></code></dt>
+ <dd>Use the provided expression to construct the name of the forward
+ declaration file. <code><i>regex</i></code> is a perl-like regular
+ expression in the form
+ <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>.
+ See also the REGEX AND SHELL QUOTING section below.
+ </dd>
+
+ <dt><code><b>--fwd-prologue</b> <i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the beginning of the forward
+ declaration file.
+ </dd>
+
+ <dt><code><b>--fwd-epilogue</b> <i>text</i></code></dt>
+ <dd>Insert <code><i>text</i></code> at the end of the forward
+ declaration file.
+ </dd>
+
+ <dt><code><b>--fwd-prologue-file</b> <i>file</i></code></dt>
+ <dd>Insert the content of the <code><i>file</i></code> at the beginning
+ of the forward declaration file.
+ </dd>
+
+ <dt><code><b>--fwd-epilogue-file</b> <i>file</i></code></dt>
+ <dd>Insert the content of the <code><i>file</i></code> at the end of the
+ forward declaration file.
+ </dd>
+
+ <!-- Parts. -->
+
+ <dt><code><b>--parts</b> <i>num</i></code></dt>
+ <dd>Split generated source code into <code><i>num</i></code> parts. This
+ is useful when translating large, monolithic schemas and a C++
+ compiler is not able to compile the resulting source code at once
+ (usually due to insufficient memory).
+ </dd>
+
+ <dt><code><b>--parts-suffix</b> <i>suffix</i></code></dt>
+ <dd>Use <code><i>suffix</i></code> instead of the default
+ '<code><b>-</b></code>' to separate the file name from the
+ part number.
+ </dd>
+
+ </dl>
+
+ <h2>CXX-PARSER COMMAND OPTIONS</h2>
+
+ <dl class="options">
+ <dt><code><b>--type-map</b> <i>mapfile</i></code></dt>
+ <dd>Read XML Schema to C++ type mapping information from
+ <code><i>mapfile</i></code>. Repeat this option to specify
+ several type maps. Type maps are considered in order of
+ appearance and the first match is used. By default all
+ user-defined types are mapped to <code><b>void</b></code>.
+ See the TYPE MAP section below for more information.</dd>
+
+ <dt><code><b>--xml-parser</b> <i>parser</i></code></dt>
+ <dd>Use <code><i>parser</i></code> as the underlying XML parser.
+ Valid values are <code><b>xerces</b></code> for Xerces-C++ (default)
+ and <code><b>expat</b></code> for Expat.</dd>
+
+ <dt><code><b>--generate-inline</b></code></dt>
+ <dd>Generate simple functions inline. This option triggers creation
+ of the inline file.</dd>
+
+ <dt><code><b>--generate-validation</b></code></dt>
+ <dd>Generate validation code ("perfect" parser) which ensures that
+ instance documents conform to the schema. Validation code is
+ generated by default when the selected underlying XML parser
+ is non-validating (<code><b>expat</b></code>).</dd>
+
+ <dt><code><b>--suppress-validation</b></code></dt>
+ <dd>Suppress the generation of validation code ("perfect" parser).
+ Validation is suppressed by default when the selected underlying
+ XML parser is validating (<code><b>xerces</b></code>).</dd>
+
+ <dt><code><b>--generate-polymorphic</b></code></dt>
+ <dd>Generate polymorphism-aware code. Specify this option if you use
+ substitution groups or <code><b>xsi:type</b></code>.</dd>
+
+ <dt><code><b>--generate-noop-impl</b></code></dt>
+ <dd>Generate a sample parser implementation that does nothing (no
+ operation). The sample implementation can then be filled with
+ the application-specific code. For an input file in the form
+ <code><b>name.xsd</b></code> this option triggers the generation
+ of the two additional C++ files in the form:
+ <code><b>name-pimpl.hxx</b></code> (parser implementation header
+ file) and <code><b>name-pimpl.cxx</b></code> (parser implementation
+ source file).</dd>
+
+ <dt><code><b>--generate-print-impl</b></code></dt>
+ <dd>Generate a sample parser implementation that prints the XML data
+ to STDOUT. For an input file in the form <code><b>name.xsd</b></code>
+ this option triggers the generation of the two additional C++ files
+ in the form: <code><b>name-pimpl.hxx</b></code> (parser implementation
+ header file) and <code><b>name-pimpl.cxx</b></code> (parser
+ implementation source file).</dd>
+
+ <dt><code><b>--generate-test-driver</b></code></dt>
+ <dd>Generate a test driver for the sample parser implementation. For an
+ input file in the form <code><b>name.xsd</b></code> this option
+ triggers the generation of an additional C++ file in the form
+ <code><b>name-driver.cxx</b></code>.</dd>
+
+ <dt><code><b>--force-overwrite</b></code></dt>
+ <dd>Force overwriting of the existing implementation and test driver
+ files. Use this option only if you do not mind loosing the changes
+ you have made in the sample implementation or test driver files.</dd>
+
+ <dt><code><b>--root-element-first</b></code></dt>
+ <dd>Indicate that the first global element is the document root. This
+ information is used to generate the test driver for the sample
+ implementation.</dd>
+
+ <dt><code><b>--root-element-last</b></code></dt>
+ <dd>Indicate that the last global element is the document root. This
+ information is used to generate the test driver for the sample
+ implementation.</dd>
+
+ <dt><code><b>--root-element <i>element</i></b></code></dt>
+ <dd>Indicate that <code><i>element</i></code> is the document root.
+ This information is used to generate the test driver for the
+ sample implementation.</dd>
+
+ <dt><code><b>--generate-xml-schema</b></code></dt>
+ <dd>Generate a C++ header file as if the schema being compiled defines
+ the XML Schema namespace. In particular, the resulting file will
+ have definitions for all parser skeletons and implementations
+ corresponding to the XML Schema built-in types. The schema file
+ provided to the compiler need not exist and is only used to derive
+ the name of the resulting header file. Use the
+ <code><b>--extern-xml-schema</b></code> option to include this file
+ in the generated files for other schemas.</dd>
+
+ <dt><code><b>--extern-xml-schema</b> <i>file</i></code></dt>
+ <dd>Include a header file derived from <i>file</i> instead of
+ generating the XML Schema namespace mapping inline. The provided
+ file need not exist and is only used to derive the name of the
+ included header file. Use the <code><b>--generate-xml-schema</b></code>
+ option to generate this header file.</dd>
+
+ <dt><code><b>--skel-type-suffix</b> <i>suffix</i></code></dt>
+ <dd>Use the provided <code><i>suffix</i></code> instead of the
+ default <code><b>_pskel</b></code> to construct the names
+ of generated parser skeletons.</dd>
+
+ <dt><code><b>--skel-file-suffix</b> <i>suffix</i></code></dt>
+ <dd>Use the provided <code><i>suffix</i></code> instead of the
+ default <code><b>-pskel</b></code> to construct the names of
+ generated parser skeleton files.</dd>
+
+ <dt><code><b>--impl-type-suffix</b> <i>suffix</i></code></dt>
+ <dd>Use the provided <code><i>suffix</i></code> instead of the
+ default <code><b>_pimpl</b></code> to construct the names of
+ parser implementations for the built-in XML Schema types
+ and sample parser implementations.</dd>
+
+ <dt><code><b>--impl-file-suffix</b> <i>suffix</i></code></dt>
+ <dd>Use the provided <code><i>suffix</i></code> instead of the
+ default <code><b>-pimpl</b></code> to construct the names of
+ generated sample parser implementation files.</dd>
+ </dl>
+
+ <h1>NAMING CONVENTION</h1>
+
+ <p>The compiler can be instructed to use a particular naming
+ convention in the generated code. A number of widely-used
+ conventions can be selected using the <code><b>--type-naming</b></code>
+ and <code><b>--function-naming</b></code> options. A custom
+ naming convention can be achieved using the
+ <code><b>--type-regex</b></code>,
+ <code><b>--accessor-regex</b></code>,
+ <code><b>--one-accessor-regex</b></code>,
+ <code><b>--opt-accessor-regex</b></code>,
+ <code><b>--seq-accessor-regex</b></code>,
+ <code><b>--modifier-regex</b></code>,
+ <code><b>--one-modifier-regex</b></code>,
+ <code><b>--opt-modifier-regex</b></code>,
+ <code><b>--seq-modifier-regex</b></code>,
+ <code><b>--parser-regex</b></code>,
+ <code><b>--serializer-regex</b></code>,
+ <code><b>--enumerator-regex</b></code>, and
+ <code><b>--element-type-regex</b></code> options.
+ </p>
+
+ <p>The <code><b>--type-naming</b></code> option specifies the
+ convention that should be used for naming C++ types. Possible
+ values for this option are <code><b>knr</b></code> (default),
+ <code><b>ucc</b></code>, and <code><b>java</b></code>. The
+ <code><b>knr</b></code> value (stands for K&amp;R) signifies
+ the standard, lower-case naming convention with the underscore
+ used as a word delimiter, for example: <code>foo</code>,
+ <code>foo_bar</code>. The <code><b>ucc</b></code> (stands
+ for upper-camel-case) and
+ <code><b>java</b></code> values a synonyms for the same
+ naming convention where the first letter of each word in the
+ name is capitalized, for example: <code>Foo</code>,
+ <code>FooBar</code>.</p>
+
+ <p>Similarly, the <code><b>--function-naming</b></code> option
+ specifies the convention that should be used for naming C++
+ functions. Possible values for this option are <code><b>knr</b></code>
+ (default), <code><b>lcc</b></code>, and <code><b>java</b></code>. The
+ <code><b>knr</b></code> value (stands for K&amp;R) signifies
+ the standard, lower-case naming convention with the underscore
+ used as a word delimiter, for example: <code>foo()</code>,
+ <code>foo_bar()</code>. The <code><b>lcc</b></code> value
+ (stands for lower-camel-case) signifies a naming convention
+ where the first letter of each word except the first is
+ capitalized, for example: <code>foo()</code>, <code>fooBar()</code>.
+ The <code><b>java</b></code> naming convention is similar to
+ the lower-camel-case one except that accessor functions are prefixed
+ with <code>get</code>, modifier functions are prefixed
+ with <code>set</code>, parsing functions are prefixed
+ with <code>parse</code>, and serialization functions are
+ prefixed with <code>serialize</code>, for example:
+ <code>getFoo()</code>, <code>setFooBar()</code>,
+ <code>parseRoot()</code>, <code>serializeRoot()</code>.</p>
+
+ <p>Note that the naming conventions specified with the
+ <code><b>--type-naming</b></code> and
+ <code><b>--function-naming</b></code> options perform only limited
+ transformations on the names that come from the schema in the
+ form of type, attribute, and element names. In other words, to
+ get consistent results, your schemas should follow a similar
+ naming convention as the one you would like to have in the
+ generated code. Alternatively, you can use the
+ <code><b>--*-regex</b></code> options (discussed below)
+ to perform further transformations on the names that come from
+ the schema.</p>
+
+ <p>The
+ <code><b>--type-regex</b></code>,
+ <code><b>--accessor-regex</b></code>,
+ <code><b>--one-accessor-regex</b></code>,
+ <code><b>--opt-accessor-regex</b></code>,
+ <code><b>--seq-accessor-regex</b></code>,
+ <code><b>--modifier-regex</b></code>,
+ <code><b>--one-modifier-regex</b></code>,
+ <code><b>--opt-modifier-regex</b></code>,
+ <code><b>--seq-modifier-regex</b></code>,
+ <code><b>--parser-regex</b></code>,
+ <code><b>--serializer-regex</b></code>,
+ <code><b>--enumerator-regex</b></code>, and
+ <code><b>--element-type-regex</b></code> options allow you to
+ specify extra regular expressions for each name category in
+ addition to the predefined set that is added depending on
+ the <code><b>--type-naming</b></code> and
+ <code><b>--function-naming</b></code> options. Expressions
+ that are provided with the <code><b>--*-regex</b></code>
+ options are evaluated prior to any predefined expressions.
+ This allows you to selectively override some or all of the
+ predefined transformations. When debugging your own expressions,
+ it is often useful to see which expressions match which names.
+ The <code><b>--name-regex-trace</b></code> option allows you
+ to trace the process of applying regular expressions to
+ names.</p>
+
+ <p>The value for the <code><b>--*-regex</b></code> options should be
+ a perl-like regular expression in the form
+ <code><b>/</b><i>pattern</i><b>/</b><i>replacement</i><b>/</b></code>.
+ Any character can be used as a delimiter instead of <code><b>/</b></code>.
+ Escaping of the delimiter character in <code><i>pattern</i></code> or
+ <code><i>replacement</i></code> is not supported.
+ All regular expressions for each category are pushed into a
+ category-specific stack with the last specified expression
+ considered first. The first match that succeeds is used. For the
+ <code><b>--one-accessor-regex</b></code> (accessors with cardinality one),
+ <code><b>--opt-accessor-regex</b></code> (accessors with cardinality optional), and
+ <code><b>--seq-accessor-regex</b></code> (accessors with cardinality sequence)
+ categories the <code><b>--accessor-regex</b></code> expressions are
+ used as a fallback. For the
+ <code><b>--one-modifier-regex</b></code>,
+ <code><b>--opt-modifier-regex</b></code>, and
+ <code><b>--seq-modifier-regex</b></code>
+ categories the <code><b>--modifier-regex</b></code> expressions are
+ used as a fallback. For the <code><b>--element-type-regex</b></code>
+ category the <code><b>--type-regex</b></code> expressions are
+ used as a fallback.</p>
+
+ <p>The type name expressions (<code><b>--type-regex</b></code>)
+ are evaluated on the name string that has the following
+ format:</p>
+
+ <p><code>[<i>namespace</i> ]<i>name</i>[,<i>name</i>][,<i>name</i>][,<i>name</i>]</code></p>
+
+ <p>The element type name expressions
+ (<code><b>--element-type-regex</b></code>), effective only when
+ the <code><b>--generate-element-type</b></code> option is specified,
+ are evaluated on the name string that has the following
+ format:</p>
+
+ <p><code><i>namespace</i> <i>name</i></code></p>
+
+ <p>In the type name format the <code><i>namespace</i></code> part
+ followed by a space is only present for global type names. For
+ global types and elements defined in schemas without a target
+ namespace, the <code><i>namespace</i></code> part is empty but
+ the space is still present. In the type name format after the
+ initial <code><i>name</i></code> component, up to three additional
+ <code><i>name</i></code> components can be present, separated
+ by commas. For example:</p>
+
+ <p><code><b>http://example.com/hello type</b></code></p>
+ <p><code><b>foo</b></code></p>
+ <p><code><b>foo,iterator</b></code></p>
+ <p><code><b>foo,const,iterator</b></code></p>
+
+ <p>The following set of predefined regular expressions is used to
+ transform type names when the upper-camel-case naming convention
+ is selected:</p>
+
+ <p><code><b>/(?:[^ ]* )?([^,]+)/\u$1/</b></code></p>
+ <p><code><b>/(?:[^ ]* )?([^,]+),([^,]+)/\u$1\u$2/</b></code></p>
+ <p><code><b>/(?:[^ ]* )?([^,]+),([^,]+),([^,]+)/\u$1\u$2\u$3/</b></code></p>
+ <p><code><b>/(?:[^ ]* )?([^,]+),([^,]+),([^,]+),([^,]+)/\u$1\u$2\u$3\u$4/</b></code></p>
+
+ <p>The accessor and modifier expressions
+ (<code><b>--*accessor-regex</b></code> and
+ <code><b>--*modifier-regex</b></code>) are evaluated on the name string
+ that has the following format:</p>
+
+ <p><code><i>name</i>[,<i>name</i>][,<i>name</i>]</code></p>
+
+ <p>After the initial <code><i>name</i></code> component, up to two
+ additional <code><i>name</i></code> components can be present,
+ separated by commas. For example:</p>
+
+ <p><code><b>foo</b></code></p>
+ <p><code><b>dom,document</b></code></p>
+ <p><code><b>foo,default,value</b></code></p>
+
+ <p>The following set of predefined regular expressions is used to
+ transform accessor names when the <code><b>java</b></code> naming
+ convention is selected:</p>
+
+ <p><code><b>/([^,]+)/get\u$1/</b></code></p>
+ <p><code><b>/([^,]+),([^,]+)/get\u$1\u$2/</b></code></p>
+ <p><code><b>/([^,]+),([^,]+),([^,]+)/get\u$1\u$2\u$3/</b></code></p>
+
+ <p>For the parser, serializer, and enumerator categories, the
+ corresponding regular expressions are evaluated on local names of
+ elements and on enumeration values, respectively. For example, the
+ following predefined regular expression is used to transform parsing
+ function names when the <code><b>java</b></code> naming convention
+ is selected:</p>
+
+ <p><code><b>/(.+)/parse\u$1/</b></code></p>
+
+ <p>See also the REGEX AND SHELL QUOTING section below.</p>
+
+ <h1>TYPE MAP</h1>
+
+ <p>Type map files are used in C++/Parser to define a mapping between
+ XML Schema and C++ types. The compiler uses this information
+ to determine the return types of <code><b>post_*</b></code>
+ functions in parser skeletons corresponding to XML Schema
+ types as well as argument types for callbacks corresponding
+ to elements and attributes of these types.</p>
+
+ <p>The compiler has a set of predefined mapping rules that map
+ built-in XML Schema types to suitable C++ types (discussed
+ below) and all other types to <code><b>void</b></code>.
+ By providing your own type maps you can override these predefined
+ rules. The format of the type map file is presented below:
+ </p>
+
+ <pre>
+namespace &lt;schema-namespace> [&lt;cxx-namespace>]
+{
+ (include &lt;file-name>;)*
+ ([type] &lt;schema-type> &lt;cxx-ret-type> [&lt;cxx-arg-type>];)*
+}
+ </pre>
+
+ <p>Both <code><i>&lt;schema-namespace></i></code> and
+ <code><i>&lt;schema-type></i></code> are regex patterns while
+ <code><i>&lt;cxx-namespace></i></code>,
+ <code><i>&lt;cxx-ret-type></i></code>, and
+ <code><i>&lt;cxx-arg-type></i></code> are regex pattern
+ substitutions. All names can be optionally enclosed in
+ <code><b>" "</b></code>, for example, to include white-spaces.</p>
+
+ <p><code><i>&lt;schema-namespace></i></code> determines XML
+ Schema namespace. Optional <code><i>&lt;cxx-namespace></i></code>
+ is prefixed to every C++ type name in this namespace declaration.
+ <code><i>&lt;cxx-ret-type></i></code> is a C++ type name that is
+ used as a return type for the <code><b>post_*</b></code> functions.
+ Optional <code><i>&lt;cxx-arg-type></i></code> is an argument
+ type for callback functions corresponding to elements and attributes
+ of this type. If
+ <code><i>&lt;cxx-arg-type></i></code> is not specified, it defaults
+ to <code><i>&lt;cxx-ret-type></i></code> if <code><i>&lt;cxx-ret-type></i></code>
+ ends with <code><b>*</b></code> or <code><b>&amp;</b></code> (that is,
+ it is a pointer or a reference) and
+ <code><b>const</b>&nbsp;<i>&lt;cxx-ret-type></i><b>&amp;</b></code>
+ otherwise.
+ <code><i>&lt;file-name></i></code> is a file name either in the
+ <code><b>" "</b></code> or <code><b>&lt; ></b></code> format
+ and is added with the <code><b>#include</b></code> directive to
+ the generated code.</p>
+
+ <p>The <code><b>#</b></code> character starts a comment that ends
+ with a new line or end of file. To specify a name that contains
+ <code><b>#</b></code> enclose it in <code><b>" "</b></code>.
+ For example:</p>
+
+ <pre>
+namespace http://www.example.com/xmlns/my my
+{
+ include "my.hxx";
+
+ # Pass apples by value.
+ #
+ apple apple;
+
+ # Pass oranges as pointers.
+ #
+ orange orange_t*;
+}
+ </pre>
+
+ <p>In the example above, for the
+ <code><b>http://www.example.com/xmlns/my#orange</b></code>
+ XML Schema type, the <code><b>my::orange_t*</b></code> C++ type will
+ be used as both return and argument types.</p>
+
+ <p>Several namespace declarations can be specified in a single
+ file. The namespace declaration can also be completely
+ omitted to map types in a schema without a namespace. For
+ instance:</p>
+
+ <pre>
+include "my.hxx";
+apple apple;
+
+namespace http://www.example.com/xmlns/my
+{
+ orange "const orange_t*";
+}
+ </pre>
+
+ <p>The compiler has a number of predefined mapping rules that can be
+ presented as the following map files. The string-based XML Schema
+ built-in types are mapped to either <code><b>std::string</b></code>
+ or <code><b>std::wstring</b></code> depending on the character type
+ selected with the <code><b>--char-type</b></code> option
+ (<code><b>char</b></code> by default).</p>
+
+ <pre>
+namespace http://www.w3.org/2001/XMLSchema
+{
+ boolean bool bool;
+
+ byte "signed char" "signed char";
+ unsignedByte "unsigned char" "unsigned char";
+
+ short short short;
+ unsignedShort "unsigned short" "unsigned short";
+
+ int int int;
+ unsignedInt "unsigned int" "unsigned int";
+
+ long "long long" "long long";
+ unsignedLong "unsigned long long" "unsigned long long";
+
+ integer "long long" "long long";
+
+ negativeInteger "long long" "long long";
+ nonPositiveInteger "long long" "long long";
+
+ positiveInteger "unsigned long long" "unsigned long long";
+ nonNegativeInteger "unsigned long long" "unsigned long long";
+
+ float float float;
+ double double double;
+ decimal double double;
+
+ string std::string;
+ normalizedString std::string;
+ token std::string;
+ Name std::string;
+ NMTOKEN std::string;
+ NCName std::string;
+ ID std::string;
+ IDREF std::string;
+ language std::string;
+ anyURI std::string;
+
+ NMTOKENS xml_schema::string_sequence;
+ IDREFS xml_schema::string_sequence;
+
+ QName xml_schema::qname;
+
+ base64Binary std::auto_ptr&lt;xml_schema::buffer>
+ std::auto_ptr&lt;xml_schema::buffer>;
+ hexBinary std::auto_ptr&lt;xml_schema::buffer>
+ std::auto_ptr&lt;xml_schema::buffer>;
+
+ date xml_schema::date;
+ dateTime xml_schema::date_time;
+ duration xml_schema::duration;
+ gDay xml_schema::gday;
+ gMonth xml_schema::gmonth;
+ gMonthDay xml_schema::gmonth_day;
+ gYear xml_schema::gyear;
+ gYearMonth xml_schema::gyear_month;
+ time xml_schema::time;
+}
+ </pre>
+
+ <p>The last predefined rule maps anything that wasn't mapped by
+ previous rules to <code><b>void</b></code>:</p>
+
+ <pre>
+namespace .*
+{
+ .* void void;
+}
+ </pre>
+
+
+ <p>When you provide your own type maps with the
+ <code><b>--type-map</b></code> option, they are evaluated first.
+ This allows you to selectively override predefined rules.</p>
+
+ <h1>REGEX AND SHELL QUOTING</h1>
+
+ <p>When entering a regular expression argument in the shell
+ command line it is often necessary to use quoting (enclosing
+ the argument in <code><b>"&nbsp;"</b></code> or
+ <code><b>'&nbsp;'</b></code>) in order to prevent the shell
+ from interpreting certain characters, for example, spaces as
+ argument separators and <code><b>$</b></code> as variable
+ expansions.</p>
+
+ <p>Unfortunately it is hard to achieve this in a manner that is
+ portable across POSIX shells, such as those found on
+ GNU/Linux and UNIX, and Windows shell. For example, if you
+ use <code><b>"&nbsp;"</b></code> for quoting you will get a
+ wrong result with POSIX shells if your expression contains
+ <code><b>$</b></code>. The standard way of dealing with this
+ on POSIX systems is to use <code><b>'&nbsp;'</b></code> instead.
+ Unfortunately, Windows shell does not remove <code><b>'&nbsp;'</b></code>
+ from arguments when they are passed to applications. As a result you
+ may have to use <code><b>'&nbsp;'</b></code> for POSIX and
+ <code><b>"&nbsp;"</b></code> for Windows (<code><b>$</b></code> is
+ not treated as a special character on Windows).</p>
+
+ <p>Alternatively, you can save regular expression options into
+ a file, one option per line, and use this file with the
+ <code><b>--options-file</b></code> option. With this approach
+ you don't need to worry about shell quoting.</p>
+
+ <h1>DIAGNOSTICS</h1>
+
+ <p>If the input file is not a valid W3C XML Schema definition,
+ <code><b>xsd</b></code> will issue diagnostic messages to STDERR
+ and exit with non-zero exit code.</p>
+
+ <h1>BUGS</h1>
+
+ <p>Send bug reports to the
+ <a href="mailto:xsd-users@codesynthesis.com">xsd-users@codesynthesis.com</a> mailing list.</p>
+
+ </div>
+ <div id="footer">
+ &copy;2005-2009 <a href="http://codesynthesis.com">CODE SYNTHESIS TOOLS CC</a>
+
+ <div id="terms">
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the
+ <a href="http://codesynthesis.com/licenses/fdl-1.2.txt">GNU Free
+ Documentation License, version 1.2</a>; with no Invariant Sections,
+ no Front-Cover Texts and no Back-Cover Texts.
+ </div>
+ </div>
+</div>
+</body>
+</html>
diff --git a/examples/cxx/parser/README b/examples/cxx/parser/README
new file mode 100644
index 0000000..01906c7
--- /dev/null
+++ b/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/examples/cxx/parser/generated/README b/examples/cxx/parser/generated/README
new file mode 100644
index 0000000..ca56974
--- /dev/null
+++ b/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/examples/cxx/parser/generated/library.xml b/examples/cxx/parser/generated/library.xml
new file mode 100644
index 0000000..2d9069c
--- /dev/null
+++ b/examples/cxx/parser/generated/library.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/library/library.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/generated/library.xsd b/examples/cxx/parser/generated/library.xsd
new file mode 100644
index 0000000..57654c7
--- /dev/null
+++ b/examples/cxx/parser/generated/library.xsd
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/library/library.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/generated/makefile b/examples/cxx/parser/generated/makefile
new file mode 100644
index 0000000..04d5831
--- /dev/null
+++ b/examples/cxx/parser/generated/makefile
@@ -0,0 +1,72 @@
+# file : examples/cxx/parser/generated/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := library.xsd
+
+obj := $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.o) $(xsd:.xsd=-pimpl.o) $(xsd:.xsd=-driver.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/$(xsd:.xsd=-driver)
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+gen := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx) \
+ $(out_base)/$(xsd:.xsd=-pimpl.hxx) \
+ $(out_base)/$(xsd:.xsd=-pimpl.cxx) \
+ $(out_base)/$(xsd:.xsd=-driver.cxx)
+
+$(gen): xsd := $(out_root)/xsd/xsd
+$(gen): xsd_options := --generate-print-impl --generate-test-driver \
+--force-overwrite
+$(gen): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pimpl.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+
+xsd_parser_impl_suffix := -pimpl
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/parser/hello/README b/examples/cxx/parser/hello/README
new file mode 100644
index 0000000..97449de
--- /dev/null
+++ b/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/examples/cxx/parser/hello/driver.cxx b/examples/cxx/parser/hello/driver.cxx
new file mode 100644
index 0000000..9aee316
--- /dev/null
+++ b/examples/cxx/parser/hello/driver.cxx
@@ -0,0 +1,68 @@
+// file : examples/cxx/parser/hello/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/hello/hello.xml b/examples/cxx/parser/hello/hello.xml
new file mode 100644
index 0000000..2e5aaa3
--- /dev/null
+++ b/examples/cxx/parser/hello/hello.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/hello/hello.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/hello/hello.xsd b/examples/cxx/parser/hello/hello.xsd
new file mode 100644
index 0000000..f0941b7
--- /dev/null
+++ b/examples/cxx/parser/hello/hello.xsd
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/hello/hello.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="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/examples/cxx/parser/hello/makefile b/examples/cxx/parser/hello/makefile
new file mode 100644
index 0000000..cfcee47
--- /dev/null
+++ b/examples/cxx/parser/hello/makefile
@@ -0,0 +1,67 @@
+# file : examples/cxx/parser/hello/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := hello.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/parser/library/README b/examples/cxx/parser/library/README
new file mode 100644
index 0000000..3f515f6
--- /dev/null
+++ b/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/examples/cxx/parser/library/driver.cxx b/examples/cxx/parser/library/driver.cxx
new file mode 100644
index 0000000..ea5f1d9
--- /dev/null
+++ b/examples/cxx/parser/library/driver.cxx
@@ -0,0 +1,110 @@
+// file : examples/cxx/parser/library/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/library/library-pimpl.cxx b/examples/cxx/parser/library/library-pimpl.cxx
new file mode 100644
index 0000000..8b6c357
--- /dev/null
+++ b/examples/cxx/parser/library/library-pimpl.cxx
@@ -0,0 +1,184 @@
+// file : examples/cxx/parser/library/library-pimpl.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/library/library-pimpl.hxx b/examples/cxx/parser/library/library-pimpl.hxx
new file mode 100644
index 0000000..180070c
--- /dev/null
+++ b/examples/cxx/parser/library/library-pimpl.hxx
@@ -0,0 +1,136 @@
+// file : examples/cxx/parser/library/library-pimpl.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/library/library.hxx b/examples/cxx/parser/library/library.hxx
new file mode 100644
index 0000000..fb6cc1d
--- /dev/null
+++ b/examples/cxx/parser/library/library.hxx
@@ -0,0 +1,242 @@
+// file : examples/cxx/parser/library/library.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/library/library.map b/examples/cxx/parser/library/library.map
new file mode 100644
index 0000000..90f4938
--- /dev/null
+++ b/examples/cxx/parser/library/library.map
@@ -0,0 +1,16 @@
+# file : examples/cxx/parser/library/library.map
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# 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/examples/cxx/parser/library/library.xml b/examples/cxx/parser/library/library.xml
new file mode 100644
index 0000000..2d9069c
--- /dev/null
+++ b/examples/cxx/parser/library/library.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/library/library.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/library/library.xsd b/examples/cxx/parser/library/library.xsd
new file mode 100644
index 0000000..57654c7
--- /dev/null
+++ b/examples/cxx/parser/library/library.xsd
@@ -0,0 +1,79 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/library/library.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/library/makefile b/examples/cxx/parser/library/makefile
new file mode 100644
index 0000000..c7f06c4
--- /dev/null
+++ b/examples/cxx/parser/library/makefile
@@ -0,0 +1,68 @@
+# file : examples/cxx/parser/library/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := library.xsd
+cxx := driver.cxx library-pimpl.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-inline --type-map $(src_base)/library.map
+$(skel): $(out_root)/xsd/xsd $(src_base)/library.map
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/parser/makefile b/examples/cxx/parser/makefile
new file mode 100644
index 0000000..25d9c54
--- /dev/null
+++ b/examples/cxx/parser/makefile
@@ -0,0 +1,19 @@
+# file : examples/cxx/parser/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make
+
+examples := generated hello library mixin mixed multiroot performance \
+polymorphism polyroot wildcard
+
+default := $(out_base)/
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(examples)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(examples)))
+
+$(foreach e,$(examples),$(call import,$(src_base)/$e/makefile))
diff --git a/examples/cxx/parser/mixed/README b/examples/cxx/parser/mixed/README
new file mode 100644
index 0000000..23ace6f
--- /dev/null
+++ b/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/examples/cxx/parser/mixed/anchor.hxx b/examples/cxx/parser/mixed/anchor.hxx
new file mode 100644
index 0000000..bc1b54d
--- /dev/null
+++ b/examples/cxx/parser/mixed/anchor.hxx
@@ -0,0 +1,34 @@
+// file : examples/cxx/parser/mixed/anchor.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/mixed/driver.cxx b/examples/cxx/parser/mixed/driver.cxx
new file mode 100644
index 0000000..45067f0
--- /dev/null
+++ b/examples/cxx/parser/mixed/driver.cxx
@@ -0,0 +1,101 @@
+// file : examples/cxx/parser/mixed/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/mixed/makefile b/examples/cxx/parser/mixed/makefile
new file mode 100644
index 0000000..642e203
--- /dev/null
+++ b/examples/cxx/parser/mixed/makefile
@@ -0,0 +1,68 @@
+# file : examples/cxx/parser/mixed/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := text.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --type-map $(src_base)/text.map
+$(skel): $(out_root)/xsd/xsd $(src_base)/text.map
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/parser/mixed/text.map b/examples/cxx/parser/mixed/text.map
new file mode 100644
index 0000000..e44caf3
--- /dev/null
+++ b/examples/cxx/parser/mixed/text.map
@@ -0,0 +1,7 @@
+# file : examples/cxx/parser/mixed/text.map
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : not copyrighted - public domain
+
+include "anchor.hxx";
+
+anchor ::anchor;
diff --git a/examples/cxx/parser/mixed/text.xml b/examples/cxx/parser/mixed/text.xml
new file mode 100644
index 0000000..97d4d21
--- /dev/null
+++ b/examples/cxx/parser/mixed/text.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/text/text.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/mixed/text.xsd b/examples/cxx/parser/mixed/text.xsd
new file mode 100644
index 0000000..4929964
--- /dev/null
+++ b/examples/cxx/parser/mixed/text.xsd
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/mixed/text.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="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/examples/cxx/parser/mixin/README b/examples/cxx/parser/mixin/README
new file mode 100644
index 0000000..343e379
--- /dev/null
+++ b/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/examples/cxx/parser/mixin/driver.cxx b/examples/cxx/parser/mixin/driver.cxx
new file mode 100644
index 0000000..41e5a45
--- /dev/null
+++ b/examples/cxx/parser/mixin/driver.cxx
@@ -0,0 +1,104 @@
+// file : examples/cxx/parser/mixin/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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:
+ auto_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]);
+ auto_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/examples/cxx/parser/mixin/instance.xml b/examples/cxx/parser/mixin/instance.xml
new file mode 100644
index 0000000..265271b
--- /dev/null
+++ b/examples/cxx/parser/mixin/instance.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/mixin/instance.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/mixin/makefile b/examples/cxx/parser/mixin/makefile
new file mode 100644
index 0000000..91030be
--- /dev/null
+++ b/examples/cxx/parser/mixin/makefile
@@ -0,0 +1,68 @@
+# file : examples/cxx/parser/mixin/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := schema.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --type-map $(src_base)/schema.map
+$(skel): $(out_root)/xsd/xsd $(src_base)/schema.map
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/parser/mixin/schema.map b/examples/cxx/parser/mixin/schema.map
new file mode 100644
index 0000000..22edb1e
--- /dev/null
+++ b/examples/cxx/parser/mixin/schema.map
@@ -0,0 +1,8 @@
+# file : examples/cxx/parser/mixin/schema.map
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : not copyrighted - public domain
+
+include "types.hxx";
+
+base ::base*;
+derived ::derived*;
diff --git a/examples/cxx/parser/mixin/schema.xsd b/examples/cxx/parser/mixin/schema.xsd
new file mode 100644
index 0000000..59d8d3b
--- /dev/null
+++ b/examples/cxx/parser/mixin/schema.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/mixin/schema.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="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/examples/cxx/parser/mixin/types.hxx b/examples/cxx/parser/mixin/types.hxx
new file mode 100644
index 0000000..708dfc3
--- /dev/null
+++ b/examples/cxx/parser/mixin/types.hxx
@@ -0,0 +1,44 @@
+// file : examples/cxx/parser/mixin/types.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/multiroot/README b/examples/cxx/parser/multiroot/README
new file mode 100644
index 0000000..041dfec
--- /dev/null
+++ b/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/examples/cxx/parser/multiroot/balance.xml b/examples/cxx/parser/multiroot/balance.xml
new file mode 100644
index 0000000..df0a6e9
--- /dev/null
+++ b/examples/cxx/parser/multiroot/balance.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/multiroot/balance.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/multiroot/deposit.xml b/examples/cxx/parser/multiroot/deposit.xml
new file mode 100644
index 0000000..3043c52
--- /dev/null
+++ b/examples/cxx/parser/multiroot/deposit.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/multiroot/deposit.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/multiroot/driver.cxx b/examples/cxx/parser/multiroot/driver.cxx
new file mode 100644
index 0000000..9e5d874
--- /dev/null
+++ b/examples/cxx/parser/multiroot/driver.cxx
@@ -0,0 +1,162 @@
+// file : examples/cxx/parser/multiroot/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_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::auto_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::auto_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/examples/cxx/parser/multiroot/makefile b/examples/cxx/parser/multiroot/makefile
new file mode 100644
index 0000000..cfe4fba
--- /dev/null
+++ b/examples/cxx/parser/multiroot/makefile
@@ -0,0 +1,68 @@
+# file : examples/cxx/parser/multiroot/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := protocol.xsd
+cxx := driver.cxx protocol-pimpl.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --type-map $(src_base)/protocol.map
+$(skel): $(out_root)/xsd/xsd $(src_base)/protocol.map
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/parser/multiroot/protocol-pimpl.cxx b/examples/cxx/parser/multiroot/protocol-pimpl.cxx
new file mode 100644
index 0000000..09a04b3
--- /dev/null
+++ b/examples/cxx/parser/multiroot/protocol-pimpl.cxx
@@ -0,0 +1,47 @@
+// file : examples/cxx/parser/multiroot/protocol-pimpl.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/multiroot/protocol-pimpl.hxx b/examples/cxx/parser/multiroot/protocol-pimpl.hxx
new file mode 100644
index 0000000..0531790
--- /dev/null
+++ b/examples/cxx/parser/multiroot/protocol-pimpl.hxx
@@ -0,0 +1,49 @@
+// file : examples/cxx/parser/multiroot/protocol-pimpl.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/multiroot/protocol.hxx b/examples/cxx/parser/multiroot/protocol.hxx
new file mode 100644
index 0000000..f076140
--- /dev/null
+++ b/examples/cxx/parser/multiroot/protocol.hxx
@@ -0,0 +1,62 @@
+// file : examples/cxx/parser/multiroot/protocol.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/multiroot/protocol.map b/examples/cxx/parser/multiroot/protocol.map
new file mode 100644
index 0000000..7389fa9
--- /dev/null
+++ b/examples/cxx/parser/multiroot/protocol.map
@@ -0,0 +1,12 @@
+# file : examples/cxx/parser/multiroot/protocol.map
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : not copyrighted - public domain
+
+namespace http://www.codesynthesis.com/protocol ::protocol
+{
+ include "protocol.hxx";
+
+ request request*;
+ balance balance*;
+ withdraw withdraw*;
+}
diff --git a/examples/cxx/parser/multiroot/protocol.xsd b/examples/cxx/parser/multiroot/protocol.xsd
new file mode 100644
index 0000000..4b29926
--- /dev/null
+++ b/examples/cxx/parser/multiroot/protocol.xsd
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/multiroot/protocol.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/multiroot/withdraw.xml b/examples/cxx/parser/multiroot/withdraw.xml
new file mode 100644
index 0000000..7a80aa7
--- /dev/null
+++ b/examples/cxx/parser/multiroot/withdraw.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/multiroot/withdraw.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/performance/README b/examples/cxx/parser/performance/README
new file mode 100644
index 0000000..d8d27a7
--- /dev/null
+++ b/examples/cxx/parser/performance/README
@@ -0,0 +1,44 @@
+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-5k.xml
+test-50k.xml
+test-500k.xml
+ Test XML documents of various sizes.
+
+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-500k.xml
diff --git a/examples/cxx/parser/performance/driver.cxx b/examples/cxx/parser/performance/driver.cxx
new file mode 100644
index 0000000..9e1d48d
--- /dev/null
+++ b/examples/cxx/parser/performance/driver.cxx
@@ -0,0 +1,308 @@
+// file : examples/cxx/parser/performance/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <string>
+#include <memory> // std::auto_ptr
+#include <cstddef> // std::size_t
+#include <fstream>
+#include <sstream>
+#include <iostream>
+
+#include "time.hxx"
+#include "test-pskel.hxx"
+
+#ifdef _XERCES_VERSION
+# 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>
+#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)
+ {
+ 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;
+ }
+
+ 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);
+
+ std::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;
+
+ XMLPlatformUtils::Initialize ();
+
+ {
+ MemBufInputSource is (
+ reinterpret_cast<XMLByte*> (buf), size, file, false);
+ is.setCopyBufToStream (false);
+
+ auto_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);
+
+ parser->loadGrammar ("test.xsd", Grammar::SchemaGrammarType, true);
+ parser->setFeature (XMLUni::fgXercesUseCachedGrammarInParse, true);
+ }
+ 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
+
+ // 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/examples/cxx/parser/performance/gen.cxx b/examples/cxx/parser/performance/gen.cxx
new file mode 100644
index 0000000..b6392c0
--- /dev/null
+++ b/examples/cxx/parser/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/examples/cxx/parser/performance/makefile b/examples/cxx/parser/performance/makefile
new file mode 100644
index 0000000..0a67a71
--- /dev/null
+++ b/examples/cxx/parser/performance/makefile
@@ -0,0 +1,68 @@
+# file : examples/cxx/parser/performance/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx time.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-inline
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/parser/performance/test-500k.xml b/examples/cxx/parser/performance/test-500k.xml
new file mode 100644
index 0000000..e895584
--- /dev/null
+++ b/examples/cxx/parser/performance/test-500k.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><record orange="317"><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="318" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="319"><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="320" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="321"><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="322" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="323"><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="324" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="325"><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="326" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="327"><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="328" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="329"><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="330" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="331"><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="332" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="333"><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="334" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="335"><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="336" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="337"><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="338" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="339"><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="340" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="341"><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="342" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="343"><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="344" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="345"><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="346" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="347"><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="348" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="349"><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="350" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="351"><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="352" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="353"><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="354" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="355"><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="356" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="357"><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="358" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="359"><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="360" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="361"><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="362" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="363"><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="364" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="365"><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="366" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="367"><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="368" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="369"><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="370" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="371"><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="372" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="373"><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="374" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="375"><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="376" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="377"><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="378" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="379"><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="380" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="381"><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="382" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="383"><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="384" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="385"><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="386" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="387"><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="388" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="389"><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="390" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="391"><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="392" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="393"><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="394" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="395"><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="396" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="397"><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="398" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="399"><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="400" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="401"><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="402" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="403"><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="404" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="405"><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="406" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="407"><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="408" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="409"><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="410" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="411"><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="412" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="413"><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="414" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="415"><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="416" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="417"><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="418" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="419"><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="420" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="421"><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="422" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="423"><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="424" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="425"><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="426" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="427"><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="428" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="429"><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="430" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="431"><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="432" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="433"><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="434" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="435"><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="436" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="437"><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="438" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="439"><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="440" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="441"><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="442" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="443"><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="444" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="445"><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="446" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="447"><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="448" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="449"><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="450" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="451"><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="452" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="453"><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="454" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="455"><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="456" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="457"><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="458" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="459"><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="460" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="461"><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="462" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="463"><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="464" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="465"><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="466" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="467"><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="468" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="469"><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="470" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="471"><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="472" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="473"><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="474" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="475"><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="476" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="477"><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="478" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="479"><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="480" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="481"><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="482" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="483"><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="484" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="485"><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="486" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="487"><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="488" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="489"><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="490" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="491"><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="492" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="493"><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="494" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="495"><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="496" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="497"><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="498" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="499"><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="500" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="501"><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="502" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="503"><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="504" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="505"><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="506" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="507"><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="508" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="509"><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="510" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="511"><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="512" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="513"><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="514" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="515"><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="516" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="517"><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="518" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="519"><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="520" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="521"><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="522" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="523"><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="524" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="525"><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="526" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="527"><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="528" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="529"><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="530" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="531"><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="532" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="533"><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="534" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="535"><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="536" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="537"><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="538" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="539"><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="540" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="541"><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="542" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="543"><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="544" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="545"><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="546" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="547"><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="548" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="549"><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="550" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="551"><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="552" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="553"><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="554" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="555"><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="556" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="557"><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="558" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="559"><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="560" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="561"><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="562" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="563"><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="564" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="565"><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="566" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="567"><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="568" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="569"><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="570" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="571"><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="572" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="573"><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="574" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="575"><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="576" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="577"><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="578" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="579"><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="580" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="581"><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="582" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="583"><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="584" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="585"><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="586" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="587"><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="588" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="589"><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="590" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="591"><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="592" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="593"><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="594" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="595"><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="596" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="597"><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="598" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="599"><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="600" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="601"><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="602" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="603"><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="604" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="605"><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="606" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="607"><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="608" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="609"><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="610" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="611"><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="612" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="613"><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="614" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="615"><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="616" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="617"><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="618" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="619"><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="620" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="621"><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="622" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="623"><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="624" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="625"><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="626" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="627"><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="628" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="629"><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="630" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="631"><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="632" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="633"><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="634" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="635"><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="636" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="637"><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="638" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="639"><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="640" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="641"><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="642" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="643"><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="644" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="645"><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="646" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="647"><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="648" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="649"><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="650" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="651"><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="652" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="653"><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="654" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="655"><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="656" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="657"><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="658" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="659"><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="660" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="661"><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="662" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="663"><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="664" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="665"><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="666" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="667"><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="668" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="669"><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="670" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="671"><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="672" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="673"><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="674" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="675"><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="676" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="677"><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="678" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="679"><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="680" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="681"><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="682" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="683"><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="684" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="685"><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="686" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="687"><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="688" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="689"><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="690" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="691"><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="692" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="693"><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="694" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="695"><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="696" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="697"><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="698" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="699"><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="700" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="701"><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="702" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="703"><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="704" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="705"><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="706" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="707"><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="708" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="709"><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="710" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="711"><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="712" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="713"><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="714" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="715"><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="716" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="717"><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="718" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="719"><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="720" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="721"><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="722" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="723"><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="724" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="725"><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="726" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="727"><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="728" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="729"><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="730" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="731"><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="732" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="733"><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="734" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="735"><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="736" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="737"><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="738" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="739"><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="740" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="741"><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="742" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="743"><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="744" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="745"><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="746" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="747"><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="748" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="749"><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="750" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="751"><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="752" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="753"><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="754" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="755"><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="756" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="757"><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="758" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="759"><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="760" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="761"><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="762" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="763"><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="764" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="765"><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="766" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="767"><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="768" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="769"><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="770" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="771"><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="772" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="773"><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="774" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="775"><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="776" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="777"><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="778" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="779"><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="780" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="781"><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="782" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="783"><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="784" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="785"><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="786" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="787"><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="788" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="789"><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="790" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="791"><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="792" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="793"><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="794" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="795"><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="796" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="797"><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="798" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="799"><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="800" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="801"><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="802" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="803"><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="804" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="805"><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="806" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="807"><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="808" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="809"><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="810" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="811"><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="812" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="813"><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="814" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="815"><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="816" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="817"><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="818" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="819"><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="820" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="821"><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="822" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="823"><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="824" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="825"><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="826" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="827"><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="828" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="829"><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="830" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="831"><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="832" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="833"><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="834" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="835"><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="836" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="837"><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="838" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="839"><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="840" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="841"><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="842" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="843"><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="844" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="845"><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="846" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="847"><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="848" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="849"><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="850" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="851"><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="852" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="853"><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="854" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="855"><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="856" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="857"><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="858" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="859"><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="860" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="861"><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="862" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="863"><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="864" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="865"><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="866" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="867"><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="868" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="869"><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="870" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="871"><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="872" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="873"><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="874" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="875"><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="876" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="877"><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="878" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="879"><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="880" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="881"><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="882" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="883"><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="884" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="885"><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="886" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="887"><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="888" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="889"><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="890" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="891"><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="892" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="893"><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="894" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="895"><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="896" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="897"><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="898" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="899"><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="900" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="901"><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="902" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="903"><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="904" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="905"><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="906" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="907"><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="908" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="909"><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="910" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="911"><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="912" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="913"><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="914" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="915"><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="916" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="917"><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="918" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="919"><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="920" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="921"><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="922" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="923"><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="924" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="925"><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="926" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="927"><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="928" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="929"><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="930" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="931"><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="932" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="933"><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="934" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="935"><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="936" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="937"><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="938" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="939"><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="940" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="941"><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="942" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="943"><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="944" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="945"><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="946" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="947"><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="948" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="949"><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="950" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="951"><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="952" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="953"><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="954" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="955"><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="956" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="957"><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="958" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="959"><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="960" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="961"><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="962" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="963"><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="964" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="965"><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="966" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="967"><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="968" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="969"><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="970" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="971"><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="972" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="973"><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="974" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="975"><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="976" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="977"><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="978" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="979"><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="980" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="981"><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="982" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="983"><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="984" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="985"><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="986" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="987"><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="988" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="989"><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="990" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="991"><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="992" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="993"><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="994" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="995"><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="996" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="997"><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="998" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="999"><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="1000" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1001"><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="1002" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1003"><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="1004" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1005"><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="1006" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1007"><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="1008" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1009"><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="1010" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1011"><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="1012" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1013"><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="1014" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1015"><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="1016" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1017"><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="1018" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1019"><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="1020" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1021"><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="1022" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1023"><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="1024" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1025"><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="1026" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1027"><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="1028" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1029"><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="1030" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1031"><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="1032" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1033"><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="1034" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1035"><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="1036" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1037"><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="1038" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1039"><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="1040" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1041"><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="1042" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1043"><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="1044" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1045"><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="1046" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1047"><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="1048" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1049"><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="1050" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1051"><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="1052" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1053"><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="1054" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1055"><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="1056" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1057"><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="1058" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1059"><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="1060" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1061"><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="1062" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1063"><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="1064" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1065"><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="1066" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1067"><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="1068" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1069"><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="1070" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1071"><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="1072" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1073"><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="1074" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1075"><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="1076" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1077"><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="1078" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1079"><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="1080" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1081"><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="1082" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1083"><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="1084" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1085"><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="1086" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1087"><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="1088" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1089"><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="1090" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1091"><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="1092" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1093"><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="1094" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1095"><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="1096" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1097"><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="1098" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1099"><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="1100" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1101"><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="1102" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1103"><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="1104" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1105"><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="1106" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1107"><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="1108" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1109"><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="1110" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1111"><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="1112" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1113"><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="1114" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1115"><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="1116" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1117"><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="1118" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1119"><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="1120" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1121"><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="1122" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1123"><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="1124" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1125"><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="1126" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1127"><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="1128" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1129"><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="1130" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1131"><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="1132" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1133"><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="1134" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1135"><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="1136" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1137"><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="1138" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1139"><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="1140" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1141"><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="1142" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1143"><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="1144" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1145"><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="1146" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1147"><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="1148" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1149"><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="1150" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1151"><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="1152" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1153"><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="1154" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1155"><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="1156" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1157"><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="1158" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1159"><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="1160" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1161"><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="1162" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1163"><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="1164" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1165"><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="1166" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1167"><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="1168" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1169"><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="1170" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1171"><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="1172" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1173"><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="1174" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1175"><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="1176" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1177"><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="1178" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1179"><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="1180" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1181"><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="1182" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1183"><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="1184" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1185"><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="1186" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1187"><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="1188" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1189"><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="1190" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1191"><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="1192" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1193"><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="1194" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1195"><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="1196" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1197"><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="1198" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1199"><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="1200" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1201"><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="1202" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1203"><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="1204" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1205"><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="1206" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1207"><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="1208" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1209"><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="1210" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1211"><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="1212" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1213"><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="1214" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1215"><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="1216" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1217"><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="1218" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1219"><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="1220" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1221"><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="1222" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1223"><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="1224" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1225"><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="1226" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1227"><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="1228" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1229"><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="1230" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1231"><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="1232" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1233"><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="1234" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1235"><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="1236" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1237"><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="1238" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1239"><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="1240" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1241"><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="1242" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1243"><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="1244" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1245"><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="1246" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1247"><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="1248" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1249"><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="1250" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1251"><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="1252" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1253"><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="1254" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1255"><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="1256" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1257"><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="1258" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1259"><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="1260" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1261"><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="1262" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1263"><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="1264" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1265"><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="1266" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1267"><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="1268" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1269"><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="1270" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1271"><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="1272" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1273"><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="1274" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1275"><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="1276" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1277"><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="1278" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1279"><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="1280" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1281"><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="1282" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1283"><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="1284" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1285"><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="1286" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1287"><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="1288" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1289"><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="1290" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1291"><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="1292" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1293"><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="1294" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1295"><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="1296" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1297"><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="1298" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1299"><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="1300" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1301"><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="1302" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1303"><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="1304" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1305"><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="1306" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1307"><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="1308" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1309"><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="1310" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1311"><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="1312" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1313"><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="1314" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1315"><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="1316" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1317"><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="1318" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1319"><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="1320" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1321"><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="1322" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1323"><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="1324" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1325"><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="1326" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1327"><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="1328" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1329"><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="1330" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1331"><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="1332" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1333"><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="1334" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1335"><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="1336" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1337"><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="1338" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1339"><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="1340" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1341"><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="1342" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1343"><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="1344" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1345"><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="1346" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1347"><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="1348" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1349"><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="1350" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1351"><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="1352" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1353"><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="1354" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1355"><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="1356" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1357"><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="1358" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1359"><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="1360" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1361"><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="1362" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1363"><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="1364" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1365"><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="1366" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1367"><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="1368" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1369"><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="1370" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1371"><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="1372" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1373"><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="1374" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1375"><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="1376" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1377"><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="1378" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1379"><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="1380" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1381"><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="1382" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1383"><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="1384" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1385"><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="1386" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1387"><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="1388" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1389"><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="1390" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1391"><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="1392" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1393"><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="1394" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1395"><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="1396" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1397"><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="1398" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1399"><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="1400" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1401"><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="1402" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1403"><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="1404" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1405"><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="1406" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1407"><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="1408" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1409"><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="1410" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1411"><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="1412" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1413"><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="1414" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1415"><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="1416" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1417"><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="1418" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1419"><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="1420" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1421"><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="1422" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1423"><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="1424" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1425"><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="1426" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1427"><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="1428" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1429"><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="1430" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1431"><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="1432" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1433"><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="1434" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1435"><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="1436" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1437"><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="1438" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1439"><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="1440" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1441"><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="1442" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1443"><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="1444" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1445"><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="1446" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1447"><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="1448" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1449"><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="1450" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1451"><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="1452" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1453"><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="1454" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1455"><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="1456" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1457"><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="1458" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1459"><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="1460" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1461"><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="1462" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1463"><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="1464" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1465"><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="1466" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1467"><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="1468" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1469"><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="1470" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1471"><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="1472" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1473"><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="1474" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1475"><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="1476" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1477"><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="1478" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1479"><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="1480" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1481"><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="1482" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1483"><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="1484" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1485"><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="1486" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1487"><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="1488" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1489"><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="1490" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1491"><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="1492" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1493"><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="1494" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1495"><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="1496" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1497"><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="1498" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1499"><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="1500" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1501"><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="1502" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1503"><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="1504" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1505"><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="1506" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1507"><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="1508" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1509"><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="1510" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1511"><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="1512" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1513"><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="1514" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1515"><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="1516" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1517"><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="1518" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1519"><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="1520" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1521"><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="1522" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1523"><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="1524" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1525"><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="1526" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1527"><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="1528" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1529"><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="1530" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1531"><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="1532" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1533"><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="1534" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1535"><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="1536" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1537"><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="1538" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1539"><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="1540" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1541"><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="1542" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1543"><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="1544" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1545"><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="1546" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1547"><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="1548" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1549"><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="1550" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1551"><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="1552" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1553"><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="1554" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1555"><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="1556" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1557"><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="1558" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1559"><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="1560" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1561"><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="1562" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1563"><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="1564" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1565"><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="1566" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1567"><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="1568" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1569"><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="1570" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1571"><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="1572" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1573"><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="1574" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1575"><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="1576" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1577"><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="1578" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1579"><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="1580" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1581"><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="1582" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1583"><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="1584" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1585"><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="1586" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1587"><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="1588" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1589"><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="1590" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1591"><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="1592" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1593"><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="1594" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1595"><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="1596" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1597"><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="1598" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1599"><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="1600" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1601"><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="1602" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1603"><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="1604" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1605"><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="1606" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1607"><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="1608" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1609"><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="1610" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1611"><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="1612" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1613"><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="1614" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1615"><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="1616" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1617"><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="1618" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1619"><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="1620" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1621"><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="1622" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1623"><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="1624" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1625"><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="1626" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1627"><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="1628" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1629"><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="1630" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1631"><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="1632" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1633"><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="1634" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1635"><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="1636" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1637"><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="1638" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1639"><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="1640" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1641"><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="1642" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1643"><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="1644" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1645"><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="1646" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1647"><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="1648" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1649"><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="1650" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1651"><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="1652" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1653"><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="1654" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1655"><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="1656" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1657"><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="1658" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1659"><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="1660" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1661"><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="1662" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1663"><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="1664" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1665"><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="1666" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1667"><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="1668" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1669"><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="1670" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1671"><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="1672" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1673"><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="1674" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1675"><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="1676" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1677"><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="1678" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1679"><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="1680" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1681"><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="1682" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1683"><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="1684" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1685"><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="1686" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1687"><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="1688" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1689"><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="1690" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1691"><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="1692" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1693"><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="1694" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1695"><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="1696" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1697"><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="1698" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1699"><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="1700" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1701"><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="1702" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1703"><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="1704" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1705"><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="1706" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1707"><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="1708" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1709"><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="1710" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1711"><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="1712" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1713"><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="1714" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1715"><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="1716" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1717"><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="1718" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1719"><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="1720" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1721"><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="1722" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1723"><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="1724" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1725"><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="1726" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1727"><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="1728" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1729"><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="1730" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1731"><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="1732" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1733"><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="1734" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1735"><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="1736" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1737"><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="1738" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1739"><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="1740" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1741"><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="1742" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1743"><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="1744" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1745"><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="1746" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1747"><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="1748" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1749"><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="1750" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1751"><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="1752" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1753"><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="1754" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1755"><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="1756" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1757"><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="1758" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1759"><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="1760" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1761"><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="1762" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1763"><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="1764" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1765"><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="1766" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1767"><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="1768" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1769"><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="1770" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1771"><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="1772" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1773"><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="1774" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1775"><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="1776" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1777"><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="1778" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1779"><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="1780" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1781"><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="1782" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1783"><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="1784" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1785"><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="1786" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1787"><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="1788" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1789"><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="1790" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1791"><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="1792" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1793"><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="1794" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1795"><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="1796" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1797"><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="1798" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1799"><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="1800" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1801"><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="1802" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1803"><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="1804" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1805"><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="1806" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1807"><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="1808" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1809"><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="1810" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1811"><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="1812" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1813"><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="1814" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1815"><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="1816" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1817"><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="1818" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1819"><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="1820" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1821"><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="1822" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1823"><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="1824" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1825"><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="1826" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1827"><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="1828" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1829"><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="1830" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1831"><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="1832" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1833"><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="1834" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1835"><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="1836" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1837"><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="1838" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1839"><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="1840" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1841"><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="1842" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1843"><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="1844" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1845"><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="1846" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1847"><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="1848" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1849"><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="1850" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1851"><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="1852" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1853"><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="1854" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1855"><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="1856" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1857"><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="1858" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1859"><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="1860" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1861"><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="1862" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1863"><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="1864" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1865"><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="1866" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1867"><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="1868" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1869"><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="1870" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1871"><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="1872" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1873"><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="1874" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1875"><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="1876" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1877"><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="1878" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1879"><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="1880" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1881"><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="1882" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1883"><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="1884" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1885"><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="1886" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1887"><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="1888" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1889"><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="1890" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1891"><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="1892" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1893"><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="1894" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1895"><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="1896" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1897"><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="1898" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1899"><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="1900" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1901"><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="1902" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1903"><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="1904" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1905"><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="1906" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1907"><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="1908" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1909"><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="1910" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1911"><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="1912" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1913"><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="1914" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1915"><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="1916" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1917"><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="1918" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1919"><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="1920" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1921"><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="1922" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1923"><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="1924" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1925"><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="1926" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1927"><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="1928" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1929"><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="1930" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1931"><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="1932" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1933"><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="1934" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1935"><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="1936" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1937"><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="1938" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1939"><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="1940" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1941"><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="1942" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1943"><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="1944" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1945"><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="1946" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1947"><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="1948" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1949"><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="1950" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1951"><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="1952" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1953"><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="1954" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1955"><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="1956" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1957"><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="1958" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1959"><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="1960" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1961"><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="1962" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1963"><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="1964" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1965"><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="1966" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1967"><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="1968" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1969"><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="1970" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1971"><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="1972" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1973"><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="1974" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1975"><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="1976" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1977"><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="1978" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1979"><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="1980" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1981"><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="1982" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1983"><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="1984" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1985"><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="1986" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1987"><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="1988" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1989"><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="1990" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1991"><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="1992" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1993"><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="1994" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1995"><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="1996" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1997"><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="1998" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1999"><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="2000" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2001"><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="2002" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2003"><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="2004" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2005"><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="2006" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2007"><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="2008" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2009"><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="2010" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2011"><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="2012" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2013"><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="2014" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2015"><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="2016" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2017"><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="2018" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2019"><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="2020" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2021"><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="2022" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2023"><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="2024" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2025"><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="2026" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2027"><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="2028" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2029"><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="2030" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2031"><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="2032" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2033"><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="2034" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2035"><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="2036" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2037"><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="2038" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2039"><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="2040" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2041"><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="2042" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2043"><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="2044" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2045"><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="2046" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2047"><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="2048" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2049"><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="2050" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2051"><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="2052" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2053"><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="2054" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2055"><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="2056" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2057"><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="2058" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2059"><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="2060" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2061"><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="2062" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2063"><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="2064" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2065"><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="2066" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2067"><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="2068" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2069"><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="2070" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2071"><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="2072" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2073"><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="2074" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2075"><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="2076" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2077"><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="2078" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2079"><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="2080" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2081"><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="2082" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2083"><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="2084" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2085"><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="2086" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2087"><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="2088" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2089"><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="2090" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2091"><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="2092" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2093"><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="2094" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2095"><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="2096" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2097"><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="2098" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2099"><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="2100" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2101"><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="2102" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2103"><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="2104" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2105"><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="2106" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2107"><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="2108" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2109"><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="2110" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2111"><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="2112" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2113"><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="2114" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2115"><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="2116" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2117"><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="2118" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2119"><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="2120" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2121"><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="2122" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2123"><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="2124" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2125"><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="2126" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2127"><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="2128" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2129"><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="2130" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2131"><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="2132" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2133"><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="2134" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2135"><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="2136" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2137"><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="2138" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2139"><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="2140" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2141"><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="2142" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2143"><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="2144" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2145"><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="2146" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2147"><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="2148" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2149"><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="2150" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2151"><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="2152" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2153"><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="2154" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2155"><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="2156" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2157"><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="2158" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2159"><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="2160" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2161"><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="2162" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2163"><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="2164" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2165"><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="2166" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2167"><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="2168" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2169"><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="2170" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2171"><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="2172" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2173"><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="2174" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2175"><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="2176" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2177"><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="2178" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2179"><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="2180" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2181"><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="2182" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2183"><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="2184" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2185"><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="2186" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2187"><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="2188" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2189"><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="2190" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2191"><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="2192" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2193"><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="2194" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2195"><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="2196" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2197"><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="2198" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2199"><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="2200" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2201"><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="2202" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2203"><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="2204" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2205"><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="2206" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2207"><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="2208" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2209"><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="2210" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2211"><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="2212" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2213"><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="2214" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2215"><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="2216" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2217"><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="2218" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2219"><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="2220" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2221"><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="2222" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2223"><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="2224" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2225"><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="2226" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2227"><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="2228" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2229"><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="2230" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2231"><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="2232" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2233"><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="2234" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2235"><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="2236" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2237"><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="2238" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2239"><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="2240" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2241"><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="2242" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2243"><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="2244" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2245"><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="2246" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2247"><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="2248" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2249"><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="2250" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2251"><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="2252" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2253"><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="2254" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2255"><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="2256" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2257"><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="2258" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2259"><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="2260" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2261"><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="2262" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2263"><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="2264" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2265"><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="2266" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2267"><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="2268" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2269"><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="2270" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2271"><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="2272" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2273"><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="2274" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2275"><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="2276" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2277"><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="2278" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2279"><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="2280" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2281"><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="2282" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2283"><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="2284" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2285"><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="2286" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2287"><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="2288" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2289"><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="2290" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2291"><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="2292" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2293"><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="2294" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2295"><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="2296" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2297"><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="2298" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2299"><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="2300" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2301"><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="2302" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2303"><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="2304" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2305"><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="2306" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2307"><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="2308" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2309"><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="2310" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2311"><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="2312" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2313"><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="2314" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2315"><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="2316" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2317"><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="2318" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2319"><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="2320" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2321"><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="2322" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2323"><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="2324" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2325"><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="2326" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2327"><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="2328" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2329"><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="2330" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2331"><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="2332" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2333"><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="2334" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2335"><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="2336" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2337"><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="2338" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2339"><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="2340" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2341"><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="2342" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2343"><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="2344" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2345"><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="2346" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2347"><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="2348" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2349"><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="2350" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2351"><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="2352" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2353"><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="2354" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2355"><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="2356" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2357"><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="2358" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2359"><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="2360" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2361"><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="2362" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2363"><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="2364" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2365"><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="2366" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2367"><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="2368" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2369"><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="2370" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2371"><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="2372" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2373"><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="2374" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2375"><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="2376" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2377"><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="2378" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2379"><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="2380" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2381"><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="2382" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2383"><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="2384" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2385"><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="2386" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2387"><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="2388" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2389"><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="2390" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2391"><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="2392" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2393"><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="2394" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2395"><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="2396" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2397"><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="2398" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2399"><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="2400" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2401"><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="2402" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2403"><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="2404" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2405"><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="2406" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2407"><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="2408" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2409"><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="2410" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2411"><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="2412" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2413"><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="2414" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2415"><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="2416" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2417"><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="2418" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2419"><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="2420" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2421"><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="2422" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2423"><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="2424" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2425"><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="2426" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2427"><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="2428" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2429"><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="2430" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2431"><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="2432" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2433"><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="2434" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2435"><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="2436" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2437"><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="2438" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2439"><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="2440" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2441"><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="2442" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2443"><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="2444" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2445"><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="2446" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2447"><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="2448" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2449"><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="2450" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2451"><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="2452" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2453"><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="2454" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2455"><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="2456" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2457"><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="2458" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2459"><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="2460" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2461"><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="2462" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2463"><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="2464" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2465"><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="2466" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2467"><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="2468" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2469"><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="2470" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2471"><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="2472" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2473"><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="2474" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2475"><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="2476" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2477"><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="2478" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2479"><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="2480" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2481"><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="2482" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2483"><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="2484" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2485"><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="2486" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2487"><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="2488" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2489"><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="2490" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2491"><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="2492" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2493"><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="2494" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2495"><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="2496" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2497"><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="2498" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2499"><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="2500" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2501"><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="2502" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2503"><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="2504" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2505"><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="2506" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2507"><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="2508" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2509"><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="2510" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2511"><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="2512" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2513"><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="2514" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2515"><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="2516" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2517"><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="2518" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2519"><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="2520" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2521"><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="2522" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2523"><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="2524" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2525"><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="2526" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2527"><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="2528" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2529"><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="2530" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2531"><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="2532" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2533"><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="2534" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2535"><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="2536" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2537"><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="2538" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2539"><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="2540" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2541"><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="2542" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2543"><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="2544" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2545"><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="2546" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2547"><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="2548" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2549"><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="2550" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2551"><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="2552" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2553"><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="2554" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2555"><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="2556" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2557"><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="2558" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2559"><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="2560" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2561"><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="2562" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2563"><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="2564" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2565"><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="2566" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2567"><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="2568" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2569"><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="2570" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2571"><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="2572" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2573"><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="2574" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2575"><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="2576" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2577"><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="2578" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2579"><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="2580" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2581"><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="2582" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2583"><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="2584" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2585"><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="2586" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2587"><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="2588" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2589"><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="2590" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2591"><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="2592" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2593"><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="2594" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2595"><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="2596" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2597"><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="2598" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2599"><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="2600" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2601"><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="2602" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2603"><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="2604" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2605"><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="2606" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2607"><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="2608" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2609"><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="2610" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2611"><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="2612" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2613"><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="2614" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2615"><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="2616" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2617"><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="2618" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2619"><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="2620" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2621"><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="2622" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2623"><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="2624" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2625"><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="2626" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2627"><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="2628" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2629"><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="2630" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2631"><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="2632" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2633"><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="2634" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2635"><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="2636" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2637"><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="2638" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2639"><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="2640" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2641"><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="2642" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2643"><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="2644" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2645"><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="2646" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2647"><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="2648" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2649"><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="2650" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2651"><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="2652" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2653"><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="2654" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2655"><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="2656" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2657"><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="2658" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2659"><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="2660" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2661"><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="2662" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2663"><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="2664" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2665"><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="2666" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2667"><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="2668" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2669"><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="2670" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2671"><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="2672" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2673"><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="2674" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2675"><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="2676" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2677"><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="2678" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2679"><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="2680" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2681"><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="2682" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2683"><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="2684" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2685"><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="2686" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2687"><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="2688" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2689"><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="2690" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2691"><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="2692" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2693"><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="2694" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2695"><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="2696" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2697"><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="2698" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2699"><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="2700" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2701"><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="2702" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2703"><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="2704" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2705"><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="2706" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2707"><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="2708" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2709"><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="2710" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2711"><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="2712" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2713"><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="2714" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2715"><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="2716" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2717"><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="2718" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2719"><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="2720" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2721"><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="2722" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2723"><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="2724" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2725"><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="2726" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2727"><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="2728" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2729"><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="2730" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2731"><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="2732" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2733"><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="2734" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2735"><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="2736" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2737"><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="2738" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2739"><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="2740" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2741"><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="2742" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2743"><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="2744" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2745"><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="2746" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2747"><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="2748" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2749"><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="2750" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2751"><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="2752" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2753"><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="2754" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2755"><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="2756" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2757"><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="2758" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2759"><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="2760" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2761"><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="2762" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2763"><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="2764" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2765"><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="2766" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2767"><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="2768" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2769"><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="2770" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2771"><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="2772" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2773"><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="2774" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2775"><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="2776" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2777"><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="2778" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2779"><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="2780" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2781"><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="2782" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2783"><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="2784" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2785"><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="2786" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2787"><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="2788" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2789"><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="2790" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2791"><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="2792" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2793"><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="2794" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2795"><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="2796" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2797"><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="2798" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2799"><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="2800" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2801"><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="2802" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2803"><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="2804" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2805"><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="2806" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2807"><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="2808" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2809"><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="2810" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2811"><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="2812" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2813"><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="2814" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2815"><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="2816" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2817"><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="2818" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2819"><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="2820" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2821"><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="2822" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2823"><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="2824" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2825"><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="2826" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2827"><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="2828" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2829"><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="2830" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2831"><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="2832" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2833"><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="2834" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2835"><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="2836" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2837"><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="2838" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2839"><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="2840" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2841"><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="2842" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2843"><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="2844" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2845"><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="2846" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2847"><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="2848" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2849"><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="2850" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2851"><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="2852" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2853"><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="2854" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2855"><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="2856" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2857"><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="2858" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2859"><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="2860" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2861"><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="2862" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2863"><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="2864" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2865"><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="2866" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2867"><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="2868" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2869"><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="2870" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2871"><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="2872" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2873"><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="2874" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2875"><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="2876" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2877"><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="2878" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2879"><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="2880" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2881"><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="2882" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2883"><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="2884" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2885"><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="2886" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2887"><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="2888" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2889"><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="2890" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2891"><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="2892" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2893"><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="2894" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2895"><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="2896" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2897"><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="2898" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2899"><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="2900" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2901"><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="2902" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2903"><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="2904" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2905"><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="2906" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2907"><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="2908" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2909"><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="2910" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2911"><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="2912" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2913"><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="2914" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2915"><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="2916" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2917"><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="2918" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2919"><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="2920" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2921"><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="2922" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2923"><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="2924" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2925"><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="2926" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2927"><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="2928" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2929"><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="2930" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2931"><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="2932" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2933"><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="2934" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2935"><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="2936" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2937"><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="2938" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2939"><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="2940" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2941"><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="2942" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2943"><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="2944" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2945"><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="2946" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2947"><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="2948" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2949"><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="2950" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2951"><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="2952" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2953"><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="2954" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2955"><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="2956" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2957"><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="2958" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2959"><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="2960" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2961"><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="2962" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2963"><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="2964" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2965"><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="2966" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2967"><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="2968" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2969"><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="2970" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2971"><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="2972" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2973"><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="2974" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2975"><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="2976" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2977"><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="2978" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2979"><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="2980" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2981"><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="2982" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2983"><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="2984" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2985"><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="2986" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2987"><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="2988" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2989"><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="2990" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2991"><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="2992" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2993"><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="2994" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2995"><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="2996" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2997"><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="2998" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2999"><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="3000" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3001"><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="3002" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3003"><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="3004" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3005"><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="3006" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3007"><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="3008" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3009"><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="3010" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3011"><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="3012" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3013"><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="3014" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3015"><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="3016" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3017"><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="3018" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3019"><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="3020" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3021"><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="3022" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3023"><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="3024" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3025"><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="3026" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3027"><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="3028" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3029"><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="3030" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3031"><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="3032" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3033"><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="3034" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3035"><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="3036" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3037"><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="3038" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3039"><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="3040" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3041"><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="3042" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3043"><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="3044" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3045"><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="3046" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3047"><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="3048" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3049"><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="3050" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3051"><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="3052" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3053"><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="3054" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3055"><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="3056" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3057"><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="3058" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3059"><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="3060" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3061"><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="3062" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3063"><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="3064" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3065"><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="3066" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3067"><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="3068" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3069"><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="3070" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3071"><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="3072" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3073"><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="3074" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3075"><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="3076" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3077"><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="3078" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3079"><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="3080" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3081"><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="3082" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3083"><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="3084" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3085"><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="3086" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3087"><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="3088" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3089"><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="3090" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3091"><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="3092" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3093"><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="3094" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3095"><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="3096" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3097"><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="3098" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3099"><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="3100" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3101"><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="3102" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3103"><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="3104" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3105"><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="3106" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3107"><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="3108" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3109"><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="3110" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3111"><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="3112" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3113"><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="3114" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3115"><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="3116" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3117"><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="3118" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3119"><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="3120" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3121"><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="3122" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3123"><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="3124" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3125"><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="3126" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3127"><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="3128" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3129"><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="3130" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3131"><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="3132" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3133"><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="3134" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3135"><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="3136" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3137"><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="3138" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3139"><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="3140" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3141"><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="3142" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3143"><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="3144" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3145"><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="3146" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3147"><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="3148" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3149"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record></t:root> \ No newline at end of file
diff --git a/examples/cxx/parser/performance/test-50k.xml b/examples/cxx/parser/performance/test-50k.xml
new file mode 100644
index 0000000..42e22f3
--- /dev/null
+++ b/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/examples/cxx/parser/performance/test-5k.xml b/examples/cxx/parser/performance/test-5k.xml
new file mode 100644
index 0000000..168cb09
--- /dev/null
+++ b/examples/cxx/parser/performance/test-5k.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></t:root> \ No newline at end of file
diff --git a/examples/cxx/parser/performance/test.xsd b/examples/cxx/parser/performance/test.xsd
new file mode 100644
index 0000000..2af594e
--- /dev/null
+++ b/examples/cxx/parser/performance/test.xsd
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/performance/test.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/performance/time.cxx b/examples/cxx/parser/performance/time.cxx
new file mode 100644
index 0000000..d7c81ce
--- /dev/null
+++ b/examples/cxx/parser/performance/time.cxx
@@ -0,0 +1,47 @@
+// file : examples/cxx/parser/performance/time.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/performance/time.hxx b/examples/cxx/parser/performance/time.hxx
new file mode 100644
index 0000000..37ec457
--- /dev/null
+++ b/examples/cxx/parser/performance/time.hxx
@@ -0,0 +1,111 @@
+// file : examples/cxx/parser/performance/time.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/polymorphism/README b/examples/cxx/parser/polymorphism/README
new file mode 100644
index 0000000..60a97e9
--- /dev/null
+++ b/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/examples/cxx/parser/polymorphism/driver.cxx b/examples/cxx/parser/polymorphism/driver.cxx
new file mode 100644
index 0000000..842a88b
--- /dev/null
+++ b/examples/cxx/parser/polymorphism/driver.cxx
@@ -0,0 +1,71 @@
+// file : examples/cxx/parser/polymorphism/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/polymorphism/makefile b/examples/cxx/parser/polymorphism/makefile
new file mode 100644
index 0000000..2c4054d
--- /dev/null
+++ b/examples/cxx/parser/polymorphism/makefile
@@ -0,0 +1,68 @@
+# file : examples/cxx/parser/polymorphism/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := supermen.xsd
+cxx := driver.cxx supermen-pimpl.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-polymorphic
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/parser/polymorphism/supermen-pimpl.cxx b/examples/cxx/parser/polymorphism/supermen-pimpl.cxx
new file mode 100644
index 0000000..8a30cbd
--- /dev/null
+++ b/examples/cxx/parser/polymorphism/supermen-pimpl.cxx
@@ -0,0 +1,86 @@
+// file : examples/cxx/parser/polymorphism/supermen-pimpl.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/polymorphism/supermen-pimpl.hxx b/examples/cxx/parser/polymorphism/supermen-pimpl.hxx
new file mode 100644
index 0000000..3c0f549
--- /dev/null
+++ b/examples/cxx/parser/polymorphism/supermen-pimpl.hxx
@@ -0,0 +1,69 @@
+// file : examples/cxx/parser/polymorphism/supermen-pimpl.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/polymorphism/supermen.xml b/examples/cxx/parser/polymorphism/supermen.xml
new file mode 100644
index 0000000..c2bc7b4
--- /dev/null
+++ b/examples/cxx/parser/polymorphism/supermen.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/polymorphism/supermen.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/polymorphism/supermen.xsd b/examples/cxx/parser/polymorphism/supermen.xsd
new file mode 100644
index 0000000..83a7aac
--- /dev/null
+++ b/examples/cxx/parser/polymorphism/supermen.xsd
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/polymorphism/supermen.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="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/examples/cxx/parser/polyroot/README b/examples/cxx/parser/polyroot/README
new file mode 100644
index 0000000..f41b91c
--- /dev/null
+++ b/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/examples/cxx/parser/polyroot/batman.xml b/examples/cxx/parser/polyroot/batman.xml
new file mode 100644
index 0000000..70abdf7
--- /dev/null
+++ b/examples/cxx/parser/polyroot/batman.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/polyroot/batman.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/polyroot/driver.cxx b/examples/cxx/parser/polyroot/driver.cxx
new file mode 100644
index 0000000..b04bba5
--- /dev/null
+++ b/examples/cxx/parser/polyroot/driver.cxx
@@ -0,0 +1,139 @@
+// file : examples/cxx/parser/polyroot/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/polyroot/makefile b/examples/cxx/parser/polyroot/makefile
new file mode 100644
index 0000000..f1d6f08
--- /dev/null
+++ b/examples/cxx/parser/polyroot/makefile
@@ -0,0 +1,68 @@
+# file : examples/cxx/parser/polyroot/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := supermen.xsd
+cxx := driver.cxx supermen-pimpl.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-polymorphic
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/parser/polyroot/person.xml b/examples/cxx/parser/polyroot/person.xml
new file mode 100644
index 0000000..157a5af
--- /dev/null
+++ b/examples/cxx/parser/polyroot/person.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/polyroot/person.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/polyroot/superman.xml b/examples/cxx/parser/polyroot/superman.xml
new file mode 100644
index 0000000..86d9682
--- /dev/null
+++ b/examples/cxx/parser/polyroot/superman.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/polyroot/superman.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/polyroot/supermen-pimpl.cxx b/examples/cxx/parser/polyroot/supermen-pimpl.cxx
new file mode 100644
index 0000000..db41ab2
--- /dev/null
+++ b/examples/cxx/parser/polyroot/supermen-pimpl.cxx
@@ -0,0 +1,86 @@
+// file : examples/cxx/parser/polyroot/supermen-pimpl.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/polyroot/supermen-pimpl.hxx b/examples/cxx/parser/polyroot/supermen-pimpl.hxx
new file mode 100644
index 0000000..035d127
--- /dev/null
+++ b/examples/cxx/parser/polyroot/supermen-pimpl.hxx
@@ -0,0 +1,65 @@
+// file : examples/cxx/parser/polyroot/supermen-pimpl.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/parser/polyroot/supermen.xsd b/examples/cxx/parser/polyroot/supermen.xsd
new file mode 100644
index 0000000..090b662
--- /dev/null
+++ b/examples/cxx/parser/polyroot/supermen.xsd
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/polyroot/supermen.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="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/examples/cxx/parser/wildcard/README b/examples/cxx/parser/wildcard/README
new file mode 100644
index 0000000..89f9aa9
--- /dev/null
+++ b/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/examples/cxx/parser/wildcard/driver.cxx b/examples/cxx/parser/wildcard/driver.cxx
new file mode 100644
index 0000000..fb87232
--- /dev/null
+++ b/examples/cxx/parser/wildcard/driver.cxx
@@ -0,0 +1,240 @@
+// file : examples/cxx/parser/wildcard/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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 ()
+ {
+ std::auto_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:
+ std::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/examples/cxx/parser/wildcard/email.xml b/examples/cxx/parser/wildcard/email.xml
new file mode 100644
index 0000000..55f1e4b
--- /dev/null
+++ b/examples/cxx/parser/wildcard/email.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/wildcard/email.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/wildcard/email.xsd b/examples/cxx/parser/wildcard/email.xsd
new file mode 100644
index 0000000..2e1f660
--- /dev/null
+++ b/examples/cxx/parser/wildcard/email.xsd
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/parser/wildcard/email.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/parser/wildcard/makefile b/examples/cxx/parser/wildcard/makefile
new file mode 100644
index 0000000..0d574ca
--- /dev/null
+++ b/examples/cxx/parser/wildcard/makefile
@@ -0,0 +1,67 @@
+# file : examples/cxx/parser/wildcard/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := email.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/README b/examples/cxx/tree/README
new file mode 100644
index 0000000..16e5ce3
--- /dev/null
+++ b/examples/cxx/tree/README
@@ -0,0 +1,70 @@
+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.
+
+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.
+
+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 create an XML document by performing multiple
+ serializations of its smaller parts. This can be useful when the
+ document is too large to fit into memory or when the other end
+ needs to start processing without waiting for the whole document
+ (streaming).
+
+binary/
+ A collection of examples that show how to serialize the object model
+ into a number of predefined and custom binary formats.
+
+dbxml
+ Shows how to use the C++/Tree mapping on top of the Berkeley DB
+ XML embedded XML database.
diff --git a/examples/cxx/tree/binary/README b/examples/cxx/tree/binary/README
new file mode 100644
index 0000000..365551e
--- /dev/null
+++ b/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/examples/cxx/tree/binary/boost/README b/examples/cxx/tree/binary/boost/README
new file mode 100644
index 0000000..6cdd2dd
--- /dev/null
+++ b/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/examples/cxx/tree/binary/boost/boost-archive-extraction.hxx b/examples/cxx/tree/binary/boost/boost-archive-extraction.hxx
new file mode 100644
index 0000000..7711b28
--- /dev/null
+++ b/examples/cxx/tree/binary/boost/boost-archive-extraction.hxx
@@ -0,0 +1,188 @@
+// file : examples/cxx/tree/binary/boost/boost-archive-insertion.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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);
+ }
+ }
+ }
+}
+
+#endif // BOOST_ARCHIVE_EXTRACTION_HXX
diff --git a/examples/cxx/tree/binary/boost/boost-archive-insertion.hxx b/examples/cxx/tree/binary/boost/boost-archive-insertion.hxx
new file mode 100644
index 0000000..7a00ef8
--- /dev/null
+++ b/examples/cxx/tree/binary/boost/boost-archive-insertion.hxx
@@ -0,0 +1,177 @@
+// file : examples/cxx/tree/binary/boost/boost-archive-insertion.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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 ());
+ }
+ }
+ }
+}
+
+#endif // BOOST_ARCHIVE_INSERTION_HXX
diff --git a/examples/cxx/tree/binary/boost/driver.cxx b/examples/cxx/tree/binary/boost/driver.cxx
new file mode 100644
index 0000000..9490d13
--- /dev/null
+++ b/examples/cxx/tree/binary/boost/driver.cxx
@@ -0,0 +1,73 @@
+// file : examples/cxx/tree/binary/boost/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_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::auto_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::auto_ptr<catalog> copy (new catalog (is));
+
+ cerr << *copy << endl;
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/examples/cxx/tree/binary/boost/library-prologue.hxx b/examples/cxx/tree/binary/boost/library-prologue.hxx
new file mode 100644
index 0000000..ba0d35f
--- /dev/null
+++ b/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/examples/cxx/tree/binary/boost/library.xml b/examples/cxx/tree/binary/boost/library.xml
new file mode 100644
index 0000000..da2bee6
--- /dev/null
+++ b/examples/cxx/tree/binary/boost/library.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/binary/boost/library.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/binary/boost/library.xsd b/examples/cxx/tree/binary/boost/library.xsd
new file mode 100644
index 0000000..9f35d4a
--- /dev/null
+++ b/examples/cxx/tree/binary/boost/library.xsd
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/binary/boost/library.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/binary/boost/makefile b/examples/cxx/tree/binary/boost/makefile
new file mode 100644
index 0000000..f40c6d6
--- /dev/null
+++ b/examples/cxx/tree/binary/boost/makefile
@@ -0,0 +1,79 @@
+# file : examples/cxx/tree/binary/boost/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := library.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+$(call import,\
+ $(scf_root)/import/libboost/serialization/stub.make,\
+ l: boost_serialization.l,cpp-options: boost_serialization.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l) $(boost_serialization.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd -I$(src_root)
+$(obj) $(dep): $(xerces_c.l.cpp-options) $(boost_serialization.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--generate-ostream \
+--hxx-prologue-file $(src_base)/library-prologue.hxx \
+--generate-insertion boost::archive::text_oarchive \
+--generate-extraction boost::archive::text_iarchive
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/binary/cdr/README b/examples/cxx/tree/binary/cdr/README
new file mode 100644
index 0000000..914d27c
--- /dev/null
+++ b/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/examples/cxx/tree/binary/cdr/driver.cxx b/examples/cxx/tree/binary/cdr/driver.cxx
new file mode 100644
index 0000000..08ec0d5
--- /dev/null
+++ b/examples/cxx/tree/binary/cdr/driver.cxx
@@ -0,0 +1,88 @@
+// file : examples/cxx/tree/binary/cdr/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_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::auto_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::auto_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/examples/cxx/tree/binary/cdr/library.xml b/examples/cxx/tree/binary/cdr/library.xml
new file mode 100644
index 0000000..e7ccb3f
--- /dev/null
+++ b/examples/cxx/tree/binary/cdr/library.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/binary/cdr/library.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/binary/cdr/library.xsd b/examples/cxx/tree/binary/cdr/library.xsd
new file mode 100644
index 0000000..92d44d1
--- /dev/null
+++ b/examples/cxx/tree/binary/cdr/library.xsd
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/binary/cdr/library.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/binary/cdr/makefile b/examples/cxx/tree/binary/cdr/makefile
new file mode 100644
index 0000000..e811695
--- /dev/null
+++ b/examples/cxx/tree/binary/cdr/makefile
@@ -0,0 +1,78 @@
+# file : examples/cxx/tree/binary/cdr/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := library.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+$(call import,\
+ $(scf_root)/import/libace/stub.make,\
+ l: ace.l,cpp-options: ace.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l) $(ace.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options) $(ace.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--generate-ostream \
+--generate-insertion ACE_OutputCDR \
+--generate-extraction ACE_InputCDR
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/binary/makefile b/examples/cxx/tree/binary/makefile
new file mode 100644
index 0000000..f30fc66
--- /dev/null
+++ b/examples/cxx/tree/binary/makefile
@@ -0,0 +1,30 @@
+# file : examples/cxx/tree/binary/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+examples :=
+
+ifeq ($(xsd_with_boost_serialization),y)
+examples += boost
+endif
+
+ifeq ($(xsd_with_ace),y)
+examples += cdr
+endif
+
+ifeq ($(xsd_with_xdr),y)
+examples += xdr
+endif
+
+default := $(out_base)/
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(examples)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(examples)))
+
+$(foreach e,$(examples),$(call import,$(src_base)/$e/makefile))
diff --git a/examples/cxx/tree/binary/xdr/README b/examples/cxx/tree/binary/xdr/README
new file mode 100644
index 0000000..22d5693
--- /dev/null
+++ b/examples/cxx/tree/binary/xdr/README
@@ -0,0 +1,34 @@
+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 out of the box on most UNIX and GNU/Linux
+systems as part of Sun RPC. 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/examples/cxx/tree/binary/xdr/driver.cxx b/examples/cxx/tree/binary/xdr/driver.cxx
new file mode 100644
index 0000000..495eafc
--- /dev/null
+++ b/examples/cxx/tree/binary/xdr/driver.cxx
@@ -0,0 +1,149 @@
+// file : examples/cxx/tree/binary/xdr/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_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::auto_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::auto_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/examples/cxx/tree/binary/xdr/library.xml b/examples/cxx/tree/binary/xdr/library.xml
new file mode 100644
index 0000000..9ddcd5a
--- /dev/null
+++ b/examples/cxx/tree/binary/xdr/library.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/binary/xdr/library.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/binary/xdr/library.xsd b/examples/cxx/tree/binary/xdr/library.xsd
new file mode 100644
index 0000000..9999e72
--- /dev/null
+++ b/examples/cxx/tree/binary/xdr/library.xsd
@@ -0,0 +1,76 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/binary/xdr/library.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/binary/xdr/makefile b/examples/cxx/tree/binary/xdr/makefile
new file mode 100644
index 0000000..6414fe9
--- /dev/null
+++ b/examples/cxx/tree/binary/xdr/makefile
@@ -0,0 +1,78 @@
+# file : examples/cxx/tree/binary/xdr/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := library.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+$(call import,\
+ $(scf_root)/import/libace/stub.make,\
+ l: ace.l,cpp-options: ace.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l) $(ace.l) -lnsl
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options) $(ace.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--generate-ostream \
+--generate-insertion XDR \
+--generate-extraction XDR
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/caching/README b/examples/cxx/tree/caching/README
new file mode 100644
index 0000000..1bbb590
--- /dev/null
+++ b/examples/cxx/tree/caching/README
@@ -0,0 +1,29 @@
+This example shows how to use the 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 book in the object model to STDERR.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver library.xml
diff --git a/examples/cxx/tree/caching/driver.cxx b/examples/cxx/tree/caching/driver.cxx
new file mode 100644
index 0000000..5c3405a
--- /dev/null
+++ b/examples/cxx/tree/caching/driver.cxx
@@ -0,0 +1,179 @@
+// file : examples/cxx/tree/caching/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/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/exceptions.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+#include "library.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;
+
+ const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+#if _XERCES_VERSION >= 30000
+
+ // Xerces-C++ 3.0.0 and later.
+ //
+ xml::dom::auto_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable/Disable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, true);
+ conf->setParameter (XMLUni::fgXercesSchema, true);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // 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.
+ //
+ parser->loadGrammar ("library.xsd", Grammar::SchemaGrammarType, true);
+ conf->setParameter (XMLUni::fgXercesUseCachedGrammarInParse, true);
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+#else // _XERCES_VERSION >= 30000
+
+ // Same as above but for Xerces-C++ 2 series.
+ //
+ xml::dom::auto_ptr<DOMBuilder> parser (
+ impl->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+
+ parser->setFeature (XMLUni::fgDOMComments, false);
+ parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
+ parser->setFeature (XMLUni::fgDOMEntities, false);
+ parser->setFeature (XMLUni::fgDOMNamespaces, true);
+ parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false);
+ parser->setFeature (XMLUni::fgDOMValidation, true);
+ parser->setFeature (XMLUni::fgXercesSchema, true);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ parser->setErrorHandler (&ehp);
+
+ parser->loadGrammar ("library.xsd", Grammar::SchemaGrammarType, true);
+ parser->setFeature (XMLUni::fgXercesUseCachedGrammarInParse, true);
+
+ parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+#endif // _XERCES_VERSION >= 30000
+
+ // 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.
+ //
+#if _XERCES_VERSION >= 30000
+ xml_schema::dom::auto_ptr<DOMDocument> doc (parser->parse (&wrap));
+#else
+ xml_schema::dom::auto_ptr<DOMDocument> doc (parser->parse (wrap));
+#endif
+
+ eh.throw_if_failed<tree::parsing<char> > ();
+
+ // Parse DOM to the object model.
+ //
+ auto_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/examples/cxx/tree/caching/library.xml b/examples/cxx/tree/caching/library.xml
new file mode 100644
index 0000000..4c12c6e
--- /dev/null
+++ b/examples/cxx/tree/caching/library.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/caching/library.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/caching/library.xsd b/examples/cxx/tree/caching/library.xsd
new file mode 100644
index 0000000..5dca460
--- /dev/null
+++ b/examples/cxx/tree/caching/library.xsd
@@ -0,0 +1,73 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/caching/library.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/caching/makefile b/examples/cxx/tree/caching/makefile
new file mode 100644
index 0000000..2f4beaa
--- /dev/null
+++ b/examples/cxx/tree/caching/makefile
@@ -0,0 +1,71 @@
+# file : examples/cxx/tree/caching/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := library.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options :=
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/custom/README b/examples/cxx/tree/custom/README
new file mode 100644
index 0000000..482f5a9
--- /dev/null
+++ b/examples/cxx/tree/custom/README
@@ -0,0 +1,37 @@
+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.
+
+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/examples/cxx/tree/custom/calendar/README b/examples/cxx/tree/custom/calendar/README
new file mode 100644
index 0000000..f7f6989
--- /dev/null
+++ b/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/examples/cxx/tree/custom/calendar/calendar.xml b/examples/cxx/tree/custom/calendar/calendar.xml
new file mode 100644
index 0000000..ae9e570
--- /dev/null
+++ b/examples/cxx/tree/custom/calendar/calendar.xml
@@ -0,0 +1,23 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/calendar/calendar.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<cal:events xmlns:cal="http://www.codesynthesis.com/calendar"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/calendar calendar.xsd">
+
+ <event title="Bike ride" date="2006-09-04">
+ Don't forget to change the tire.
+ </event>
+
+ <event title="Mountain hike" date="2006-09-05">
+ Can be cancelled if it is too cold.
+ </event>
+
+</cal:events>
diff --git a/examples/cxx/tree/custom/calendar/calendar.xsd b/examples/cxx/tree/custom/calendar/calendar.xsd
new file mode 100644
index 0000000..fa612a7
--- /dev/null
+++ b/examples/cxx/tree/custom/calendar/calendar.xsd
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/calendar/calendar.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:cal="http://www.codesynthesis.com/calendar"
+ targetNamespace="http://www.codesynthesis.com/calendar">
+
+ <xsd:complexType name="event">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="title" type="xsd:string" use="required"/>
+ <xsd:attribute name="date" type="xsd:date" use="required"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="events">
+ <xsd:sequence>
+ <xsd:element name="event" type="cal:event" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="events" type="cal:events"/>
+
+</xsd:schema>
diff --git a/examples/cxx/tree/custom/calendar/driver.cxx b/examples/cxx/tree/custom/calendar/driver.cxx
new file mode 100644
index 0000000..02f1c27
--- /dev/null
+++ b/examples/cxx/tree/custom/calendar/driver.cxx
@@ -0,0 +1,40 @@
+// file : examples/cxx/tree/custom/calendar/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "calendar.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " calendar.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace calendar;
+
+ std::auto_ptr<events> e (events_ (argv[1]));
+
+ for (events::event_const_iterator i (e->event ().begin ());
+ i != e->event ().end (); ++i)
+ {
+ cerr << i->date () << " " << i->title () << endl
+ << *i << endl;
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/examples/cxx/tree/custom/calendar/makefile b/examples/cxx/tree/custom/calendar/makefile
new file mode 100644
index 0000000..36525aa
--- /dev/null
+++ b/examples/cxx/tree/custom/calendar/makefile
@@ -0,0 +1,90 @@
+# file : examples/cxx/tree/custom/calendar/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := calendar.xsd
+cxx := driver.cxx xml-schema-custom.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+$(call import,\
+ $(scf_root)/import/libboost/date-time/stub.make,\
+ l: boost_date_time.l,cpp-options: boost_date_time.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l) $(boost_date_time.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options) $(boost_date_time.l.cpp-options)
+
+# Header file for XML Schema namespace.
+#
+$(out_base)/xml-schema.hxx: $(out_root)/xsd/xsd
+ $(call message,xsd $(src_base)/xml-schema.xsd,\
+$(out_root)/xsd/xsd cxx-tree --output-dir $(out_base) --generate-xml-schema \
+--custom-type date \
+--hxx-epilogue '\#include "xml-schema-custom.hxx"' xml-schema.xsd)
+
+#
+#
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+# We have to double-escape '#' because the message function
+# (which is used in command scripts) expands things twice.
+#
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--generate-inline \
+--extern-xml-schema xml-schema.xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+ $(call message,rm $$1,rm -f $$1,$(out_base)/xml-schema.hxx)
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/custom/calendar/xml-schema-custom.cxx b/examples/cxx/tree/custom/calendar/xml-schema-custom.cxx
new file mode 100644
index 0000000..440a407
--- /dev/null
+++ b/examples/cxx/tree/custom/calendar/xml-schema-custom.cxx
@@ -0,0 +1,57 @@
+// file : examples/cxx/tree/custom/calendar/xml-schema-custom.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Include xml-schema.hxx instead of xml-schema-custom.hxx here.
+//
+#include "xml-schema.hxx"
+
+#include <xsd/cxx/xml/string.hxx> // xsd::cxx::xml::transcode
+#include <xsd/cxx/tree/text.hxx> // xsd::cxx::tree::text_content
+
+using namespace boost;
+using namespace boost::gregorian;
+
+namespace xml_schema
+{
+ date::
+ date (const xercesc::DOMElement& e, flags f, container* c)
+ : simple_type (e, f, c),
+ gregorian::date (
+ from_simple_string (
+ xsd::cxx::tree::text_content<char> (e)))
+ {
+ }
+
+ date::
+ date (const xercesc::DOMAttr& a, flags f, container* c)
+ : simple_type (a, f, c),
+ gregorian::date (
+ from_simple_string (
+ xsd::cxx::xml::transcode<char> (a.getValue ())))
+ {
+ }
+
+ date::
+ date (const std::string& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : simple_type (s, e, f, c),
+ gregorian::date (from_simple_string (s))
+ {
+ }
+
+ date::
+ date (const date& d, flags f, container* c)
+ : simple_type (d, f, c),
+ gregorian::date (d)
+ {
+ }
+
+ date* date::
+ _clone (flags f, container* c) const
+ {
+ return new date (*this, f, c);
+ }
+}
diff --git a/examples/cxx/tree/custom/calendar/xml-schema-custom.hxx b/examples/cxx/tree/custom/calendar/xml-schema-custom.hxx
new file mode 100644
index 0000000..2bab0b5
--- /dev/null
+++ b/examples/cxx/tree/custom/calendar/xml-schema-custom.hxx
@@ -0,0 +1,34 @@
+// file : examples/cxx/tree/custom/calendar/xml-schema-custom.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use xml-schema.hxx instead. This
+// file is included into generated xml-schema.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <boost/date_time/gregorian/gregorian.hpp> // boost::gregorian::date
+
+namespace xml_schema
+{
+ class date: public simple_type,
+ public boost::gregorian::date
+ {
+ public:
+ // Parsing c-tors: element, attribute, and list item.
+ //
+ date (const xercesc::DOMElement&, flags = 0, container* = 0);
+ date (const xercesc::DOMAttr&, flags = 0, container* = 0);
+ date (const std::string&,
+ const xercesc::DOMElement*,
+ flags = 0,
+ container* = 0);
+
+ // Copy c-tor and _clone.
+ //
+ date (const date&, flags = 0, container* = 0);
+
+ virtual date*
+ _clone (flags = 0, container* = 0) const;
+ };
+}
diff --git a/examples/cxx/tree/custom/comments/README b/examples/cxx/tree/custom/comments/README
new file mode 100644
index 0000000..8fd69d0
--- /dev/null
+++ b/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/examples/cxx/tree/custom/comments/dom-parse.cxx b/examples/cxx/tree/custom/comments/dom-parse.cxx
new file mode 100644
index 0000000..7ad6aa5
--- /dev/null
+++ b/examples/cxx/tree/custom/comments/dom-parse.cxx
@@ -0,0 +1,118 @@
+// file : examples/cxx/tree/custom/comments/dom-parse.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include "dom-parse.hxx"
+
+#include <istream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_*
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+using namespace xercesc;
+namespace xml = xsd::cxx::xml;
+namespace tree = xsd::cxx::tree;
+
+xml::dom::auto_ptr<DOMDocument>
+parse (std::istream& is, const std::string& id, bool validate)
+{
+ const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+#if _XERCES_VERSION >= 30000
+
+ // Xerces-C++ 3.0.0 and later.
+ //
+ xml::dom::auto_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable/Disable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, validate);
+ conf->setParameter (XMLUni::fgXercesSchema, validate);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ // Set error handler.
+ //
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+#else // _XERCES_VERSION >= 30000
+
+ // Same as above but for Xerces-C++ 2 series.
+ //
+ xml::dom::auto_ptr<DOMBuilder> parser (
+ impl->createDOMBuilder (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ parser->setFeature (XMLUni::fgDOMComments, false);
+ parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
+ parser->setFeature (XMLUni::fgDOMEntities, false);
+ parser->setFeature (XMLUni::fgDOMNamespaces, true);
+ parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false);
+ parser->setFeature (XMLUni::fgDOMValidation, validate);
+ parser->setFeature (XMLUni::fgXercesSchema, validate);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ parser->setErrorHandler (&ehp);
+
+#endif // _XERCES_VERSION >= 30000
+
+ // Prepare input stream.
+ //
+ xml::sax::std_input_source isrc (is, id);
+ Wrapper4InputSource wrap (&isrc, false);
+
+#if _XERCES_VERSION >= 30000
+ xml::dom::auto_ptr<DOMDocument> doc (parser->parse (&wrap));
+#else
+ xml::dom::auto_ptr<DOMDocument> doc (parser->parse (wrap));
+#endif
+
+ eh.throw_if_failed<tree::parsing<char> > ();
+
+ return doc;
+}
diff --git a/examples/cxx/tree/custom/comments/dom-parse.hxx b/examples/cxx/tree/custom/comments/dom-parse.hxx
new file mode 100644
index 0000000..05bfa2e
--- /dev/null
+++ b/examples/cxx/tree/custom/comments/dom-parse.hxx
@@ -0,0 +1,23 @@
+// file : examples/cxx/tree/custom/comments/dom-parse.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef DOM_PARSE
+#define DOM_PARSE
+
+#include <string>
+#include <iosfwd>
+
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+
+// Parse an XML document from the standard input stream with an
+// optional resource id. Resource id is used in diagnostics as
+// well as to locate schemas referenced from inside the document.
+//
+xsd::cxx::xml::dom::auto_ptr<xercesc::DOMDocument>
+parse (std::istream& is,
+ const std::string& id,
+ bool validate);
+
+#endif // DOM_PARSE
diff --git a/examples/cxx/tree/custom/comments/driver.cxx b/examples/cxx/tree/custom/comments/driver.cxx
new file mode 100644
index 0000000..4ce2573
--- /dev/null
+++ b/examples/cxx/tree/custom/comments/driver.cxx
@@ -0,0 +1,91 @@
+// file : examples/cxx/tree/custom/commens/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include "people.hxx"
+#include "dom-parse.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " people.xml" << endl;
+ return 1;
+ }
+
+ int r (0);
+
+ // We need to initialize the Xerces-C++ runtime because we
+ // are doing the XML-to-DOM parsing ourselves (see below).
+ //
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ using namespace people;
+ namespace xml = xsd::cxx::xml;
+
+ ifstream ifs;
+ ifs.exceptions (ifstream::badbit | ifstream::failbit);
+ ifs.open (argv[1]);
+
+ // For performance reasons the internal XML to DOM parsing code
+ // discards comments in the resulting DOM document. To overcome
+ // this we are going to use our own parse() function from
+ // dom-parse.hxx that preserves comments in the resulting DOM
+ // documents.
+ //
+ xml_schema::dom::auto_ptr<xercesc::DOMDocument> doc (
+ parse (ifs, argv[1], true));
+
+ // Parse the DOM document to the object model.
+ //
+ std::auto_ptr<catalog> c (catalog_ (*doc));
+
+ // Change the object model.
+ //
+ catalog::person_sequence& ps (c->person ());
+
+ for (catalog::person_iterator i (ps.begin ()); i != ps.end (); ++i)
+ {
+ i->age (i->age () + 1);
+ }
+
+ person john ("John Doe", 30);
+ john.comment ("Record for John Doe");
+
+ ps.push_back (john);
+
+ // Serialize.
+ //
+ xml_schema::namespace_infomap map;
+
+ map["ppl"].name = "http://www.codesynthesis.com/people";
+ map["ppl"].schema = "people.xsd";
+
+ catalog_ (std::cout, *c, map);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ r = 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << argv[1] << ": unable to open or read failure" << endl;
+ r = 1;
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+ return r;
+}
diff --git a/examples/cxx/tree/custom/comments/makefile b/examples/cxx/tree/custom/comments/makefile
new file mode 100644
index 0000000..a12b3fe
--- /dev/null
+++ b/examples/cxx/tree/custom/comments/makefile
@@ -0,0 +1,84 @@
+# file : examples/cxx/tree/custom/comments/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := people.xsd
+cxx := driver.cxx xml-schema-custom.cxx dom-parse.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+# Header file for XML Schema namespace.
+#
+$(out_base)/xml-schema.hxx: $(out_root)/xsd/xsd
+ $(call message,xsd $(src_base)/xml-schema.xsd,\
+$(out_root)/xsd/xsd cxx-tree --output-dir $(out_base) --generate-xml-schema \
+--generate-serialization --custom-type anyType=/type_base \
+--hxx-epilogue '\#include "xml-schema-custom.hxx"' xml-schema.xsd)
+
+#
+#
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--generate-inline \
+--generate-serialization \
+--extern-xml-schema xml-schema.xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+ $(call message,rm $$1,rm -f $$1,$(out_base)/xml-schema.hxx)
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/custom/comments/people.xml b/examples/cxx/tree/custom/comments/people.xml
new file mode 100644
index 0000000..b6a44e5
--- /dev/null
+++ b/examples/cxx/tree/custom/comments/people.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/comments/people.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<ppl:catalog xmlns:ppl="http://www.codesynthesis.com/people"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/people people.xsd">
+
+ <person>
+ <!--Record for Joe Dirt-->
+ <name>Joe Dirt</name>
+ <age>28</age>
+ </person>
+
+</ppl:catalog>
diff --git a/examples/cxx/tree/custom/comments/people.xsd b/examples/cxx/tree/custom/comments/people.xsd
new file mode 100644
index 0000000..2f40754
--- /dev/null
+++ b/examples/cxx/tree/custom/comments/people.xsd
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/comments/people.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:ppl="http://www.codesynthesis.com/people"
+ targetNamespace="http://www.codesynthesis.com/people">
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="age" type="xsd:unsignedShort"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="catalog">
+ <xsd:sequence>
+ <xsd:element name="person" type="ppl:person" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="catalog" type="ppl:catalog"/>
+
+</xsd:schema>
diff --git a/examples/cxx/tree/custom/comments/xml-schema-custom.cxx b/examples/cxx/tree/custom/comments/xml-schema-custom.cxx
new file mode 100644
index 0000000..d86d6af
--- /dev/null
+++ b/examples/cxx/tree/custom/comments/xml-schema-custom.cxx
@@ -0,0 +1,118 @@
+// file : examples/cxx/tree/custom/comments/xml-schema-custom.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Include xml-schema.hxx instead of xml-schema-custom.hxx here.
+//
+#include "xml-schema.hxx"
+
+#include <xercesc/dom/DOMComment.hpp>
+#include <xercesc/dom/DOMDocument.hpp>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode, xml::string
+
+namespace xml = xsd::cxx::xml;
+
+namespace xml_schema
+{
+ type::
+ type ()
+ : type_base ()
+ {
+ }
+
+ type::
+ type (const xercesc::DOMElement& e, flags f, container* c)
+ : type_base (e, f, c)
+ {
+ using namespace xercesc;
+
+ // Here we are only handling a comment that is the first
+ // node in the element's content.
+ //
+ const DOMNode* n (e.getFirstChild ());
+
+ if (n != 0 && n->getNodeType () == DOMNode::COMMENT_NODE)
+ {
+ const DOMComment* c (static_cast<const DOMComment*> (n));
+ comment_ = xml::transcode<char> (c->getData ());
+ }
+ }
+
+ type::
+ type (const xercesc::DOMAttr& a, flags f, container* c)
+ : type_base (a, f, c)
+ {
+ // No comments for attributes.
+ //
+ }
+
+ type::
+ type (const std::string& s, const xercesc::DOMElement* e,
+ flags f, container* c)
+ : type_base (s, e, f, c)
+ {
+ // No comments for list items.
+ //
+ }
+
+ type::
+ type (const type& x, flags f, container* c)
+ : type_base (x, f, c), comment_ (x.comment_)
+ {
+ }
+
+ type* type::
+ _clone (flags f, container* c) const
+ {
+ return new type (*this, f, c);
+ }
+
+ // Serialization operators.
+ //
+ void
+ operator<< (xercesc::DOMElement& e, const type& x)
+ {
+ // Call our base first.
+ //
+ const type_base& b (x);
+ e << b;
+
+ // Add the comment if any.
+ //
+ const std::string s (x.comment ());
+
+ if (!s.empty ())
+ {
+ using namespace xercesc;
+
+ DOMDocument* doc (e.getOwnerDocument ());
+ DOMComment* c (doc->createComment (xml::string (s).c_str ()));
+ e.appendChild (c);
+ }
+ }
+
+ void
+ operator<< (xercesc::DOMAttr& a, const type& x)
+ {
+ // Call our base first.
+ //
+ const type_base& b (x);
+ a << b;
+
+ // No comments for attributes.
+ //
+ }
+
+ void
+ operator<< (xml_schema::list_stream& ls, const type& x)
+ {
+ // Call our base first.
+ //
+ const type_base& b (x);
+ ls << b;
+
+ // No comments for list items.
+ //
+ }
+}
diff --git a/examples/cxx/tree/custom/comments/xml-schema-custom.hxx b/examples/cxx/tree/custom/comments/xml-schema-custom.hxx
new file mode 100644
index 0000000..821d0dd
--- /dev/null
+++ b/examples/cxx/tree/custom/comments/xml-schema-custom.hxx
@@ -0,0 +1,58 @@
+// file : examples/cxx/tree/custom/comments/xml-schema-custom.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use xml-schema.hxx instead. This
+// file is included into generated xml-schema.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <string>
+
+namespace xml_schema
+{
+ // When customizing anyType always inherit from the original type.
+ //
+ class type: public type_base
+ {
+ public:
+ type ();
+ type (const xercesc::DOMElement&, flags = 0, container* = 0);
+ type (const xercesc::DOMAttr&, flags = 0, container* = 0);
+ type (const std::string&, const xercesc::DOMElement*,
+ flags = 0, container* = 0);
+ type (const type&, flags = 0, container* = 0);
+
+ virtual type*
+ _clone (flags = 0, container* = 0) const;
+
+ public:
+ // Comment manipulation API.
+ //
+ const std::string&
+ comment () const
+ {
+ return comment_;
+ }
+
+ void
+ comment (const std::string& c)
+ {
+ comment_ = c;
+ }
+
+ private:
+ std::string comment_;
+ };
+
+ // New serialization operators.
+ //
+ void
+ operator<< (xercesc::DOMElement&, const type&);
+
+ void
+ operator<< (xercesc::DOMAttr&, const type&);
+
+ void
+ operator<< (xml_schema::list_stream&, const type&);
+}
diff --git a/examples/cxx/tree/custom/contacts/README b/examples/cxx/tree/custom/contacts/README
new file mode 100644
index 0000000..a3b237c
--- /dev/null
+++ b/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 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/examples/cxx/tree/custom/contacts/contacts-custom.cxx b/examples/cxx/tree/custom/contacts/contacts-custom.cxx
new file mode 100644
index 0000000..dd7c453
--- /dev/null
+++ b/examples/cxx/tree/custom/contacts/contacts-custom.cxx
@@ -0,0 +1,51 @@
+// file : examples/cxx/tree/custom/contacts/contacts-custom.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <ostream>
+
+// Include contacts.hxx instead of contacts-custom.hxx here.
+//
+#include "contacts.hxx"
+
+namespace contacts
+{
+ // We implement the following constructs by simply forwarding
+ // to our base.
+ //
+ contact::
+ contact (const name_type& n,
+ const email_type& e,
+ const phone_type& p)
+ : contact_base (n, e, p)
+ {
+ }
+
+ contact::
+ contact (const xercesc::DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : contact_base (e, f, c)
+ {
+ }
+
+ contact::
+ contact (const contact& x,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : contact_base (x, f, c)
+ {
+ }
+
+ contact* contact::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new contact (*this, f, c);
+ }
+
+ void contact::
+ print (std::ostream& os) const
+ {
+ os << name () << " e| " << email () << " t| " << phone () << std::endl;
+ }
+}
diff --git a/examples/cxx/tree/custom/contacts/contacts-custom.hxx b/examples/cxx/tree/custom/contacts/contacts-custom.hxx
new file mode 100644
index 0000000..fdb6810
--- /dev/null
+++ b/examples/cxx/tree/custom/contacts/contacts-custom.hxx
@@ -0,0 +1,44 @@
+// file : examples/cxx/tree/custom/contacts/contacts-custom.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use contacts.hxx instead. This
+// file is included into generated contacts.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <iosfwd> // std::ostream
+
+namespace contacts
+{
+ class contact: public contact_base
+ {
+ // The following constructor signatures are copied from
+ // contact_base except for the copy constructor and the
+ // _clone function where we had to change the type from
+ // contact_base to contact.
+ //
+ public:
+ contact (const name_type&,
+ const email_type&,
+ const phone_type&);
+
+ contact (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ contact (const contact&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ virtual contact*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ // Our customizations.
+ //
+ public:
+ void
+ print (std::ostream&) const;
+ };
+}
diff --git a/examples/cxx/tree/custom/contacts/contacts.xml b/examples/cxx/tree/custom/contacts/contacts.xml
new file mode 100644
index 0000000..c6dc38f
--- /dev/null
+++ b/examples/cxx/tree/custom/contacts/contacts.xml
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/contacts/contacts.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<cts:catalog xmlns:cts="http://www.codesynthesis.com/contacts"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/contacts contacts.xsd">
+
+ <contact>
+ <name>Joe Dirt</name>
+ <email>joe@dirt.com</email>
+ <phone>555 DIRT</phone>
+ </contact>
+
+</cts:catalog>
diff --git a/examples/cxx/tree/custom/contacts/contacts.xsd b/examples/cxx/tree/custom/contacts/contacts.xsd
new file mode 100644
index 0000000..da73c78
--- /dev/null
+++ b/examples/cxx/tree/custom/contacts/contacts.xsd
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/contacts/contacts.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:cts="http://www.codesynthesis.com/contacts"
+ targetNamespace="http://www.codesynthesis.com/contacts">
+
+ <xsd:complexType name="contact">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="email" type="xsd:string"/>
+ <xsd:element name="phone" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="catalog">
+ <xsd:sequence>
+ <xsd:element name="contact" type="cts:contact" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <xsd:element name="catalog" type="cts:catalog"/>
+
+</xsd:schema>
diff --git a/examples/cxx/tree/custom/contacts/driver.cxx b/examples/cxx/tree/custom/contacts/driver.cxx
new file mode 100644
index 0000000..9015e87
--- /dev/null
+++ b/examples/cxx/tree/custom/contacts/driver.cxx
@@ -0,0 +1,39 @@
+// file : examples/cxx/tree/custom/contacts/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "contacts.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " contacts.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace contacts;
+
+ std::auto_ptr<catalog> c (catalog_ (argv[1]));
+
+ for (catalog::contact_const_iterator i (c->contact ().begin ());
+ i != c->contact ().end (); ++i)
+ {
+ i->print (cerr);
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/examples/cxx/tree/custom/contacts/makefile b/examples/cxx/tree/custom/contacts/makefile
new file mode 100644
index 0000000..9a8dc89
--- /dev/null
+++ b/examples/cxx/tree/custom/contacts/makefile
@@ -0,0 +1,77 @@
+# file : examples/cxx/tree/custom/contacts/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := contacts.xsd
+cxx := driver.cxx contacts-custom.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+# We have to double-escape '#' because the message function
+# (which is used in command scripts) expands things twice.
+#
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--generate-inline \
+--custom-type contact=/contact_base \
+--hxx-epilogue '\\\#include "contacts-custom.hxx"'
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/custom/double/README b/examples/cxx/tree/custom/double/README
new file mode 100644
index 0000000..15348d2
--- /dev/null
+++ b/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/examples/cxx/tree/custom/double/double-custom.cxx b/examples/cxx/tree/custom/double/double-custom.cxx
new file mode 100644
index 0000000..78904a0
--- /dev/null
+++ b/examples/cxx/tree/custom/double/double-custom.cxx
@@ -0,0 +1,97 @@
+// file : examples/cxx/tree/custom/double/double-custom.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Include xml-schema.hxx instead of double-custom.hxx here.
+//
+#include "xml-schema.hxx"
+
+#include <limits>
+#include <locale>
+#include <sstream>
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+using namespace std;
+
+// Parsing.
+//
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ double traits<double, char, schema_type::double_>::
+ create (const std::string& s,
+ const xercesc::DOMElement*,
+ flags,
+ type*)
+ {
+ // This type cannot have whitespaces in its values. As result we
+ // don't need to waste time collapsing whitespaces. All we need to
+ // do is trim the string representation which can be done without
+ // copying.
+ //
+ ro_string<char> tmp (s);
+ trim (tmp);
+
+ zc_istream<char> is (tmp);
+ is.imbue (locale::classic ());
+
+ double t;
+ is >> t;
+
+ return t;
+ }
+ }
+ }
+}
+
+// Serialization.
+//
+namespace XERCES_CPP_NAMESPACE
+{
+ void
+ operator<< (xercesc::DOMElement& e, const xml_schema::as_double& d)
+ {
+ ostringstream os;
+ os.imbue (locale::classic ());
+
+ os.precision (2);
+ os << fixed << d.x;
+
+ e << os.str ();
+ }
+
+ void
+ operator<< (xercesc::DOMAttr& a, const xml_schema::as_double& d)
+ {
+ ostringstream os;
+ os.imbue (locale::classic ());
+
+ os.precision (2);
+ os << fixed << d.x;
+
+ a << os.str ();
+ }
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ void
+ operator<< (xml_schema::list_stream& ls,
+ const xml_schema::as_double& d)
+ {
+ ls.os_.imbue (locale::classic ());
+ ls.os_.precision (2);
+ ls.os_ << fixed << d.x;
+ }
+ }
+ }
+}
diff --git a/examples/cxx/tree/custom/double/double-custom.hxx b/examples/cxx/tree/custom/double/double-custom.hxx
new file mode 100644
index 0000000..17d9a44
--- /dev/null
+++ b/examples/cxx/tree/custom/double/double-custom.hxx
@@ -0,0 +1,68 @@
+// file : examples/cxx/tree/custom/double/double-custom.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use xml-schema.hxx instead. This
+// file is included into generated xml-schema.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+#include <xsd/cxx/tree/text.hxx> // text_content
+
+// Parsing.
+//
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template<>
+ struct traits<double, char, schema_type::double_>
+ {
+ static double
+ create (const xercesc::DOMElement& e, flags f, type* c)
+ {
+ return create (text_content<char> (e), 0, f, c);
+ }
+
+ static double
+ create (const xercesc::DOMAttr& a, flags f, type* c)
+ {
+ return create (xml::transcode<char> (a.getValue ()), 0, f, c);
+ }
+
+ static double
+ create (const std::string& s,
+ const xercesc::DOMElement*,
+ flags,
+ type*);
+ };
+ }
+ }
+}
+
+// Serialization.
+//
+namespace XERCES_CPP_NAMESPACE
+{
+ void
+ operator<< (xercesc::DOMElement& e, const xml_schema::as_double& d);
+
+ void
+ operator<< (xercesc::DOMAttr& a, const xml_schema::as_double& d);
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ void
+ operator<< (xml_schema::list_stream& ls,
+ const xml_schema::as_double& d);
+ }
+ }
+}
diff --git a/examples/cxx/tree/custom/double/driver.cxx b/examples/cxx/tree/custom/double/driver.cxx
new file mode 100644
index 0000000..2e5b44d
--- /dev/null
+++ b/examples/cxx/tree/custom/double/driver.cxx
@@ -0,0 +1,32 @@
+// file : examples/cxx/tree/custom/double/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <iostream>
+
+#include "order.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main ()
+{
+ try
+ {
+ // Order one Airbus A380.
+ //
+ order o;
+ o.item ().push_back (item ("Airbus A380", 317000000.90));
+
+
+ // Serialize.
+ //
+ order_ (std::cout, o);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/examples/cxx/tree/custom/double/makefile b/examples/cxx/tree/custom/double/makefile
new file mode 100644
index 0000000..249ed01
--- /dev/null
+++ b/examples/cxx/tree/custom/double/makefile
@@ -0,0 +1,79 @@
+# file : examples/cxx/tree/custom/double/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := order.xsd
+cxx := driver.cxx double-custom.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/xml-schema.hxx: $(out_root)/xsd/xsd
+ $(call message,xsd $(src_base)/xml-schema.xsd,\
+$(out_root)/xsd/xsd cxx-tree --output-dir $(out_base) --generate-xml-schema \
+--generate-serialization --custom-type double=double \
+--hxx-epilogue '\#include "double-custom.hxx"' xml-schema.xsd)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--generate-serialization --extern-xml-schema xml-schema.xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+ $(call message,rm $$1,rm -f $$1,$(out_base)/xml-schema.hxx)
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/custom/double/order.xsd b/examples/cxx/tree/custom/double/order.xsd
new file mode 100644
index 0000000..0d7fe05
--- /dev/null
+++ b/examples/cxx/tree/custom/double/order.xsd
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/double/order.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="item">
+ <xsd:attribute name="name" type="xsd:string" use="required"/>
+ <xsd:attribute name="price" type="xsd:double" use="required"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="order">
+ <xsd:sequence>
+ <xsd:element name="item" type="item" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="order" type="order"/>
+
+</xsd:schema>
diff --git a/examples/cxx/tree/custom/makefile b/examples/cxx/tree/custom/makefile
new file mode 100644
index 0000000..c29fd03
--- /dev/null
+++ b/examples/cxx/tree/custom/makefile
@@ -0,0 +1,22 @@
+# file : examples/cxx/tree/custom/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+examples := comments contacts double taxonomy wildcard
+
+ifeq ($(xsd_with_boost_date_time),y)
+examples += calendar
+endif
+
+default := $(out_base)/
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(examples)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(examples)))
+
+$(foreach e,$(examples),$(call import,$(src_base)/$e/makefile))
diff --git a/examples/cxx/tree/custom/taxonomy/README b/examples/cxx/tree/custom/taxonomy/README
new file mode 100644
index 0000000..addce83
--- /dev/null
+++ b/examples/cxx/tree/custom/taxonomy/README
@@ -0,0 +1,50 @@
+This example shows how to map user-defined XML Schema types to custom C++
+classes. It presents the complex case where the customized types are
+inherited from in the same schema. For the simple case see the contacts
+example. For more information on the C++/Tree mapping customization see
+the C++/Tree Mapping Customization Guide[1].
+
+[1] http://wiki.codesynthesis.com/Tree/Customization_guide
+
+The example consists of the following files:
+
+people.xsd
+ XML Schema definition for a simple people database.
+
+people.xml
+ Sample XML instance document.
+
+people-fwd.hxx
+people.hxx
+people.ixx
+people.cxx
+ C++ types that represent the given vocabulary and a set of parsing
+ functions that convert XML instance documents to a tree-like in-memory
+ object model. These are generated by XSD from people.xsd with the
+ --custom-type option in order to to customize the person, superman,
+ and batman types. Generation of the people-fwd.hxx forward declaration
+ file is requested with the --generate-forward option.
+
+people-custom-fwd.hxx
+ Header file which forward-declares our own person, superman, and batman
+ as class templates. It is included at the beginning of people-fwd.hxx
+ using the --fwd-prologue option.
+
+people-custom.hxx
+ Header file which defines our own person, superman, and batman class
+ templates by inheriting from the generated person_base, superman_base,
+ and batman_base. It is included at the beginning of people.hxx using
+ the --hxx-prologue option.
+
+people-custom.cxx
+ Source file which contains the implementations and instantiations of
+ our person, superman, and batman class templates.
+
+driver.cxx
+ Driver for the example. It first calls one of the parsing functions
+ that constructs the object model from the input file. It then prints
+ the database to STDERR.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver people.xml
diff --git a/examples/cxx/tree/custom/taxonomy/driver.cxx b/examples/cxx/tree/custom/taxonomy/driver.cxx
new file mode 100644
index 0000000..f102fc3
--- /dev/null
+++ b/examples/cxx/tree/custom/taxonomy/driver.cxx
@@ -0,0 +1,39 @@
+// file : examples/cxx/tree/custom/taxonomy/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "people.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " people.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace people;
+
+ std::auto_ptr<catalog> c (catalog_ (argv[1]));
+
+ for (catalog::person_const_iterator i (c->person ().begin ());
+ i != c->person ().end (); ++i)
+ {
+ i->print (cerr);
+ }
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/examples/cxx/tree/custom/taxonomy/makefile b/examples/cxx/tree/custom/taxonomy/makefile
new file mode 100644
index 0000000..a5fa4a3
--- /dev/null
+++ b/examples/cxx/tree/custom/taxonomy/makefile
@@ -0,0 +1,82 @@
+# file : examples/cxx/tree/custom/taxonomy/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := people.xsd
+cxx := driver.cxx people-custom.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+# We have to double-escape '#' because the message function
+# (which is used in command scripts) expands things twice.
+#
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--generate-inline \
+--generate-forward \
+--generate-polymorphic \
+--custom-type "person=person_impl<person_base>/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"'
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx b/examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx
new file mode 100644
index 0000000..973b6e5
--- /dev/null
+++ b/examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx
@@ -0,0 +1,20 @@
+// file : examples/cxx/tree/custom/taxonomy/people-custom-fwd.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use people-fwd.hxx instead. This
+// file is included into generated people-fwd.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+namespace people
+{
+ template <typename base>
+ class person_impl;
+
+ template <typename base>
+ class superman_impl;
+
+ template <typename base>
+ class batman_impl;
+}
diff --git a/examples/cxx/tree/custom/taxonomy/people-custom.cxx b/examples/cxx/tree/custom/taxonomy/people-custom.cxx
new file mode 100644
index 0000000..14c7087
--- /dev/null
+++ b/examples/cxx/tree/custom/taxonomy/people-custom.cxx
@@ -0,0 +1,180 @@
+// file : examples/cxx/tree/custom/taxonomy/people-custom.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <ostream>
+
+// Include people.hxx instead of people-custom.hxx here.
+//
+#include "people.hxx"
+
+namespace people
+{
+ // person_impl
+ //
+ template <typename base>
+ person_impl<base>::
+ person_impl (const xml_schema::string& name)
+ : base (name)
+ {
+ }
+
+ template <typename base>
+ person_impl<base>::
+ person_impl (std::auto_ptr<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 (std::auto_ptr<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 (std::auto_ptr<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/examples/cxx/tree/custom/taxonomy/people-custom.hxx b/examples/cxx/tree/custom/taxonomy/people-custom.hxx
new file mode 100644
index 0000000..23e7731
--- /dev/null
+++ b/examples/cxx/tree/custom/taxonomy/people-custom.hxx
@@ -0,0 +1,103 @@
+// file : examples/cxx/tree/custom/taxonomy/people-custom.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use people.hxx instead. This
+// file is included into generated people.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+#include <iosfwd> // std::ostream
+
+// Include people-fwd.hxx here so that we can refer to the generated
+// types.
+//
+#include "people-fwd.hxx"
+
+namespace people
+{
+ //
+ //
+ template <typename base>
+ class person_impl: public base
+ {
+ public:
+ person_impl (const xml_schema::string& name);
+ person_impl (std::auto_ptr<xml_schema::string>& name);
+
+ person_impl (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ person_impl (const person_impl&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ virtual person_impl*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ public:
+ virtual void
+ print (std::ostream&) const;
+ };
+
+
+ //
+ //
+ template <typename base>
+ class superman_impl: public base
+ {
+ public:
+ superman_impl (const xml_schema::string& name, bool can_fly);
+ superman_impl (std::auto_ptr<xml_schema::string>& name, bool can_fly);
+
+ superman_impl (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ superman_impl (const superman_impl&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ virtual superman_impl*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ public:
+ virtual void
+ print (std::ostream&) const;
+ };
+
+
+ //
+ //
+ template <typename base>
+ class batman_impl: public base
+ {
+ public:
+ batman_impl (const xml_schema::string& name,
+ bool can_fly,
+ unsigned int wing_span);
+
+ batman_impl (std::auto_ptr<xml_schema::string>& name,
+ bool can_fly,
+ unsigned int wing_span);
+
+ batman_impl (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ batman_impl (const batman_impl&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ virtual batman_impl*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ public:
+ virtual void
+ print (std::ostream&) const;
+ };
+}
diff --git a/examples/cxx/tree/custom/taxonomy/people.xml b/examples/cxx/tree/custom/taxonomy/people.xml
new file mode 100644
index 0000000..5f84855
--- /dev/null
+++ b/examples/cxx/tree/custom/taxonomy/people.xml
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/taxonomy/people.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<ppl:catalog xmlns:ppl="http://www.codesynthesis.com/people"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/people people.xsd">
+
+ <person>
+ <name>Joe Dirt</name>
+ </person>
+
+ <person xsi:type="ppl:superman" can-fly="false">
+ <name>James "007" Bond</name>
+ </person>
+
+ <person xsi:type="ppl:batman" can-fly="true" wing-span="10">
+ <name>Bruce Wayne</name>
+ </person>
+
+</ppl:catalog>
diff --git a/examples/cxx/tree/custom/taxonomy/people.xsd b/examples/cxx/tree/custom/taxonomy/people.xsd
new file mode 100644
index 0000000..c77a866
--- /dev/null
+++ b/examples/cxx/tree/custom/taxonomy/people.xsd
@@ -0,0 +1,45 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/taxonomy/people.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:ppl="http://www.codesynthesis.com/people"
+ targetNamespace="http://www.codesynthesis.com/people">
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="superman">
+ <xsd:complexContent>
+ <xsd:extension base="ppl:person">
+ <xsd:attribute name="can-fly" type="xsd:boolean" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="batman">
+ <xsd:complexContent>
+ <xsd:extension base="ppl:superman">
+ <xsd:attribute name="wing-span" type="xsd:unsignedInt" use="required"/>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="catalog">
+ <xsd:sequence>
+ <xsd:element name="person" type="ppl:person" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="catalog" type="ppl:catalog"/>
+
+</xsd:schema>
diff --git a/examples/cxx/tree/custom/wildcard/README b/examples/cxx/tree/custom/wildcard/README
new file mode 100644
index 0000000..5ca25c0
--- /dev/null
+++ b/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.
+
+contacts.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 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/examples/cxx/tree/custom/wildcard/driver.cxx b/examples/cxx/tree/custom/wildcard/driver.cxx
new file mode 100644
index 0000000..d63fb11
--- /dev/null
+++ b/examples/cxx/tree/custom/wildcard/driver.cxx
@@ -0,0 +1,48 @@
+// file : examples/cxx/tree/custom/wildcard/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "wildcard.hxx"
+
+using std::cerr;
+using std::endl;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " wildcard.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ using namespace wildcard;
+
+ // Parse.
+ //
+ std::auto_ptr<data> d (data_ (argv[1]));
+
+ // Print.
+ //
+ cerr << *d << endl;
+
+ // Serialize.
+ //
+ xml_schema::namespace_infomap map;
+
+ map["wc"].name = "http://www.codesynthesis.com/wildcard";
+ map["wc"].schema = "wildcard.xsd";
+
+ data_ (std::cout, *d, map);
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/examples/cxx/tree/custom/wildcard/makefile b/examples/cxx/tree/custom/wildcard/makefile
new file mode 100644
index 0000000..87f95ea
--- /dev/null
+++ b/examples/cxx/tree/custom/wildcard/makefile
@@ -0,0 +1,79 @@
+# file : examples/cxx/tree/custom/wildcard/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := wildcard.xsd
+cxx := driver.cxx wildcard-custom.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+# We have to double-escape '#' because the message function
+# (which is used in command scripts) expands things twice.
+#
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--generate-inline \
+--generate-ostream \
+--generate-serialization \
+--custom-type data=/data_base \
+--hxx-epilogue '\\\#include "wildcard-custom.hxx"'
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/custom/wildcard/wildcard-custom.cxx b/examples/cxx/tree/custom/wildcard/wildcard-custom.cxx
new file mode 100644
index 0000000..422a4b3
--- /dev/null
+++ b/examples/cxx/tree/custom/wildcard/wildcard-custom.cxx
@@ -0,0 +1,85 @@
+// file : examples/cxx/tree/custom/wildcard/wildcard-custom.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <ostream>
+
+// Include wildcard.hxx instead of wildcard-custom.hxx here.
+//
+#include "wildcard.hxx"
+
+namespace wildcard
+{
+ data::
+ data (const xml_schema::string& d)
+ : data_base (d), scope_present_ (false)
+ {
+ }
+
+ data::
+ data (const xercesc::DOMElement& e,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : data_base (e, f, c), scope_present_ (false)
+ {
+ // Check if we've got the scope attribute.
+ //
+ namespace xml = xsd::cxx::xml;
+ xml::string name ("scope");
+
+ if (e.hasAttribute (name.c_str ()))
+ {
+ scope (xml::transcode<char> (e.getAttribute (name.c_str ())));
+ }
+ }
+
+ data::
+ data (const data& d,
+ xml_schema::flags f,
+ xml_schema::container* c)
+ : data_base (d, f, c),
+ scope_present_ (d.scope_present_),
+ scope_ (d.scope_)
+ {
+ }
+
+ data* data::
+ _clone (xml_schema::flags f, xml_schema::container* c) const
+ {
+ return new data (*this, f, c);
+ }
+
+ void
+ operator<< (xercesc::DOMElement& e, const data& x)
+ {
+ // Use our base to serialize data and id.
+ //
+ const data_base& b (x);
+ e << b;
+
+ // Add the scope attribute if present.
+ //
+ if (x.scope_present ())
+ {
+ namespace xml = xsd::cxx::xml;
+ xml::string name ("scope");
+ xml::string value (x.scope ());
+
+ e.setAttribute (name.c_str (), value.c_str ());
+ }
+ }
+
+ std::ostream&
+ operator<< (std::ostream& os, const data& x)
+ {
+ // Use our base to print date and id.
+ //
+ const data_base& b (x);
+ os << b;
+
+ if (x.scope_present ())
+ os << std::endl << "scope: " << x.scope ();
+
+ return os;
+ }
+}
diff --git a/examples/cxx/tree/custom/wildcard/wildcard-custom.hxx b/examples/cxx/tree/custom/wildcard/wildcard-custom.hxx
new file mode 100644
index 0000000..2c58cc8
--- /dev/null
+++ b/examples/cxx/tree/custom/wildcard/wildcard-custom.hxx
@@ -0,0 +1,67 @@
+// file : examples/cxx/tree/custom/wildcard/wildcard-custom.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Do not include this file directly, use wildcard.hxx instead. This
+// file is included into generated wildcard.hxx so we do not need to
+// guard against multiple inclusions.
+//
+
+namespace wildcard
+{
+ class data: public data_base
+ {
+ // Standard constructors.
+ //
+ public:
+ data (const xml_schema::string&);
+
+ data (const xercesc::DOMElement&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ data (const data&,
+ xml_schema::flags = 0,
+ xml_schema::container* = 0);
+
+ virtual data*
+ _clone (xml_schema::flags = 0,
+ xml_schema::container* = 0) const;
+
+ // Our customizations.
+ //
+ public:
+ bool
+ scope_present () const
+ {
+ return scope_present_;
+ }
+
+ const xml_schema::string&
+ scope () const
+ {
+ return scope_;
+ }
+
+ void
+ scope (const xml_schema::string& s)
+ {
+ scope_present_ = true;
+ scope_ = s;
+ }
+
+ private:
+ bool scope_present_;
+ xml_schema::string scope_;
+ };
+
+ // Serialization operator.
+ //
+ void
+ operator<< (xercesc::DOMElement&, const data&);
+
+ // std::ostream insertion operator.
+ //
+ std::ostream&
+ operator<< (std::ostream&, const data&);
+}
diff --git a/examples/cxx/tree/custom/wildcard/wildcard.xml b/examples/cxx/tree/custom/wildcard/wildcard.xml
new file mode 100644
index 0000000..c980193
--- /dev/null
+++ b/examples/cxx/tree/custom/wildcard/wildcard.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/wildcard/wildcard.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<wc:data xmlns:wc="http://www.codesynthesis.com/wildcard"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/wildcard wildcard.xsd"
+ id="1"
+ scope="global">abc123</wc:data>
diff --git a/examples/cxx/tree/custom/wildcard/wildcard.xsd b/examples/cxx/tree/custom/wildcard/wildcard.xsd
new file mode 100644
index 0000000..ccce30b
--- /dev/null
+++ b/examples/cxx/tree/custom/wildcard/wildcard.xsd
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/custom/wildcard/wildcard.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:wc="http://www.codesynthesis.com/wildcard"
+ targetNamespace="http://www.codesynthesis.com/wildcard">
+
+ <xsd:complexType name="data">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="id" type="xsd:unsignedInt"/>
+ <xsd:anyAttribute namespace="##any" processContents="skip"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:element name="data" type="wc:data"/>
+
+</xsd:schema>
diff --git a/examples/cxx/tree/dbxml/README b/examples/cxx/tree/dbxml/README
new file mode 100644
index 0000000..59e67d0
--- /dev/null
+++ b/examples/cxx/tree/dbxml/README
@@ -0,0 +1,45 @@
+This example shows how to use the C++/Tree mapping on top of the Berkeley
+DB XML embedded XML database. This example is described in detail in the
+"C++/Tree Mapping and Berkeley DB XML Integration Guide" which can be
+found in the documentation/cxx/tree/dbxml directory of the XSD
+distribution.
+
+You will need the Berkeley DB XML libraries[1] installed in order to build
+and run this example. The makefiles and project files for this example link
+to the DB XML library names corresponding to version 2.3.X. Earlier and later
+versions can also be used but may require adjustments to the library names
+being linked to.
+
+Note that due to the incomplete DOM API implementation provided by DB
+XML (as of version 2.3.10), the generated code and your application
+should be compiled with the DBXML_DOM macro defined in order to avoid
+using unsupported parts of the API.
+
+The example consists of the following files:
+
+library.xsd
+ XML Schema which describes a library of books.
+
+library.hxx
+library.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 library.xsd.
+
+driver.cxx
+ Driver for the example. It performs the following four operations on
+ the database:
+
+ * Create a new document in DB from an object model
+ * Create an object model from a document in DB
+ * Create an object model from a document fragment in DB
+ * Update a document fragment in DB from an object model
+
+
+To run the example simply execute:
+
+$ ./driver
+
+
+[1] http://www.sleepycat.com/products/bdbxml.html
diff --git a/examples/cxx/tree/dbxml/driver.cxx b/examples/cxx/tree/dbxml/driver.cxx
new file mode 100644
index 0000000..56cbb4a
--- /dev/null
+++ b/examples/cxx/tree/dbxml/driver.cxx
@@ -0,0 +1,175 @@
+// file : examples/cxx/tree/dbxml/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <string>
+#include <cassert>
+#include <iostream>
+
+#include <dbxml/DbXml.hpp>
+
+#include "library.hxx"
+
+using std::cerr;
+using std::endl;
+using std::string;
+using std::auto_ptr;
+
+using namespace DbXml;
+using namespace xsd::cxx; // for xml::string
+
+void
+print_document (const string& desc,
+ XmlContainer container,
+ const string& name)
+{
+ XmlDocument doc (container.getDocument (name));
+
+ string content;
+ doc.getContent (content);
+
+ cerr << endl
+ << desc << endl
+ << content << endl;
+}
+
+int
+main ()
+{
+ try
+ {
+ using namespace library;
+ using xml_schema::date;
+
+ XmlManager manager;
+
+ {
+ XmlContainer container (manager.createContainer ("new.bdbxml"));
+
+ XmlUpdateContext update_context (manager.createUpdateContext ());
+
+ XmlQueryContext context (manager.createQueryContext ());
+ context.setNamespace ("lib", "http://www.codesynthesis.com/library");
+
+
+ // Create a new document from an object model.
+ //
+ {
+ // Create a new catalog with one book.
+ //
+ catalog c;
+
+ book b (20530902, // ISBN
+ "The Elements of Style", // Title
+ genre::reference, // Genre
+ "ES"); // ID
+
+ author strunk ("William Strunk, Jr.", date (1869, 7, 1));
+ strunk.died (date (1946, 9, 26));
+
+ b.author ().push_back (strunk);
+ c.book ().push_back (b);
+
+
+ // Create a new XML document.
+ //
+ XmlDocument doc (manager.createDocument ());
+ doc.setName ("new.xml");
+
+
+ // Obtain its DOM representation and add the root element.
+ //
+ xercesc::DOMDocument& dom_doc (*doc.getContentAsDOM ());
+
+ dom_doc.appendChild (
+ dom_doc.createElementNS (
+ xml::string ("http://www.codesynthesis.com/library").c_str (),
+ xml::string ("lib:catalog").c_str ()));
+
+
+ // Serialize the object model to the XML document. Also avoid
+ // re-initializing the Xerces-C++ runtime since XmlManager has
+ // it initialized.
+ //
+ catalog_ (dom_doc, c, xml_schema::flags::dont_initialize);
+
+
+ // Place the document into the container.
+ //
+ container.putDocument (doc, update_context);
+
+ print_document ("after create:", container, "new.xml");
+ }
+
+ // Create an object model from a document in DB.
+ //
+ {
+ // Resolve the document in the container.
+ //
+ XmlDocument doc (container.getDocument ("new.xml"));
+
+
+ // Create the object model from the document's DOM. Also avoid
+ // re-initializing the Xerces-C++ runtime since XmlManager has
+ // it initialized.
+ //
+ auto_ptr<catalog> c (catalog_ (*doc.getContentAsDOM (),
+ xml_schema::flags::dont_initialize));
+
+ cerr << *c << endl;
+ }
+
+
+ // Lookup a document fragment.
+ //
+
+ string query ("collection('new.bdbxml')/lib:catalog/book[@id='ES']");
+
+ // Find "The Elements of Style".
+ //
+ XmlValue v;
+ XmlResults results (manager.query (query, context));
+
+ if (results.next (v))
+ {
+ // Create an object model from the document fragment.
+ //
+ auto_ptr<book> b (
+ new book (
+ *static_cast<xercesc::DOMElement*> (v.asNode ())));
+
+ cerr << *b << endl;
+
+
+ // Add another author, change the availability status.
+ //
+ author white ("E.B. White", date (1899, 7, 11));
+ white.died (date (1985, 10, 1));
+
+ b->author ().push_back (white);
+ b->available (false);
+
+
+ // Update the document fragment from the object model.
+ //
+ *static_cast<xercesc::DOMElement*> (v.asNode ()) << *b;
+
+
+ // Update the document in the container.
+ //
+ XmlDocument doc (v.asDocument ());
+ container.updateDocument (doc, update_context);
+ }
+
+ print_document ("after update:", container, "new.xml");
+ }
+
+ manager.removeContainer ("new.bdbxml");
+ }
+ catch (const std::exception& e)
+ {
+ cerr << e.what () << endl;
+ return 1;
+ }
+}
diff --git a/examples/cxx/tree/dbxml/library.xsd b/examples/cxx/tree/dbxml/library.xsd
new file mode 100644
index 0000000..c71c312
--- /dev/null
+++ b/examples/cxx/tree/dbxml/library.xsd
@@ -0,0 +1,75 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/dbxml/library.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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:enumeration value="reference"/>
+ </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/examples/cxx/tree/dbxml/makefile b/examples/cxx/tree/dbxml/makefile
new file mode 100644
index 0000000..2a5ba4e
--- /dev/null
+++ b/examples/cxx/tree/dbxml/makefile
@@ -0,0 +1,76 @@
+# file : examples/cxx/tree/dbxml/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := library.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+$(call import,\
+ $(scf_root)/import/libdbxml/stub.make,\
+ l: dbxml.l,cpp-options: dbxml.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l) $(dbxml.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd -DDBXML_DOM
+$(obj) $(dep): $(xerces_c.l.cpp-options) $(dbxml.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-serialization \
+ --generate-ostream
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/hello/README b/examples/cxx/tree/hello/README
new file mode 100644
index 0000000..bb98584
--- /dev/null
+++ b/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/examples/cxx/tree/hello/driver.cxx b/examples/cxx/tree/hello/driver.cxx
new file mode 100644
index 0000000..6ea6823
--- /dev/null
+++ b/examples/cxx/tree/hello/driver.cxx
@@ -0,0 +1,37 @@
+// file : examples/cxx/tree/hello/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_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
+ {
+ auto_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/examples/cxx/tree/hello/hello.xml b/examples/cxx/tree/hello/hello.xml
new file mode 100644
index 0000000..bcde610
--- /dev/null
+++ b/examples/cxx/tree/hello/hello.xml
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/hello/hello.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/hello/hello.xsd b/examples/cxx/tree/hello/hello.xsd
new file mode 100644
index 0000000..e8f5147
--- /dev/null
+++ b/examples/cxx/tree/hello/hello.xsd
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/hello/hello.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="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/examples/cxx/tree/hello/makefile b/examples/cxx/tree/hello/makefile
new file mode 100644
index 0000000..95288f5
--- /dev/null
+++ b/examples/cxx/tree/hello/makefile
@@ -0,0 +1,71 @@
+# file : examples/cxx/tree/hello/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := hello.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options :=
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/library/README b/examples/cxx/tree/library/README
new file mode 100644
index 0000000..960d1d4
--- /dev/null
+++ b/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 to use the ID/IDREF cross-referencing
+mechanism and the xsd:enumeration to C++ enum mapping.
diff --git a/examples/cxx/tree/library/driver.cxx b/examples/cxx/tree/library/driver.cxx
new file mode 100644
index 0000000..ae68b87
--- /dev/null
+++ b/examples/cxx/tree/library/driver.cxx
@@ -0,0 +1,131 @@
+// file : examples/cxx/tree/library/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_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::auto_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/examples/cxx/tree/library/library.xml b/examples/cxx/tree/library/library.xml
new file mode 100644
index 0000000..e9acb75
--- /dev/null
+++ b/examples/cxx/tree/library/library.xml
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/library/library.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/library/library.xsd b/examples/cxx/tree/library/library.xsd
new file mode 100644
index 0000000..baf2221
--- /dev/null
+++ b/examples/cxx/tree/library/library.xsd
@@ -0,0 +1,73 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/library/library.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/library/makefile b/examples/cxx/tree/library/makefile
new file mode 100644
index 0000000..ceecbb2
--- /dev/null
+++ b/examples/cxx/tree/library/makefile
@@ -0,0 +1,73 @@
+# file : examples/cxx/tree/library/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := library.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-inline \
+ --generate-ostream \
+ --generate-serialization
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/makefile b/examples/cxx/tree/makefile
new file mode 100644
index 0000000..7866b33
--- /dev/null
+++ b/examples/cxx/tree/makefile
@@ -0,0 +1,27 @@
+# file : examples/cxx/tree/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make
+
+examples := binary caching custom hello library messaging mixed multiroot \
+performance polymorphism streaming wildcard
+
+ifeq ($(xsd_with_dbxml),y)
+examples += dbxml
+endif
+
+ifeq ($(xsd_with_xqilla),y)
+examples += xpath
+endif
+
+default := $(out_base)/
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(examples)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(examples)))
+
+$(foreach e,$(examples),$(call import,$(src_base)/$e/makefile))
diff --git a/examples/cxx/tree/messaging/README b/examples/cxx/tree/messaging/README
new file mode 100644
index 0000000..435a4cf
--- /dev/null
+++ b/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/examples/cxx/tree/messaging/balance.xml b/examples/cxx/tree/messaging/balance.xml
new file mode 100644
index 0000000..57eeaed
--- /dev/null
+++ b/examples/cxx/tree/messaging/balance.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/messaging/balance.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/messaging/deposit.xml b/examples/cxx/tree/messaging/deposit.xml
new file mode 100644
index 0000000..9da3c59
--- /dev/null
+++ b/examples/cxx/tree/messaging/deposit.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/messaging/deposit.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/messaging/dom-parse.cxx b/examples/cxx/tree/messaging/dom-parse.cxx
new file mode 100644
index 0000000..d6ce204
--- /dev/null
+++ b/examples/cxx/tree/messaging/dom-parse.cxx
@@ -0,0 +1,118 @@
+// file : examples/cxx/tree/messaging/dom-parse.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include "dom-parse.hxx"
+
+#include <istream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_*
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+using namespace xercesc;
+namespace xml = xsd::cxx::xml;
+namespace tree = xsd::cxx::tree;
+
+xml::dom::auto_ptr<DOMDocument>
+parse (std::istream& is, const std::string& id, bool validate)
+{
+ const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+#if _XERCES_VERSION >= 30000
+
+ // Xerces-C++ 3.0.0 and later.
+ //
+ xml::dom::auto_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable/Disable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, validate);
+ conf->setParameter (XMLUni::fgXercesSchema, validate);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ // Set error handler.
+ //
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+#else // _XERCES_VERSION >= 30000
+
+ // Same as above but for Xerces-C++ 2 series.
+ //
+ xml::dom::auto_ptr<DOMBuilder> parser (
+ impl->createDOMBuilder (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ parser->setFeature (XMLUni::fgDOMComments, false);
+ parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
+ parser->setFeature (XMLUni::fgDOMEntities, false);
+ parser->setFeature (XMLUni::fgDOMNamespaces, true);
+ parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false);
+ parser->setFeature (XMLUni::fgDOMValidation, validate);
+ parser->setFeature (XMLUni::fgXercesSchema, validate);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ parser->setErrorHandler (&ehp);
+
+#endif // _XERCES_VERSION >= 30000
+
+ // Prepare input stream.
+ //
+ xml::sax::std_input_source isrc (is, id);
+ Wrapper4InputSource wrap (&isrc, false);
+
+#if _XERCES_VERSION >= 30000
+ xml::dom::auto_ptr<DOMDocument> doc (parser->parse (&wrap));
+#else
+ xml::dom::auto_ptr<DOMDocument> doc (parser->parse (wrap));
+#endif
+
+ eh.throw_if_failed<tree::parsing<char> > ();
+
+ return doc;
+}
diff --git a/examples/cxx/tree/messaging/dom-parse.hxx b/examples/cxx/tree/messaging/dom-parse.hxx
new file mode 100644
index 0000000..640b28a
--- /dev/null
+++ b/examples/cxx/tree/messaging/dom-parse.hxx
@@ -0,0 +1,23 @@
+// file : examples/cxx/tree/messaging/dom-parse.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef DOM_PARSE
+#define DOM_PARSE
+
+#include <string>
+#include <iosfwd>
+
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+
+// Parse an XML document from the standard input stream with an
+// optional resource id. Resource id is used in diagnostics as
+// well as to locate schemas referenced from inside the document.
+//
+xsd::cxx::xml::dom::auto_ptr<xercesc::DOMDocument>
+parse (std::istream& is,
+ const std::string& id,
+ bool validate);
+
+#endif // DOM_PARSE
diff --git a/examples/cxx/tree/messaging/dom-serialize.cxx b/examples/cxx/tree/messaging/dom-serialize.cxx
new file mode 100644
index 0000000..c0f4311
--- /dev/null
+++ b/examples/cxx/tree/messaging/dom-serialize.cxx
@@ -0,0 +1,89 @@
+// file : examples/cxx/tree/messaging/dom-serialize.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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);
+
+#if _XERCES_VERSION >= 30000
+
+ // Create a DOMSerializer.
+ //
+ xml::dom::auto_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);
+
+ xml::dom::auto_ptr<DOMLSOutput> out (impl->createLSOutput ());
+ out->setEncoding (xml::string (encoding).c_str ());
+ out->setByteStream (&oft);
+
+ writer->write (&doc, out.get ());
+
+#else
+
+ // Create a DOMWriter.
+ //
+ xml::dom::auto_ptr<DOMWriter> writer (impl->createDOMWriter ());
+
+ // Set error handler.
+ //
+ writer->setErrorHandler (&ehp);
+
+ // Set encoding.
+ //
+ writer->setEncoding(xml::string (encoding).c_str ());
+
+ // Set some generally nice features.
+ //
+ writer->setFeature (XMLUni::fgDOMWRTDiscardDefaultContent, true);
+ writer->setFeature (XMLUni::fgDOMWRTFormatPrettyPrint, true);
+
+ writer->writeNode (&oft, doc);
+
+#endif
+
+ eh.throw_if_failed<tree::serialization<char> > ();
+}
diff --git a/examples/cxx/tree/messaging/dom-serialize.hxx b/examples/cxx/tree/messaging/dom-serialize.hxx
new file mode 100644
index 0000000..1a7e855
--- /dev/null
+++ b/examples/cxx/tree/messaging/dom-serialize.hxx
@@ -0,0 +1,21 @@
+// file : examples/cxx/tree/messaging/dom-serialize.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/tree/messaging/driver.cxx b/examples/cxx/tree/messaging/driver.cxx
new file mode 100644
index 0000000..4c36aa4
--- /dev/null
+++ b/examples/cxx/tree/messaging/driver.cxx
@@ -0,0 +1,145 @@
+// file : examples/cxx/tree/messaging/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_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]);
+
+ auto_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::auto_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::auto_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/examples/cxx/tree/messaging/makefile b/examples/cxx/tree/messaging/makefile
new file mode 100644
index 0000000..2f4c7fe
--- /dev/null
+++ b/examples/cxx/tree/messaging/makefile
@@ -0,0 +1,72 @@
+# file : examples/cxx/tree/messaging/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := protocol.xsd
+cxx := driver.cxx dom-parse.cxx dom-serialize.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --root-element-all \
+--generate-element-type --generate-element-map --generate-serialization
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/messaging/protocol.xsd b/examples/cxx/tree/messaging/protocol.xsd
new file mode 100644
index 0000000..3461133
--- /dev/null
+++ b/examples/cxx/tree/messaging/protocol.xsd
@@ -0,0 +1,54 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/messaging/protocol.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/messaging/withdraw.xml b/examples/cxx/tree/messaging/withdraw.xml
new file mode 100644
index 0000000..16a7440
--- /dev/null
+++ b/examples/cxx/tree/messaging/withdraw.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/messaging/withdraw.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/mixed/README b/examples/cxx/tree/mixed/README
new file mode 100644
index 0000000..c6f8be7
--- /dev/null
+++ b/examples/cxx/tree/mixed/README
@@ -0,0 +1,38 @@
+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.
+
+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/examples/cxx/tree/mixed/driver.cxx b/examples/cxx/tree/mixed/driver.cxx
new file mode 100644
index 0000000..d905421
--- /dev/null
+++ b/examples/cxx/tree/mixed/driver.cxx
@@ -0,0 +1,121 @@
+// file : examples/cxx/tree/mixed/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+
+#include "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::auto_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
+ {
+ auto_ptr<text> t (
+ text_ (argv[1],
+ xml_schema::flags::keep_dom |
+ xml_schema::flags::dont_initialize));
+
+ // Note that DOM association is preserved in copies but only if they
+ // are "complete", i.e., made from the root of the tree.
+ //
+ text copy (*t);
+
+ // 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/examples/cxx/tree/mixed/makefile b/examples/cxx/tree/mixed/makefile
new file mode 100644
index 0000000..cc81bca
--- /dev/null
+++ b/examples/cxx/tree/mixed/makefile
@@ -0,0 +1,73 @@
+# file : examples/cxx/tree/mixed/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := text.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options :=
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/mixed/text.xml b/examples/cxx/tree/mixed/text.xml
new file mode 100644
index 0000000..69abe8f
--- /dev/null
+++ b/examples/cxx/tree/mixed/text.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/text/text.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/mixed/text.xsd b/examples/cxx/tree/mixed/text.xsd
new file mode 100644
index 0000000..8aa8280
--- /dev/null
+++ b/examples/cxx/tree/mixed/text.xsd
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/mixed/text.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="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/examples/cxx/tree/multiroot/README b/examples/cxx/tree/multiroot/README
new file mode 100644
index 0000000..b742422
--- /dev/null
+++ b/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/examples/cxx/tree/multiroot/balance.xml b/examples/cxx/tree/multiroot/balance.xml
new file mode 100644
index 0000000..055546a
--- /dev/null
+++ b/examples/cxx/tree/multiroot/balance.xml
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/multiroot/balance.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/multiroot/deposit.xml b/examples/cxx/tree/multiroot/deposit.xml
new file mode 100644
index 0000000..3207eee
--- /dev/null
+++ b/examples/cxx/tree/multiroot/deposit.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/multiroot/deposit.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/multiroot/dom-parse.cxx b/examples/cxx/tree/multiroot/dom-parse.cxx
new file mode 100644
index 0000000..3a67626
--- /dev/null
+++ b/examples/cxx/tree/multiroot/dom-parse.cxx
@@ -0,0 +1,118 @@
+// file : examples/cxx/tree/multiroot/dom-parse.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include "dom-parse.hxx"
+
+#include <istream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_*
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+using namespace xercesc;
+namespace xml = xsd::cxx::xml;
+namespace tree = xsd::cxx::tree;
+
+xml::dom::auto_ptr<DOMDocument>
+parse (std::istream& is, const std::string& id, bool validate)
+{
+ const XMLCh ls_id [] = {chLatin_L, chLatin_S, chNull};
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+#if _XERCES_VERSION >= 30000
+
+ // Xerces-C++ 3.0.0 and later.
+ //
+ xml::dom::auto_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable/Disable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, validate);
+ conf->setParameter (XMLUni::fgXercesSchema, validate);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ // Set error handler.
+ //
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+#else // _XERCES_VERSION >= 30000
+
+ // Same as above but for Xerces-C++ 2 series.
+ //
+ xml::dom::auto_ptr<DOMBuilder> parser (
+ impl->createDOMBuilder (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ parser->setFeature (XMLUni::fgDOMComments, false);
+ parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
+ parser->setFeature (XMLUni::fgDOMEntities, false);
+ parser->setFeature (XMLUni::fgDOMNamespaces, true);
+ parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false);
+ parser->setFeature (XMLUni::fgDOMValidation, validate);
+ parser->setFeature (XMLUni::fgXercesSchema, validate);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ parser->setErrorHandler (&ehp);
+
+#endif // _XERCES_VERSION >= 30000
+
+ // Prepare input stream.
+ //
+ xml::sax::std_input_source isrc (is, id);
+ Wrapper4InputSource wrap (&isrc, false);
+
+#if _XERCES_VERSION >= 30000
+ xml::dom::auto_ptr<DOMDocument> doc (parser->parse (&wrap));
+#else
+ xml::dom::auto_ptr<DOMDocument> doc (parser->parse (wrap));
+#endif
+
+ eh.throw_if_failed<tree::parsing<char> > ();
+
+ return doc;
+}
diff --git a/examples/cxx/tree/multiroot/dom-parse.hxx b/examples/cxx/tree/multiroot/dom-parse.hxx
new file mode 100644
index 0000000..c3bbf71
--- /dev/null
+++ b/examples/cxx/tree/multiroot/dom-parse.hxx
@@ -0,0 +1,23 @@
+// file : examples/cxx/tree/multiroot/dom-parse.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef DOM_PARSE
+#define DOM_PARSE
+
+#include <string>
+#include <iosfwd>
+
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+
+// Parse an XML document from the standard input stream with an
+// optional resource id. Resource id is used in diagnostics as
+// well as to locate schemas referenced from inside the document.
+//
+xsd::cxx::xml::dom::auto_ptr<xercesc::DOMDocument>
+parse (std::istream& is,
+ const std::string& id,
+ bool validate);
+
+#endif // DOM_PARSE
diff --git a/examples/cxx/tree/multiroot/driver.cxx b/examples/cxx/tree/multiroot/driver.cxx
new file mode 100644
index 0000000..cd5be34
--- /dev/null
+++ b/examples/cxx/tree/multiroot/driver.cxx
@@ -0,0 +1,125 @@
+// file : examples/cxx/tree/multiroot/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_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.
+//
+auto_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::auto_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 ()));
+
+ auto_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]);
+
+ auto_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/examples/cxx/tree/multiroot/makefile b/examples/cxx/tree/multiroot/makefile
new file mode 100644
index 0000000..37e2722
--- /dev/null
+++ b/examples/cxx/tree/multiroot/makefile
@@ -0,0 +1,71 @@
+# file : examples/cxx/tree/multiroot/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := protocol.xsd
+cxx := driver.cxx dom-parse.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --root-element-all
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/multiroot/protocol.xsd b/examples/cxx/tree/multiroot/protocol.xsd
new file mode 100644
index 0000000..28e8478
--- /dev/null
+++ b/examples/cxx/tree/multiroot/protocol.xsd
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/multiroot/protocol.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/multiroot/withdraw.xml b/examples/cxx/tree/multiroot/withdraw.xml
new file mode 100644
index 0000000..4df736f
--- /dev/null
+++ b/examples/cxx/tree/multiroot/withdraw.xml
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/multiroot/withdraw.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/performance/README b/examples/cxx/tree/performance/README
new file mode 100644
index 0000000..440ee62
--- /dev/null
+++ b/examples/cxx/tree/performance/README
@@ -0,0 +1,60 @@
+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-5k.xml
+test-50k.xml
+test-500k.xml
+ Test XML documents of various sizes.
+
+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-500k.xml
diff --git a/examples/cxx/tree/performance/driver.cxx b/examples/cxx/tree/performance/driver.cxx
new file mode 100644
index 0000000..f3e388b
--- /dev/null
+++ b/examples/cxx/tree/performance/driver.cxx
@@ -0,0 +1,91 @@
+// file : examples/cxx/tree/performance/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/tree/performance/gen.cxx b/examples/cxx/tree/performance/gen.cxx
new file mode 100644
index 0000000..b6392c0
--- /dev/null
+++ b/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/examples/cxx/tree/performance/makefile b/examples/cxx/tree/performance/makefile
new file mode 100644
index 0000000..f60e281
--- /dev/null
+++ b/examples/cxx/tree/performance/makefile
@@ -0,0 +1,72 @@
+# file : examples/cxx/tree/performance/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx parsing.cxx serialization.cxx time.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--generate-inline --generate-serialization
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/performance/parsing.cxx b/examples/cxx/tree/performance/parsing.cxx
new file mode 100644
index 0000000..fd27fb2
--- /dev/null
+++ b/examples/cxx/tree/performance/parsing.cxx
@@ -0,0 +1,200 @@
+// file : examples/cxx/tree/performance/parsing.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <cstddef> // std::size_t
+#include <fstream>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#if _XERCES_VERSION >= 30000
+# include <xercesc/dom/DOMLSParser.hpp>
+#else
+# include <xercesc/dom/DOMBuilder.hpp>
+#endif
+#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);
+
+ std::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);
+
+#if _XERCES_VERSION >= 30000
+
+ xml_schema::dom::auto_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);
+
+ // If we are validating, pre-load and cache the schema.
+ //
+ parser->loadGrammar ("test.xsd", Grammar::SchemaGrammarType, true);
+ conf->setParameter (XMLUni::fgXercesUseCachedGrammarInParse, true);
+ }
+ else
+ {
+ conf->setParameter (XMLUni::fgDOMValidate, false);
+ conf->setParameter (XMLUni::fgXercesSchema, false);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+#else // _XERCES_VERSION >= 30000
+
+ // Same as above but for Xerces-C++ 2 series.
+ //
+ xml_schema::dom::auto_ptr<DOMBuilder> parser (
+ impl->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ parser->setFeature (XMLUni::fgDOMComments, false);
+ parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
+ parser->setFeature (XMLUni::fgDOMEntities, false);
+ parser->setFeature (XMLUni::fgDOMNamespaces, true);
+ parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false);
+
+ parser->setErrorHandler (&ehp);
+
+ if (validate)
+ {
+ parser->setFeature (XMLUni::fgDOMValidation, true);
+ parser->setFeature (XMLUni::fgXercesSchema, true);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+
+ parser->loadGrammar ("test.xsd", Grammar::SchemaGrammarType, true);
+ parser->setFeature (XMLUni::fgXercesUseCachedGrammarInParse, true);
+ }
+ else
+ {
+ parser->setFeature (XMLUni::fgDOMValidation, false);
+ parser->setFeature (XMLUni::fgXercesSchema, false);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+
+ parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+#endif
+
+ // 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.
+ //
+#if _XERCES_VERSION >= 30000
+ xml_schema::dom::auto_ptr<DOMDocument> doc (parser->parse (&wis));
+#else
+ xml_schema::dom::auto_ptr<DOMDocument> doc (parser->parse (wis));
+#endif
+ eh.throw_if_failed<xml_schema::parsing> ();
+
+ // Then parse DOM to the object model.
+ //
+ auto_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/examples/cxx/tree/performance/serialization.cxx b/examples/cxx/tree/performance/serialization.cxx
new file mode 100644
index 0000000..5ad6654
--- /dev/null
+++ b/examples/cxx/tree/performance/serialization.cxx
@@ -0,0 +1,151 @@
+// file : examples/cxx/tree/performance/serialization.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <cstddef> // std::size_t
+#include <sstream>
+#include <iostream>
+
+#include <xercesc/dom/DOM.hpp>
+#if _XERCES_VERSION >= 30000
+# include <xercesc/dom/DOMLSOutput.hpp>
+# include <xercesc/dom/DOMLSSerializer.hpp>
+#else
+# include <xercesc/dom/DOMWriter.hpp>
+#endif
+#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.
+ //
+ auto_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);
+
+ std::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);
+
+#if _XERCES_VERSION >= 30000
+ xml_schema::dom::auto_ptr<DOMLSSerializer> writer (
+ impl->createLSSerializer ());
+
+ DOMConfiguration* conf (writer->getDomConfig ());
+
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+ conf->setParameter (XMLUni::fgDOMXMLDeclaration, false);
+
+ xml_schema::dom::auto_ptr<DOMLSOutput> out (impl->createLSOutput ());
+
+ out->setByteStream (&ft);
+#else
+ // Same as above but for Xerces-C++ 2 series.
+ //
+ xml_schema::dom::auto_ptr<DOMWriter> writer (impl->createDOMWriter ());
+
+ writer->setErrorHandler (&ehp);
+ writer->setFeature (XMLUni::fgDOMXMLDeclaration, false);
+#endif
+
+ // Serialization loop.
+ //
+ os::time start;
+
+ for (unsigned long i (0); i < iter; ++i)
+ {
+ // First serialize the object model to DOM.
+ //
+ xml_schema::dom::auto_ptr<DOMDocument> doc (test::root_ (*r, map));
+
+ ft.reset ();
+
+ // Then serialize DOM to XML reusing the serializer we created above.
+ //
+#if _XERCES_VERSION >= 30000
+ writer->write (doc.get (), out.get ());
+#else
+ writer->writeNode (&ft, *doc);
+#endif
+
+ eh.throw_if_failed<xml_schema::parsing> ();
+ }
+
+ 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/examples/cxx/tree/performance/test-500k.xml b/examples/cxx/tree/performance/test-500k.xml
new file mode 100644
index 0000000..e895584
--- /dev/null
+++ b/examples/cxx/tree/performance/test-500k.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><record orange="317"><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="318" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="319"><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="320" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="321"><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="322" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="323"><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="324" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="325"><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="326" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="327"><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="328" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="329"><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="330" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="331"><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="332" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="333"><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="334" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="335"><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="336" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="337"><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="338" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="339"><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="340" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="341"><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="342" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="343"><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="344" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="345"><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="346" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="347"><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="348" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="349"><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="350" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="351"><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="352" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="353"><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="354" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="355"><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="356" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="357"><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="358" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="359"><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="360" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="361"><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="362" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="363"><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="364" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="365"><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="366" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="367"><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="368" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="369"><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="370" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="371"><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="372" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="373"><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="374" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="375"><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="376" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="377"><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="378" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="379"><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="380" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="381"><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="382" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="383"><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="384" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="385"><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="386" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="387"><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="388" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="389"><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="390" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="391"><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="392" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="393"><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="394" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="395"><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="396" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="397"><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="398" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="399"><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="400" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="401"><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="402" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="403"><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="404" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="405"><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="406" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="407"><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="408" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="409"><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="410" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="411"><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="412" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="413"><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="414" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="415"><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="416" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="417"><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="418" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="419"><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="420" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="421"><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="422" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="423"><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="424" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="425"><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="426" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="427"><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="428" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="429"><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="430" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="431"><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="432" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="433"><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="434" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="435"><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="436" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="437"><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="438" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="439"><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="440" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="441"><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="442" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="443"><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="444" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="445"><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="446" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="447"><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="448" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="449"><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="450" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="451"><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="452" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="453"><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="454" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="455"><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="456" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="457"><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="458" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="459"><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="460" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="461"><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="462" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="463"><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="464" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="465"><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="466" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="467"><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="468" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="469"><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="470" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="471"><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="472" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="473"><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="474" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="475"><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="476" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="477"><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="478" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="479"><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="480" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="481"><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="482" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="483"><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="484" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="485"><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="486" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="487"><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="488" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="489"><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="490" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="491"><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="492" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="493"><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="494" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="495"><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="496" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="497"><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="498" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="499"><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="500" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="501"><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="502" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="503"><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="504" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="505"><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="506" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="507"><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="508" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="509"><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="510" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="511"><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="512" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="513"><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="514" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="515"><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="516" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="517"><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="518" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="519"><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="520" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="521"><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="522" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="523"><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="524" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="525"><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="526" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="527"><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="528" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="529"><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="530" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="531"><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="532" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="533"><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="534" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="535"><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="536" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="537"><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="538" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="539"><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="540" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="541"><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="542" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="543"><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="544" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="545"><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="546" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="547"><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="548" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="549"><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="550" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="551"><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="552" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="553"><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="554" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="555"><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="556" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="557"><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="558" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="559"><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="560" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="561"><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="562" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="563"><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="564" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="565"><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="566" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="567"><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="568" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="569"><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="570" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="571"><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="572" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="573"><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="574" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="575"><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="576" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="577"><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="578" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="579"><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="580" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="581"><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="582" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="583"><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="584" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="585"><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="586" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="587"><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="588" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="589"><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="590" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="591"><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="592" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="593"><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="594" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="595"><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="596" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="597"><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="598" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="599"><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="600" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="601"><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="602" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="603"><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="604" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="605"><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="606" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="607"><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="608" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="609"><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="610" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="611"><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="612" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="613"><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="614" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="615"><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="616" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="617"><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="618" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="619"><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="620" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="621"><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="622" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="623"><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="624" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="625"><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="626" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="627"><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="628" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="629"><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="630" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="631"><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="632" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="633"><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="634" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="635"><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="636" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="637"><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="638" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="639"><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="640" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="641"><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="642" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="643"><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="644" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="645"><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="646" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="647"><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="648" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="649"><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="650" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="651"><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="652" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="653"><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="654" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="655"><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="656" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="657"><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="658" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="659"><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="660" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="661"><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="662" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="663"><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="664" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="665"><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="666" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="667"><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="668" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="669"><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="670" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="671"><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="672" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="673"><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="674" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="675"><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="676" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="677"><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="678" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="679"><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="680" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="681"><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="682" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="683"><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="684" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="685"><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="686" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="687"><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="688" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="689"><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="690" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="691"><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="692" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="693"><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="694" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="695"><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="696" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="697"><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="698" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="699"><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="700" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="701"><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="702" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="703"><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="704" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="705"><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="706" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="707"><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="708" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="709"><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="710" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="711"><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="712" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="713"><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="714" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="715"><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="716" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="717"><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="718" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="719"><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="720" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="721"><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="722" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="723"><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="724" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="725"><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="726" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="727"><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="728" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="729"><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="730" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="731"><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="732" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="733"><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="734" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="735"><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="736" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="737"><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="738" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="739"><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="740" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="741"><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="742" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="743"><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="744" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="745"><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="746" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="747"><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="748" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="749"><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="750" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="751"><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="752" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="753"><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="754" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="755"><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="756" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="757"><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="758" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="759"><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="760" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="761"><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="762" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="763"><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="764" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="765"><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="766" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="767"><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="768" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="769"><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="770" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="771"><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="772" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="773"><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="774" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="775"><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="776" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="777"><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="778" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="779"><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="780" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="781"><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="782" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="783"><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="784" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="785"><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="786" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="787"><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="788" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="789"><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="790" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="791"><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="792" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="793"><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="794" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="795"><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="796" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="797"><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="798" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="799"><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="800" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="801"><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="802" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="803"><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="804" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="805"><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="806" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="807"><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="808" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="809"><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="810" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="811"><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="812" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="813"><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="814" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="815"><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="816" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="817"><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="818" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="819"><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="820" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="821"><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="822" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="823"><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="824" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="825"><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="826" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="827"><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="828" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="829"><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="830" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="831"><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="832" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="833"><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="834" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="835"><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="836" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="837"><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="838" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="839"><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="840" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="841"><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="842" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="843"><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="844" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="845"><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="846" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="847"><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="848" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="849"><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="850" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="851"><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="852" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="853"><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="854" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="855"><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="856" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="857"><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="858" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="859"><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="860" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="861"><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="862" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="863"><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="864" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="865"><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="866" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="867"><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="868" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="869"><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="870" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="871"><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="872" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="873"><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="874" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="875"><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="876" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="877"><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="878" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="879"><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="880" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="881"><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="882" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="883"><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="884" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="885"><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="886" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="887"><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="888" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="889"><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="890" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="891"><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="892" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="893"><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="894" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="895"><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="896" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="897"><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="898" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="899"><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="900" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="901"><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="902" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="903"><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="904" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="905"><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="906" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="907"><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="908" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="909"><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="910" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="911"><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="912" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="913"><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="914" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="915"><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="916" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="917"><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="918" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="919"><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="920" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="921"><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="922" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="923"><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="924" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="925"><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="926" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="927"><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="928" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="929"><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="930" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="931"><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="932" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="933"><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="934" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="935"><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="936" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="937"><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="938" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="939"><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="940" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="941"><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="942" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="943"><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="944" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="945"><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="946" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="947"><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="948" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="949"><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="950" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="951"><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="952" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="953"><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="954" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="955"><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="956" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="957"><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="958" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="959"><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="960" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="961"><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="962" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="963"><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="964" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="965"><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="966" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="967"><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="968" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="969"><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="970" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="971"><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="972" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="973"><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="974" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="975"><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="976" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="977"><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="978" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="979"><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="980" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="981"><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="982" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="983"><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="984" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="985"><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="986" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="987"><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="988" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="989"><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="990" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="991"><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="992" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="993"><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="994" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="995"><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="996" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="997"><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="998" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="999"><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="1000" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1001"><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="1002" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1003"><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="1004" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1005"><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="1006" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1007"><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="1008" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1009"><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="1010" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1011"><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="1012" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1013"><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="1014" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1015"><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="1016" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1017"><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="1018" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1019"><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="1020" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1021"><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="1022" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1023"><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="1024" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1025"><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="1026" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1027"><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="1028" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1029"><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="1030" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1031"><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="1032" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1033"><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="1034" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1035"><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="1036" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1037"><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="1038" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1039"><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="1040" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1041"><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="1042" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1043"><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="1044" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1045"><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="1046" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1047"><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="1048" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1049"><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="1050" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1051"><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="1052" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1053"><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="1054" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1055"><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="1056" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1057"><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="1058" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1059"><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="1060" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1061"><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="1062" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1063"><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="1064" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1065"><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="1066" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1067"><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="1068" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1069"><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="1070" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1071"><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="1072" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1073"><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="1074" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1075"><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="1076" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1077"><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="1078" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1079"><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="1080" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1081"><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="1082" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1083"><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="1084" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1085"><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="1086" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1087"><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="1088" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1089"><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="1090" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1091"><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="1092" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1093"><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="1094" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1095"><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="1096" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1097"><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="1098" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1099"><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="1100" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1101"><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="1102" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1103"><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="1104" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1105"><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="1106" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1107"><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="1108" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1109"><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="1110" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1111"><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="1112" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1113"><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="1114" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1115"><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="1116" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1117"><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="1118" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1119"><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="1120" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1121"><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="1122" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1123"><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="1124" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1125"><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="1126" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1127"><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="1128" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1129"><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="1130" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1131"><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="1132" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1133"><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="1134" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1135"><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="1136" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1137"><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="1138" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1139"><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="1140" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1141"><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="1142" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1143"><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="1144" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1145"><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="1146" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1147"><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="1148" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1149"><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="1150" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1151"><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="1152" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1153"><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="1154" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1155"><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="1156" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1157"><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="1158" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1159"><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="1160" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1161"><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="1162" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1163"><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="1164" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1165"><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="1166" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1167"><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="1168" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1169"><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="1170" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1171"><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="1172" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1173"><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="1174" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1175"><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="1176" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1177"><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="1178" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1179"><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="1180" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1181"><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="1182" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1183"><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="1184" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1185"><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="1186" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1187"><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="1188" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1189"><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="1190" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1191"><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="1192" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1193"><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="1194" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1195"><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="1196" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1197"><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="1198" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1199"><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="1200" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1201"><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="1202" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1203"><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="1204" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1205"><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="1206" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1207"><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="1208" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1209"><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="1210" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1211"><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="1212" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1213"><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="1214" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1215"><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="1216" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1217"><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="1218" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1219"><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="1220" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1221"><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="1222" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1223"><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="1224" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1225"><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="1226" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1227"><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="1228" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1229"><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="1230" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1231"><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="1232" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1233"><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="1234" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1235"><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="1236" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1237"><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="1238" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1239"><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="1240" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1241"><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="1242" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1243"><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="1244" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1245"><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="1246" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1247"><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="1248" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1249"><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="1250" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1251"><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="1252" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1253"><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="1254" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1255"><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="1256" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1257"><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="1258" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1259"><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="1260" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1261"><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="1262" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1263"><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="1264" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1265"><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="1266" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1267"><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="1268" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1269"><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="1270" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1271"><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="1272" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1273"><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="1274" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1275"><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="1276" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1277"><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="1278" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1279"><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="1280" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1281"><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="1282" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1283"><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="1284" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1285"><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="1286" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1287"><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="1288" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1289"><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="1290" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1291"><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="1292" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1293"><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="1294" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1295"><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="1296" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1297"><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="1298" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1299"><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="1300" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1301"><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="1302" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1303"><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="1304" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1305"><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="1306" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1307"><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="1308" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1309"><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="1310" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1311"><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="1312" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1313"><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="1314" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1315"><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="1316" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1317"><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="1318" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1319"><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="1320" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1321"><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="1322" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1323"><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="1324" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1325"><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="1326" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1327"><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="1328" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1329"><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="1330" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1331"><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="1332" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1333"><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="1334" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1335"><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="1336" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1337"><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="1338" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1339"><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="1340" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1341"><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="1342" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1343"><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="1344" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1345"><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="1346" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1347"><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="1348" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1349"><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="1350" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1351"><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="1352" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1353"><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="1354" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1355"><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="1356" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1357"><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="1358" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1359"><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="1360" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1361"><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="1362" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1363"><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="1364" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1365"><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="1366" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1367"><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="1368" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1369"><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="1370" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1371"><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="1372" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1373"><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="1374" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1375"><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="1376" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1377"><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="1378" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1379"><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="1380" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1381"><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="1382" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1383"><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="1384" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1385"><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="1386" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1387"><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="1388" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1389"><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="1390" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1391"><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="1392" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1393"><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="1394" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1395"><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="1396" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1397"><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="1398" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1399"><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="1400" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1401"><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="1402" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1403"><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="1404" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1405"><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="1406" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1407"><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="1408" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1409"><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="1410" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1411"><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="1412" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1413"><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="1414" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1415"><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="1416" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1417"><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="1418" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1419"><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="1420" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1421"><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="1422" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1423"><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="1424" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1425"><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="1426" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1427"><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="1428" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1429"><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="1430" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1431"><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="1432" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1433"><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="1434" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1435"><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="1436" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1437"><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="1438" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1439"><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="1440" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1441"><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="1442" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1443"><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="1444" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1445"><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="1446" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1447"><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="1448" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1449"><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="1450" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1451"><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="1452" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1453"><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="1454" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1455"><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="1456" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1457"><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="1458" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1459"><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="1460" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1461"><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="1462" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1463"><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="1464" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1465"><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="1466" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1467"><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="1468" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1469"><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="1470" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1471"><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="1472" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1473"><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="1474" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1475"><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="1476" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1477"><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="1478" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1479"><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="1480" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1481"><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="1482" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1483"><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="1484" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1485"><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="1486" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1487"><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="1488" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1489"><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="1490" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1491"><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="1492" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1493"><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="1494" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1495"><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="1496" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1497"><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="1498" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1499"><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="1500" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1501"><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="1502" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1503"><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="1504" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1505"><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="1506" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1507"><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="1508" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1509"><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="1510" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1511"><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="1512" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1513"><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="1514" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1515"><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="1516" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1517"><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="1518" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1519"><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="1520" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1521"><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="1522" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1523"><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="1524" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1525"><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="1526" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1527"><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="1528" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1529"><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="1530" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1531"><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="1532" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1533"><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="1534" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1535"><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="1536" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1537"><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="1538" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1539"><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="1540" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1541"><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="1542" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1543"><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="1544" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1545"><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="1546" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1547"><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="1548" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1549"><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="1550" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1551"><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="1552" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1553"><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="1554" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1555"><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="1556" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1557"><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="1558" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1559"><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="1560" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1561"><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="1562" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1563"><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="1564" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1565"><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="1566" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1567"><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="1568" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1569"><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="1570" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1571"><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="1572" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1573"><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="1574" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1575"><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="1576" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1577"><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="1578" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1579"><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="1580" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1581"><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="1582" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1583"><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="1584" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1585"><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="1586" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1587"><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="1588" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1589"><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="1590" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1591"><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="1592" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1593"><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="1594" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1595"><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="1596" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1597"><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="1598" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1599"><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="1600" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1601"><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="1602" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1603"><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="1604" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1605"><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="1606" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1607"><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="1608" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1609"><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="1610" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1611"><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="1612" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1613"><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="1614" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1615"><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="1616" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1617"><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="1618" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1619"><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="1620" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1621"><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="1622" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1623"><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="1624" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1625"><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="1626" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1627"><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="1628" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1629"><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="1630" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1631"><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="1632" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1633"><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="1634" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1635"><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="1636" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1637"><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="1638" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1639"><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="1640" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1641"><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="1642" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1643"><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="1644" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1645"><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="1646" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1647"><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="1648" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1649"><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="1650" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1651"><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="1652" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1653"><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="1654" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1655"><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="1656" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1657"><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="1658" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1659"><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="1660" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1661"><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="1662" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1663"><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="1664" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1665"><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="1666" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1667"><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="1668" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1669"><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="1670" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1671"><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="1672" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1673"><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="1674" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1675"><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="1676" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1677"><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="1678" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1679"><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="1680" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1681"><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="1682" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1683"><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="1684" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1685"><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="1686" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1687"><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="1688" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1689"><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="1690" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1691"><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="1692" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1693"><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="1694" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1695"><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="1696" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1697"><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="1698" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1699"><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="1700" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1701"><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="1702" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1703"><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="1704" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1705"><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="1706" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1707"><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="1708" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1709"><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="1710" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1711"><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="1712" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1713"><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="1714" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1715"><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="1716" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1717"><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="1718" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1719"><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="1720" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1721"><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="1722" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1723"><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="1724" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1725"><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="1726" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1727"><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="1728" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1729"><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="1730" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1731"><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="1732" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1733"><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="1734" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1735"><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="1736" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1737"><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="1738" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1739"><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="1740" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1741"><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="1742" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1743"><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="1744" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1745"><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="1746" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1747"><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="1748" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1749"><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="1750" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1751"><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="1752" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1753"><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="1754" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1755"><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="1756" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1757"><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="1758" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1759"><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="1760" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1761"><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="1762" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1763"><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="1764" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1765"><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="1766" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1767"><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="1768" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1769"><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="1770" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1771"><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="1772" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1773"><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="1774" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1775"><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="1776" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1777"><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="1778" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1779"><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="1780" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1781"><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="1782" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1783"><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="1784" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1785"><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="1786" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1787"><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="1788" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1789"><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="1790" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1791"><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="1792" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1793"><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="1794" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1795"><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="1796" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1797"><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="1798" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1799"><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="1800" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1801"><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="1802" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1803"><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="1804" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1805"><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="1806" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1807"><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="1808" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1809"><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="1810" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1811"><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="1812" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1813"><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="1814" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1815"><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="1816" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1817"><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="1818" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1819"><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="1820" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1821"><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="1822" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1823"><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="1824" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1825"><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="1826" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1827"><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="1828" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1829"><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="1830" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1831"><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="1832" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1833"><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="1834" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1835"><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="1836" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1837"><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="1838" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1839"><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="1840" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1841"><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="1842" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1843"><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="1844" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1845"><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="1846" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1847"><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="1848" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1849"><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="1850" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1851"><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="1852" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1853"><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="1854" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1855"><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="1856" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1857"><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="1858" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1859"><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="1860" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1861"><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="1862" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1863"><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="1864" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1865"><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="1866" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1867"><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="1868" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1869"><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="1870" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1871"><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="1872" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1873"><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="1874" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1875"><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="1876" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1877"><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="1878" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1879"><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="1880" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1881"><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="1882" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1883"><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="1884" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1885"><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="1886" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1887"><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="1888" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1889"><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="1890" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1891"><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="1892" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1893"><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="1894" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1895"><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="1896" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1897"><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="1898" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1899"><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="1900" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1901"><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="1902" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1903"><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="1904" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1905"><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="1906" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1907"><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="1908" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1909"><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="1910" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1911"><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="1912" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1913"><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="1914" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1915"><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="1916" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1917"><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="1918" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1919"><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="1920" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1921"><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="1922" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1923"><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="1924" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1925"><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="1926" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1927"><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="1928" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1929"><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="1930" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1931"><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="1932" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1933"><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="1934" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1935"><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="1936" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1937"><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="1938" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1939"><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="1940" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1941"><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="1942" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1943"><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="1944" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1945"><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="1946" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1947"><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="1948" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1949"><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="1950" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1951"><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="1952" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1953"><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="1954" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1955"><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="1956" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1957"><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="1958" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1959"><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="1960" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1961"><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="1962" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1963"><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="1964" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1965"><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="1966" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1967"><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="1968" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1969"><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="1970" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1971"><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="1972" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1973"><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="1974" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1975"><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="1976" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1977"><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="1978" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1979"><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="1980" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="1981"><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="1982" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="1983"><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="1984" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="1985"><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="1986" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="1987"><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="1988" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="1989"><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="1990" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="1991"><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="1992" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="1993"><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="1994" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="1995"><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="1996" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="1997"><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="1998" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="1999"><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="2000" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2001"><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="2002" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2003"><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="2004" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2005"><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="2006" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2007"><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="2008" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2009"><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="2010" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2011"><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="2012" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2013"><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="2014" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2015"><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="2016" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2017"><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="2018" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2019"><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="2020" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2021"><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="2022" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2023"><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="2024" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2025"><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="2026" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2027"><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="2028" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2029"><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="2030" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2031"><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="2032" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2033"><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="2034" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2035"><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="2036" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2037"><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="2038" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2039"><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="2040" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2041"><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="2042" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2043"><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="2044" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2045"><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="2046" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2047"><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="2048" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2049"><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="2050" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2051"><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="2052" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2053"><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="2054" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2055"><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="2056" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2057"><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="2058" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2059"><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="2060" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2061"><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="2062" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2063"><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="2064" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2065"><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="2066" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2067"><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="2068" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2069"><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="2070" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2071"><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="2072" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2073"><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="2074" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2075"><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="2076" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2077"><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="2078" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2079"><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="2080" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2081"><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="2082" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2083"><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="2084" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2085"><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="2086" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2087"><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="2088" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2089"><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="2090" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2091"><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="2092" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2093"><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="2094" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2095"><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="2096" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2097"><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="2098" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2099"><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="2100" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2101"><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="2102" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2103"><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="2104" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2105"><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="2106" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2107"><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="2108" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2109"><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="2110" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2111"><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="2112" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2113"><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="2114" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2115"><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="2116" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2117"><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="2118" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2119"><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="2120" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2121"><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="2122" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2123"><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="2124" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2125"><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="2126" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2127"><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="2128" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2129"><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="2130" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2131"><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="2132" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2133"><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="2134" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2135"><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="2136" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2137"><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="2138" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2139"><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="2140" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2141"><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="2142" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2143"><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="2144" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2145"><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="2146" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2147"><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="2148" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2149"><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="2150" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2151"><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="2152" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2153"><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="2154" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2155"><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="2156" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2157"><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="2158" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2159"><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="2160" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2161"><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="2162" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2163"><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="2164" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2165"><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="2166" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2167"><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="2168" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2169"><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="2170" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2171"><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="2172" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2173"><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="2174" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2175"><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="2176" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2177"><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="2178" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2179"><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="2180" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2181"><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="2182" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2183"><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="2184" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2185"><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="2186" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2187"><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="2188" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2189"><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="2190" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2191"><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="2192" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2193"><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="2194" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2195"><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="2196" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2197"><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="2198" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2199"><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="2200" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2201"><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="2202" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2203"><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="2204" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2205"><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="2206" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2207"><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="2208" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2209"><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="2210" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2211"><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="2212" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2213"><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="2214" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2215"><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="2216" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2217"><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="2218" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2219"><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="2220" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2221"><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="2222" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2223"><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="2224" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2225"><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="2226" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2227"><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="2228" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2229"><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="2230" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2231"><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="2232" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2233"><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="2234" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2235"><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="2236" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2237"><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="2238" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2239"><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="2240" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2241"><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="2242" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2243"><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="2244" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2245"><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="2246" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2247"><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="2248" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2249"><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="2250" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2251"><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="2252" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2253"><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="2254" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2255"><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="2256" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2257"><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="2258" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2259"><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="2260" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2261"><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="2262" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2263"><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="2264" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2265"><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="2266" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2267"><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="2268" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2269"><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="2270" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2271"><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="2272" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2273"><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="2274" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2275"><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="2276" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2277"><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="2278" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2279"><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="2280" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2281"><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="2282" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2283"><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="2284" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2285"><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="2286" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2287"><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="2288" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2289"><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="2290" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2291"><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="2292" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2293"><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="2294" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2295"><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="2296" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2297"><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="2298" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2299"><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="2300" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2301"><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="2302" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2303"><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="2304" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2305"><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="2306" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2307"><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="2308" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2309"><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="2310" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2311"><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="2312" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2313"><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="2314" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2315"><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="2316" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2317"><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="2318" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2319"><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="2320" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2321"><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="2322" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2323"><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="2324" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2325"><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="2326" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2327"><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="2328" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2329"><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="2330" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2331"><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="2332" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2333"><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="2334" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2335"><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="2336" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2337"><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="2338" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2339"><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="2340" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2341"><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="2342" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2343"><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="2344" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2345"><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="2346" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2347"><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="2348" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2349"><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="2350" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2351"><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="2352" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2353"><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="2354" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2355"><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="2356" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2357"><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="2358" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2359"><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="2360" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2361"><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="2362" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2363"><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="2364" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2365"><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="2366" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2367"><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="2368" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2369"><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="2370" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2371"><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="2372" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2373"><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="2374" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2375"><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="2376" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2377"><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="2378" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2379"><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="2380" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2381"><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="2382" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2383"><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="2384" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2385"><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="2386" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2387"><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="2388" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2389"><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="2390" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2391"><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="2392" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2393"><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="2394" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2395"><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="2396" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2397"><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="2398" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2399"><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="2400" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2401"><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="2402" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2403"><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="2404" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2405"><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="2406" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2407"><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="2408" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2409"><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="2410" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2411"><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="2412" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2413"><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="2414" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2415"><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="2416" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2417"><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="2418" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2419"><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="2420" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2421"><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="2422" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2423"><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="2424" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2425"><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="2426" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2427"><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="2428" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2429"><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="2430" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2431"><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="2432" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2433"><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="2434" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2435"><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="2436" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2437"><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="2438" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2439"><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="2440" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2441"><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="2442" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2443"><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="2444" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2445"><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="2446" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2447"><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="2448" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2449"><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="2450" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2451"><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="2452" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2453"><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="2454" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2455"><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="2456" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2457"><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="2458" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2459"><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="2460" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2461"><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="2462" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2463"><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="2464" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2465"><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="2466" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2467"><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="2468" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2469"><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="2470" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2471"><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="2472" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2473"><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="2474" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2475"><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="2476" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2477"><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="2478" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2479"><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="2480" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2481"><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="2482" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2483"><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="2484" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2485"><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="2486" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2487"><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="2488" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2489"><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="2490" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2491"><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="2492" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2493"><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="2494" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2495"><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="2496" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2497"><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="2498" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2499"><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="2500" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2501"><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="2502" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2503"><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="2504" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2505"><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="2506" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2507"><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="2508" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2509"><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="2510" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2511"><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="2512" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2513"><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="2514" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2515"><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="2516" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2517"><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="2518" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2519"><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="2520" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2521"><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="2522" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2523"><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="2524" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2525"><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="2526" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2527"><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="2528" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2529"><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="2530" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2531"><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="2532" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2533"><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="2534" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2535"><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="2536" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2537"><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="2538" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2539"><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="2540" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2541"><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="2542" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2543"><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="2544" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2545"><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="2546" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2547"><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="2548" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2549"><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="2550" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2551"><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="2552" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2553"><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="2554" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2555"><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="2556" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2557"><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="2558" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2559"><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="2560" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2561"><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="2562" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2563"><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="2564" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2565"><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="2566" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2567"><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="2568" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2569"><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="2570" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2571"><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="2572" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2573"><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="2574" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2575"><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="2576" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2577"><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="2578" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2579"><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="2580" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2581"><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="2582" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2583"><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="2584" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2585"><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="2586" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2587"><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="2588" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2589"><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="2590" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2591"><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="2592" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2593"><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="2594" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2595"><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="2596" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2597"><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="2598" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2599"><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="2600" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2601"><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="2602" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2603"><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="2604" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2605"><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="2606" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2607"><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="2608" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2609"><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="2610" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2611"><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="2612" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2613"><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="2614" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2615"><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="2616" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2617"><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="2618" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2619"><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="2620" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2621"><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="2622" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2623"><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="2624" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2625"><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="2626" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2627"><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="2628" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2629"><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="2630" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2631"><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="2632" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2633"><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="2634" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2635"><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="2636" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2637"><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="2638" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2639"><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="2640" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2641"><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="2642" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2643"><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="2644" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2645"><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="2646" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2647"><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="2648" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2649"><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="2650" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2651"><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="2652" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2653"><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="2654" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2655"><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="2656" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2657"><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="2658" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2659"><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="2660" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2661"><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="2662" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2663"><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="2664" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2665"><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="2666" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2667"><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="2668" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2669"><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="2670" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2671"><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="2672" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2673"><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="2674" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2675"><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="2676" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2677"><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="2678" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2679"><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="2680" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2681"><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="2682" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2683"><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="2684" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2685"><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="2686" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2687"><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="2688" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2689"><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="2690" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2691"><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="2692" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2693"><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="2694" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2695"><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="2696" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2697"><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="2698" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2699"><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="2700" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2701"><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="2702" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2703"><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="2704" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2705"><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="2706" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2707"><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="2708" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2709"><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="2710" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2711"><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="2712" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2713"><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="2714" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2715"><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="2716" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2717"><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="2718" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2719"><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="2720" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2721"><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="2722" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2723"><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="2724" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2725"><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="2726" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2727"><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="2728" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2729"><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="2730" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2731"><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="2732" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2733"><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="2734" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2735"><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="2736" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2737"><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="2738" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2739"><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="2740" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2741"><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="2742" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2743"><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="2744" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2745"><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="2746" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2747"><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="2748" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2749"><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="2750" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2751"><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="2752" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2753"><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="2754" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2755"><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="2756" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2757"><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="2758" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2759"><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="2760" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2761"><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="2762" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2763"><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="2764" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2765"><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="2766" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2767"><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="2768" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2769"><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="2770" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2771"><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="2772" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2773"><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="2774" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2775"><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="2776" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2777"><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="2778" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2779"><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="2780" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2781"><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="2782" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2783"><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="2784" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2785"><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="2786" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2787"><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="2788" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2789"><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="2790" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2791"><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="2792" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2793"><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="2794" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2795"><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="2796" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2797"><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="2798" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2799"><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="2800" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2801"><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="2802" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2803"><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="2804" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2805"><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="2806" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2807"><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="2808" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2809"><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="2810" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2811"><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="2812" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2813"><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="2814" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2815"><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="2816" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2817"><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="2818" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2819"><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="2820" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2821"><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="2822" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2823"><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="2824" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2825"><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="2826" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2827"><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="2828" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2829"><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="2830" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2831"><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="2832" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2833"><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="2834" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2835"><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="2836" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2837"><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="2838" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2839"><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="2840" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2841"><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="2842" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2843"><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="2844" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2845"><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="2846" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2847"><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="2848" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2849"><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="2850" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2851"><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="2852" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2853"><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="2854" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2855"><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="2856" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2857"><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="2858" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2859"><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="2860" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2861"><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="2862" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2863"><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="2864" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2865"><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="2866" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2867"><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="2868" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2869"><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="2870" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2871"><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="2872" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2873"><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="2874" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2875"><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="2876" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2877"><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="2878" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2879"><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="2880" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2881"><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="2882" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2883"><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="2884" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2885"><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="2886" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2887"><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="2888" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2889"><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="2890" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2891"><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="2892" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2893"><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="2894" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2895"><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="2896" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2897"><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="2898" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2899"><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="2900" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2901"><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="2902" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2903"><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="2904" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2905"><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="2906" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2907"><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="2908" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2909"><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="2910" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2911"><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="2912" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2913"><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="2914" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2915"><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="2916" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2917"><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="2918" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2919"><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="2920" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2921"><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="2922" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2923"><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="2924" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2925"><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="2926" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2927"><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="2928" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2929"><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="2930" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2931"><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="2932" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2933"><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="2934" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2935"><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="2936" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2937"><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="2938" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2939"><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="2940" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2941"><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="2942" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2943"><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="2944" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2945"><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="2946" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2947"><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="2948" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2949"><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="2950" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2951"><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="2952" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2953"><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="2954" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2955"><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="2956" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2957"><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="2958" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2959"><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="2960" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2961"><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="2962" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2963"><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="2964" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2965"><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="2966" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2967"><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="2968" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2969"><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="2970" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2971"><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="2972" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2973"><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="2974" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2975"><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="2976" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2977"><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="2978" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2979"><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="2980" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="2981"><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="2982" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="2983"><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="2984" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="2985"><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="2986" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="2987"><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="2988" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="2989"><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="2990" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="2991"><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="2992" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="2993"><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="2994" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="2995"><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="2996" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="2997"><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="2998" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="2999"><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="3000" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3001"><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="3002" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3003"><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="3004" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3005"><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="3006" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3007"><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="3008" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3009"><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="3010" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3011"><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="3012" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3013"><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="3014" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3015"><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="3016" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3017"><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="3018" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3019"><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="3020" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3021"><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="3022" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3023"><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="3024" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3025"><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="3026" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3027"><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="3028" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3029"><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="3030" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3031"><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="3032" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3033"><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="3034" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3035"><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="3036" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3037"><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="3038" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3039"><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="3040" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3041"><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="3042" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3043"><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="3044" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3045"><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="3046" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3047"><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="3048" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3049"><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="3050" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3051"><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="3052" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3053"><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="3054" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3055"><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="3056" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3057"><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="3058" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3059"><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="3060" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3061"><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="3062" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3063"><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="3064" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3065"><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="3066" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3067"><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="3068" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3069"><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="3070" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3071"><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="3072" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3073"><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="3074" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3075"><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="3076" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3077"><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="3078" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3079"><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="3080" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3081"><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="3082" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3083"><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="3084" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3085"><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="3086" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3087"><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="3088" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3089"><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="3090" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3091"><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="3092" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3093"><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="3094" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3095"><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="3096" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3097"><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="3098" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3099"><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="3100" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3101"><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="3102" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3103"><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="3104" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3105"><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="3106" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3107"><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="3108" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3109"><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="3110" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3111"><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="3112" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3113"><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="3114" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3115"><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="3116" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3117"><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="3118" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3119"><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="3120" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3121"><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="3122" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3123"><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="3124" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3125"><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="3126" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3127"><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="3128" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3129"><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="3130" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>romance</enum></record><record orange="3131"><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="3132" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>horror</enum></record><record orange="3133"><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="3134" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>philosophy</enum></record><record orange="3135"><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="3136" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>fiction</enum></record><record orange="3137"><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="3138" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>history</enum></record><record orange="3139"><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="3140" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>romance</enum></record><record orange="3141"><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="3142" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>horror</enum></record><record orange="3143"><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="3144" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>philosophy</enum></record><record orange="3145"><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="3146" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice3>3 choice</choice3><enum>fiction</enum></record><record orange="3147"><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="3148" apple="true"><int>42</int><double>42345.4232</double><name>name123_45</name><choice1>1 choice</choice1><enum>history</enum></record><record orange="3149"><int>42</int><double>42345.4232</double><name>name123_45</name><string>one two three</string><choice2>2 choice</choice2><enum>philosophy</enum></record></t:root> \ No newline at end of file
diff --git a/examples/cxx/tree/performance/test-50k.xml b/examples/cxx/tree/performance/test-50k.xml
new file mode 100644
index 0000000..42e22f3
--- /dev/null
+++ b/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/examples/cxx/tree/performance/test-5k.xml b/examples/cxx/tree/performance/test-5k.xml
new file mode 100644
index 0000000..168cb09
--- /dev/null
+++ b/examples/cxx/tree/performance/test-5k.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></t:root> \ No newline at end of file
diff --git a/examples/cxx/tree/performance/test.xsd b/examples/cxx/tree/performance/test.xsd
new file mode 100644
index 0000000..cf1f046
--- /dev/null
+++ b/examples/cxx/tree/performance/test.xsd
@@ -0,0 +1,50 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/performance/test.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/performance/time.cxx b/examples/cxx/tree/performance/time.cxx
new file mode 100644
index 0000000..c2de6dc
--- /dev/null
+++ b/examples/cxx/tree/performance/time.cxx
@@ -0,0 +1,47 @@
+// file : examples/cxx/tree/performance/time.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/tree/performance/time.hxx b/examples/cxx/tree/performance/time.hxx
new file mode 100644
index 0000000..f83e628
--- /dev/null
+++ b/examples/cxx/tree/performance/time.hxx
@@ -0,0 +1,111 @@
+// file : examples/cxx/tree/performance/time.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// 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/examples/cxx/tree/polymorphism/README b/examples/cxx/tree/polymorphism/README
new file mode 100644
index 0000000..05d794f
--- /dev/null
+++ b/examples/cxx/tree/polymorphism/README
@@ -0,0 +1,28 @@
+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 the use of the --generate-polymorphic command line option.
+
+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/examples/cxx/tree/polymorphism/driver.cxx b/examples/cxx/tree/polymorphism/driver.cxx
new file mode 100644
index 0000000..582e2dd
--- /dev/null
+++ b/examples/cxx/tree/polymorphism/driver.cxx
@@ -0,0 +1,60 @@
+// file : examples/cxx/tree/polymorphism/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "supermen.hxx"
+
+using std::cerr;
+using std::endl;
+using std::auto_ptr;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " supermen.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_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/examples/cxx/tree/polymorphism/makefile b/examples/cxx/tree/polymorphism/makefile
new file mode 100644
index 0000000..f4e0b16
--- /dev/null
+++ b/examples/cxx/tree/polymorphism/makefile
@@ -0,0 +1,72 @@
+# file : examples/cxx/tree/polymorphism/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := supermen.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-polymorphic --generate-serialization --root-element-last
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/polymorphism/supermen.xml b/examples/cxx/tree/polymorphism/supermen.xml
new file mode 100644
index 0000000..5053142
--- /dev/null
+++ b/examples/cxx/tree/polymorphism/supermen.xml
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/polymorphism/supermen.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/polymorphism/supermen.xsd b/examples/cxx/tree/polymorphism/supermen.xsd
new file mode 100644
index 0000000..ffdd21c
--- /dev/null
+++ b/examples/cxx/tree/polymorphism/supermen.xsd
@@ -0,0 +1,49 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/polymorphism/supermen.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="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/examples/cxx/tree/streaming/README b/examples/cxx/tree/streaming/README
new file mode 100644
index 0000000..51e5c14
--- /dev/null
+++ b/examples/cxx/tree/streaming/README
@@ -0,0 +1,22 @@
+This example shows how to create an XML document by performing multiple
+serializations of its smaller parts. This can be useful when the
+document is too large to fit into memory or when the other end needs
+to start processing without waiting for the whole document (streaming).
+
+The example consists of the following files:
+
+records.xsd
+ XML Schema which describes a collection of data records.
+
+records.hxx
+records.cxx
+ C++ types that represent the given vocabulary as well as serialization
+ functions. These are generated by XSD from records.xsd.
+
+driver.cxx
+ Driver for the example. It progressively serializes one thousand data
+ record into a file (out.xml).
+
+To run the example simply execute:
+
+$ ./driver
diff --git a/examples/cxx/tree/streaming/driver.cxx b/examples/cxx/tree/streaming/driver.cxx
new file mode 100644
index 0000000..6afc1ce
--- /dev/null
+++ b/examples/cxx/tree/streaming/driver.cxx
@@ -0,0 +1,65 @@
+// file : examples/cxx/tree/streaming/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <iostream>
+#include <fstream>
+
+#include "records.hxx"
+
+using std::cerr;
+using std::endl;
+using std::ios_base;
+
+int
+main ()
+{
+ try
+ {
+ std::ofstream ofs;
+ ofs.exceptions (ios_base::badbit | ios_base::failbit);
+ ofs.open ("out.xml");
+
+ // We will need to create XML declaration as well as open and close
+ // the root tag ourselves.
+ //
+ ofs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl
+ << "<records>" << endl;
+
+ // For performance reasons, we would like to initialize/terminate
+ // Xerces-C++ ourselves once instead of letting the serialization
+ // function do it for every record.
+ //
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ xml_schema::namespace_infomap map;
+
+ for (unsigned long i (0); i < 1000; ++i)
+ {
+ // Create the next record.
+ //
+ record r ("data");
+
+ record_ (ofs,
+ r,
+ map,
+ "UTF-8",
+ xml_schema::flags::dont_initialize |
+ xml_schema::flags::no_xml_declaration);
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+
+ ofs << "</records>" << endl;
+ }
+ catch (const xml_schema::exception& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/examples/cxx/tree/streaming/makefile b/examples/cxx/tree/streaming/makefile
new file mode 100644
index 0000000..0c478e0
--- /dev/null
+++ b/examples/cxx/tree/streaming/makefile
@@ -0,0 +1,74 @@
+# file : examples/cxx/tree/streaming/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := records.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-serialization \
+ --suppress-parsing \
+ --root-element-all
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+ $(call message,rm $$1,rm -f $$1,$(out_base)/out.xml)
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/streaming/records.xsd b/examples/cxx/tree/streaming/records.xsd
new file mode 100644
index 0000000..2b357e6
--- /dev/null
+++ b/examples/cxx/tree/streaming/records.xsd
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/streaming/records.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="record">
+ <xsd:sequence>
+ <xsd:element name="data" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!--
+
+ We need this global element so that we get serialization functions
+ for record. Note that global elements are always qualified. As a
+ result, if you are using XML namespaces (this example is not), you
+ will need to make sure the record element inside the records type
+ is also qualified.
+
+ -->
+ <xsd:element name="record" type="record"/>
+
+ <xsd:complexType name="records">
+ <xsd:sequence>
+ <xsd:element name="record" type="record" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="records" type="records"/>
+
+</xsd:schema>
diff --git a/examples/cxx/tree/wildcard/README b/examples/cxx/tree/wildcard/README
new file mode 100644
index 0000000..d451509
--- /dev/null
+++ b/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/examples/cxx/tree/wildcard/driver.cxx b/examples/cxx/tree/wildcard/driver.cxx
new file mode 100644
index 0000000..5fc6abf
--- /dev/null
+++ b/examples/cxx/tree/wildcard/driver.cxx
@@ -0,0 +1,160 @@
+// file : examples/cxx/tree/wildcard/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <string>
+#include <memory> // std::auto_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::auto_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/examples/cxx/tree/wildcard/email.xml b/examples/cxx/tree/wildcard/email.xml
new file mode 100644
index 0000000..517c3c6
--- /dev/null
+++ b/examples/cxx/tree/wildcard/email.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/wildcard/email.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/wildcard/email.xsd b/examples/cxx/tree/wildcard/email.xsd
new file mode 100644
index 0000000..c14eebe
--- /dev/null
+++ b/examples/cxx/tree/wildcard/email.xsd
@@ -0,0 +1,51 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/wildcard/email.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+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/examples/cxx/tree/wildcard/makefile b/examples/cxx/tree/wildcard/makefile
new file mode 100644
index 0000000..6a287e6
--- /dev/null
+++ b/examples/cxx/tree/wildcard/makefile
@@ -0,0 +1,72 @@
+# file : examples/cxx/tree/wildcard/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := email.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-inline \
+--generate-wildcard --generate-serialization --root-element message
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/xpath/README b/examples/cxx/tree/xpath/README
new file mode 100644
index 0000000..48d40d6
--- /dev/null
+++ b/examples/cxx/tree/xpath/README
@@ -0,0 +1,47 @@
+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 Xerces-C++ 3.x.y/XQilla 2.2.x. 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.
+
+driver-2.cxx
+ Driver for Xerces-C++ 2.x.y/XQilla 2.1.x. It performs the same set
+ of actions as driver.cxx above.
+
+To run the example on the sample XML document simply execute:
+
+$ ./driver people.xml
diff --git a/examples/cxx/tree/xpath/dom-parse.cxx b/examples/cxx/tree/xpath/dom-parse.cxx
new file mode 100644
index 0000000..84ff0af
--- /dev/null
+++ b/examples/cxx/tree/xpath/dom-parse.cxx
@@ -0,0 +1,113 @@
+// file : examples/cxx/tree/xpath/dom-parse.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include "dom-parse.hxx"
+
+#include <istream>
+
+#include <xercesc/dom/DOM.hpp>
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/error-handler.hxx>
+
+using namespace xercesc;
+namespace xml = xsd::cxx::xml;
+namespace tree = xsd::cxx::tree;
+
+xml::dom::auto_ptr<DOMDocument>
+parse (std::istream& is,
+ const std::string& id,
+ bool validate,
+ DOMImplementation* impl)
+{
+#if _XERCES_VERSION >= 30000
+
+ // Xerces-C++ 3.0.0 and later.
+ //
+ xml::dom::auto_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ // Enable/Disable validation.
+ //
+ conf->setParameter (XMLUni::fgDOMValidate, validate);
+ conf->setParameter (XMLUni::fgXercesSchema, validate);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+
+ // We will release the DOM document ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ // Set error handler.
+ //
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+#else // _XERCES_VERSION >= 30000
+
+ // Same as above but for Xerces-C++ 2 series.
+ //
+ xml::dom::auto_ptr<DOMBuilder> parser (
+ impl->createDOMBuilder (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ parser->setFeature (XMLUni::fgDOMComments, false);
+ parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
+ parser->setFeature (XMLUni::fgDOMEntities, false);
+ parser->setFeature (XMLUni::fgDOMNamespaces, true);
+ parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false);
+ parser->setFeature (XMLUni::fgDOMValidation, validate);
+ parser->setFeature (XMLUni::fgXercesSchema, validate);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ tree::error_handler<char> eh;
+ xml::dom::bits::error_handler_proxy<char> ehp (eh);
+ parser->setErrorHandler (&ehp);
+
+#endif // _XERCES_VERSION >= 30000
+
+ // Prepare input stream.
+ //
+ xml::sax::std_input_source isrc (is, id);
+ Wrapper4InputSource wrap (&isrc, false);
+
+#if _XERCES_VERSION >= 30000
+ xml::dom::auto_ptr<DOMDocument> doc (parser->parse (&wrap));
+#else
+ xml::dom::auto_ptr<DOMDocument> doc (parser->parse (wrap));
+#endif
+
+ eh.throw_if_failed<tree::parsing<char> > ();
+
+ return doc;
+}
diff --git a/examples/cxx/tree/xpath/dom-parse.hxx b/examples/cxx/tree/xpath/dom-parse.hxx
new file mode 100644
index 0000000..cfa1555
--- /dev/null
+++ b/examples/cxx/tree/xpath/dom-parse.hxx
@@ -0,0 +1,26 @@
+// file : examples/cxx/tree/xpath/dom-parse.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef DOM_PARSE
+#define DOM_PARSE
+
+#include <string>
+#include <iosfwd>
+
+#include <xercesc/dom/DOMDocument.hpp>
+#include <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::auto_ptr<xercesc::DOMDocument>
+parse (std::istream& is,
+ const std::string& id,
+ bool validate,
+ xercesc::DOMImplementation*);
+
+#endif // DOM_PARSE
diff --git a/examples/cxx/tree/xpath/driver-2.cxx b/examples/cxx/tree/xpath/driver-2.cxx
new file mode 100644
index 0000000..ccbdd7c
--- /dev/null
+++ b/examples/cxx/tree/xpath/driver-2.cxx
@@ -0,0 +1,139 @@
+// file : examples/cxx/tree/xpath/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#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::auto_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::auto_ptr<directory> d (
+ directory_ (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::auto_ptr<XQillaNSResolver> resolver (
+ (XQillaNSResolver*)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::auto_ptr<const XQillaExpression> expr (
+ static_cast<const XQillaExpression*> (
+ doc->createExpression (
+ xml::string ("p:directory/person[age > 30]").c_str (),
+ resolver.get ())));
+
+ // Execute the query.
+ //
+ xml_schema::dom::auto_ptr<XPath2Result> r (
+ static_cast<XPath2Result*> (
+ expr->evaluate (doc, XPath2Result::ITERATOR_RESULT, 0)));
+
+ // Iterate over the result.
+ //
+ cout << "Records matching the query:" << endl;
+
+ while (r->iterateNext ())
+ {
+ const DOMNode* n (r->asNode ());
+
+ // 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.
+ //
+ cout << 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/examples/cxx/tree/xpath/driver.cxx b/examples/cxx/tree/xpath/driver.cxx
new file mode 100644
index 0000000..b55037b
--- /dev/null
+++ b/examples/cxx/tree/xpath/driver.cxx
@@ -0,0 +1,137 @@
+// file : examples/cxx/tree/xpath/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#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::auto_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::auto_ptr<directory> d (
+ directory_ (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::auto_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::auto_ptr<DOMXPathExpression> expr (
+ doc->createExpression (
+ xml::string ("p:directory/person[age > 30]").c_str (),
+ resolver.get ()));
+
+ // Execute the query.
+ //
+ xml_schema::dom::auto_ptr<DOMXPathResult> r (
+ expr->evaluate (doc, DOMXPathResult::ITERATOR_RESULT_TYPE, 0));
+
+ // Iterate over the result.
+ //
+ cout << "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.
+ //
+ cout << 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/examples/cxx/tree/xpath/makefile b/examples/cxx/tree/xpath/makefile
new file mode 100644
index 0000000..5e73cfb
--- /dev/null
+++ b/examples/cxx/tree/xpath/makefile
@@ -0,0 +1,71 @@
+# file : examples/cxx/tree/xpath/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := people.xsd
+cxx := driver.cxx dom-parse.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+$(call import,\
+ $(scf_root)/import/libxqilla/stub.make,\
+ l: xqilla.l,cpp-options: xqilla.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xqilla.l) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xqilla.l.cpp-options) $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/examples/cxx/tree/xpath/people.xml b/examples/cxx/tree/xpath/people.xml
new file mode 100644
index 0000000..24af876
--- /dev/null
+++ b/examples/cxx/tree/xpath/people.xml
@@ -0,0 +1,29 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/xpath/people.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<ppl:directory xmlns:ppl="http://www.codesynthesis.com/people"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/people people.xsd">
+
+ <person>
+ <first-name>John</first-name>
+ <last-name>Doe</last-name>
+ <gender>male</gender>
+ <age>32</age>
+ </person>
+
+ <person>
+ <first-name>Jane</first-name>
+ <last-name>Doe</last-name>
+ <gender>female</gender>
+ <age>28</age>
+ </person>
+
+</ppl:directory>
diff --git a/examples/cxx/tree/xpath/people.xsd b/examples/cxx/tree/xpath/people.xsd
new file mode 100644
index 0000000..12c8aef
--- /dev/null
+++ b/examples/cxx/tree/xpath/people.xsd
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/tree/xpath/people.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:ppl="http://www.codesynthesis.com/people"
+ targetNamespace="http://www.codesynthesis.com/people">
+
+ <xsd:simpleType name="gender">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="male"/>
+ <xsd:enumeration value="female"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:complexType name="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>
diff --git a/examples/makefile b/examples/makefile
new file mode 100644
index 0000000..fcc4e71
--- /dev/null
+++ b/examples/makefile
@@ -0,0 +1,17 @@
+# file : examples/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
+
+default := $(out_base)/
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(clean)
+
+$(default): $(out_base)/cxx/parser/ $(out_base)/cxx/tree/
+$(clean): $(out_base)/cxx/parser/.clean $(out_base)/cxx/tree/.clean
+
+$(call import,$(src_base)/cxx/parser/makefile)
+$(call import,$(src_base)/cxx/tree/makefile)
diff --git a/libxsd/FLOSSE b/libxsd/FLOSSE
new file mode 100644
index 0000000..cbf8b2c
--- /dev/null
+++ b/libxsd/FLOSSE
@@ -0,0 +1,89 @@
+1. Intent
+
+We want specified Free/Libre and Open Source Software ("FLOSS") to be
+able to use the specified GPL-licensed XSD runtime library (libxsd) and
+XSD generated code (collectively called the "Program") despite the fact
+that not all FLOSS licenses are compatible with version 2 of the GNU
+General Public License (the "GPL").
+
+It is our intent to allow distribution of the entire Derivative Work
+(including the Program) under one or more of the FLOSS licenses listed
+in section 3 (section 2.a). It is also our intent to disallow simple
+relicensing of the Program for the sole purpose of using it in
+proprietary applications (section 2.b and 2.c). As an example, consider
+two hypothetical scenarios:
+
+ a) You created a program that uses the XSD generated code and the XSD
+ runtime library to access information in XML instance documents.
+ Your program performs useful computations based on this information
+ (sections 2.b and 2.c are satisfied). You distribute your program,
+ including the XSD generated code and the XSD runtime library under
+ the BSD license and make it available at no charge to all third
+ parties (section 2.a is satisfied). Later you (or someone else) may
+ choose to base their proprietary application on your code since the
+ BSD license does not prohibit it.
+
+ This scenario falls under this FLOSS Exception.
+
+
+ b) You created a library that uses the XSD generated code and the XSD
+ runtime library to access information in XML instance documents. You
+ did not add to the library any other useful code that uses the XSD
+ generated code or the XSD runtime library (neither section 2.b nor
+ 2.c is satisfied). You distribute your library, including the XSD
+ generated code and the XSD runtime library under the BSD license and
+ make it available at no charge to all third parties (section 2.a
+ is satisfied). Later you base your proprietary application on this
+ library since the BSD license does not prohibit it.
+
+ This scenario does not fall under this FLOSS Exception (neither
+ section 2.b nor 2.c is satisfied). You created the library for the
+ sole purpose of making the XSD generated code and the XSD runtime
+ library available to your proprietary application.
+
+
+2. Legal Terms and Conditions
+
+As a special exception to the terms and conditions of version 2 of
+the GPL you are free to distribute a verbatim copy of the Program
+as part of the Derivative Work that is formed from the Program or
+any part thereof and one or more works (each, a "FLOSS Work") as
+long as you also meet all of these conditions:
+
+ a) You must cause the Derivative Work that in whole or in part
+ contains or is derived from the Program or any part thereof,
+ to be licensed as a whole at no charge to all third parties
+ under the terms of one or more of the licenses listed in
+ section 3.
+
+ b) The Derivative Work should contain one or more FLOSS Work that
+ can be reasonably considered as derived from the Program or some
+ part thereof.
+
+ c) The Derivative Work should not contain any part of the Program
+ that cannot be reasonably considered as a base of one or more
+ FLOSS Work.
+
+
+3. FLOSS License List
+
+ a) Any license listed in the "GPL-Compatible Free Software Licenses"
+ and the "GPL-Incompatible Free Software Licenses" sections of the
+ License List as published by the Free Software Foundation (FSF):
+
+ http://www.gnu.org/licenses/license-list.html
+
+
+4. Definitions
+
+Terms used, but not defined, herein shall have the meaning provided in
+the GPL.
+
+Derivative Work means a derivative work under copyright law.
+
+
+5. Applicability
+
+You may choose to redistribute a copy of the Program exclusively under
+the terms of the GPL by removing the FLOSS Exception notice from that
+copy of the Program.
diff --git a/libxsd/GPLv2 b/libxsd/GPLv2
new file mode 100644
index 0000000..3912109
--- /dev/null
+++ b/libxsd/GPLv2
@@ -0,0 +1,340 @@
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) <year> <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) year name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
diff --git a/libxsd/INSTALL b/libxsd/INSTALL
new file mode 100644
index 0000000..537f00a
--- /dev/null
+++ b/libxsd/INSTALL
@@ -0,0 +1,17 @@
+Prerequisites
+
+ run-time:
+
+ - libxerces-c >= 2.5.0 http://xerces.apache.org/xerces-c/
+
+
+Building libxsd
+
+ No building is necessary at the moment.
+
+
+Installing libxsd
+
+ Not supported in this version. You may want to copy libxsd/xsd
+ to $(prefix)/include so that you have $(prefix)/include/xsd/*.
+
diff --git a/libxsd/LICENSE b/libxsd/LICENSE
new file mode 100644
index 0000000..42346bf
--- /dev/null
+++ b/libxsd/LICENSE
@@ -0,0 +1,26 @@
+This program is free software; you can redistribute it and/or modify
+it under the terms of the GNU General Public License version 2 as
+published by the Free Software Foundation.
+
+This program is distributed in the hope that it will be useful,
+but WITHOUT ANY WARRANTY; without even the implied warranty of
+MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+GNU General Public License for details.
+
+You should have received a copy of the GNU General Public License
+along with this program; if not, write to the Free Software
+Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+
+In addition, as a special exception, Code Synthesis Tools CC gives
+permission to link this program with the Xerces-C++ library (or with
+modified versions of Xerces-C++ that use the same license as Xerces-C++),
+and distribute linked combinations including the two. You must obey
+the GNU General Public License version 2 in all respects for all of
+the code used other than Xerces-C++. If you modify this copy of the
+program, you may extend this exception to your version of the program,
+but you are not obligated to do so. If you do not wish to do so, delete
+this exception statement from your version.
+
+In addition, Code Synthesis Tools CC makes a special exception for
+the Free/Libre and Open Source Software (FLOSS) which is described
+in the accompanying FLOSSE file.
diff --git a/libxsd/README b/libxsd/README
new file mode 100644
index 0000000..328d8b2
--- /dev/null
+++ b/libxsd/README
@@ -0,0 +1,13 @@
+libxsd is a runtime library for language mappings generated by
+XSD, a W3C XML Schema to C++ data binding compiler.
+
+
+See the LICENSE file for distribution conditions.
+
+See the INSTALL file for prerequisites and installation instructions.
+
+The project page is at http://codesynthesis.com/projects/xsd/
+
+Send bug reports or any other feedback to the xsd-users@codesynthesis.com
+mailing list.
+
diff --git a/libxsd/makefile b/libxsd/makefile
new file mode 100644
index 0000000..7024fef
--- /dev/null
+++ b/libxsd/makefile
@@ -0,0 +1,20 @@
+# file : libxsd/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
+
+install := $(out_base)/.install
+
+.PHONY: $(install)
+
+$(install):
+ $(call install-dir,$(src_base)/xsd,$(install_inc_dir)/xsd)
+ $(call install-data,$(src_base)/FLOSSE,$(install_doc_dir)/libxsd/FLOSSE)
+ $(call install-data,$(src_base)/GPLv2,$(install_doc_dir)/libxsd/GPLv2)
+ $(call install-data,$(src_base)/LICENSE,$(install_doc_dir)/libxsd/LICENSE)
+ $(call install-data,$(src_base)/README,$(install_doc_dir)/libxsd/README)
+
+
+$(call include,$(bld_root)/install.make)
diff --git a/libxsd/xsd/cxx/auto-array.hxx b/libxsd/xsd/cxx/auto-array.hxx
new file mode 100644
index 0000000..b9ef09e
--- /dev/null
+++ b/libxsd/xsd/cxx/auto-array.hxx
@@ -0,0 +1,114 @@
+// file : xsd/cxx/auto-array.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_AUTO_ARRAY_HXX
+#define XSD_CXX_AUTO_ARRAY_HXX
+
+#include <cstddef> // std::size_t
+
+namespace xsd
+{
+ namespace cxx
+ {
+ template <typename T>
+ struct std_deallocator
+ {
+ void
+ deallocate (T* p)
+ {
+ delete[] p;
+ }
+ };
+
+ // Simple automatic array. The second template parameter is
+ // an optional deallocator type. If not specified, delete[]
+ // is used.
+ //
+ template <typename T, typename D = std_deallocator<T> >
+ struct auto_array
+ {
+ auto_array (T a[])
+ : a_ (a), d_ (0)
+ {
+ }
+
+ auto_array (T a[], D& d)
+ : a_ (a), d_ (&d)
+ {
+ }
+
+ ~auto_array ()
+ {
+ if (d_ != 0)
+ d_->deallocate (a_);
+ else
+ delete[] a_;
+ }
+
+ T&
+ operator[] (std::size_t index) const
+ {
+ return a_[index];
+ }
+
+ T*
+ get () const
+ {
+ return a_;
+ }
+
+ T*
+ release ()
+ {
+ T* tmp (a_);
+ a_ = 0;
+ return tmp;
+ }
+
+ void
+ reset (T a[] = 0)
+ {
+ if (a_ != a)
+ {
+ if (d_ != 0)
+ d_->deallocate (a_);
+ else
+ delete[] a_;
+
+ a_ = a;
+ }
+ }
+
+ typedef void (auto_array::*bool_convertible)();
+
+ operator bool_convertible () const
+ {
+ return a_ ? &auto_array<T, D>::true_ : 0;
+ }
+
+ private:
+ auto_array (const auto_array&);
+
+ auto_array&
+ operator= (const auto_array&);
+
+ private:
+ void
+ true_ ();
+
+ private:
+ T* a_;
+ D* d_;
+ };
+
+ template <typename T, typename D>
+ void auto_array<T, D>::
+ true_ ()
+ {
+ }
+ }
+}
+
+#endif // XSD_CXX_AUTO_ARRAY_HXX
diff --git a/libxsd/xsd/cxx/compilers/vc-7/post.hxx b/libxsd/xsd/cxx/compilers/vc-7/post.hxx
new file mode 100644
index 0000000..13efa6a
--- /dev/null
+++ b/libxsd/xsd/cxx/compilers/vc-7/post.hxx
@@ -0,0 +1,6 @@
+// file : xsd/cxx/compilers/vc-7/post.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#pragma warning (pop)
diff --git a/libxsd/xsd/cxx/compilers/vc-7/pre.hxx b/libxsd/xsd/cxx/compilers/vc-7/pre.hxx
new file mode 100644
index 0000000..1d431a7
--- /dev/null
+++ b/libxsd/xsd/cxx/compilers/vc-7/pre.hxx
@@ -0,0 +1,36 @@
+// file : xsd/cxx/compilers/vc-7/pre.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+
+#if (_MSC_VER < 1310)
+# error Microsoft Visual C++ 7.0 (.NET 2002) is not supported.
+#endif
+
+
+// These warnings had to be disabled "for good".
+//
+#pragma warning (disable:4250) // inherits via dominance
+#pragma warning (disable:4505) // unreferenced local function has been removed
+#pragma warning (disable:4661) // no definition for explicit instantiation
+
+
+// Push warning state.
+//
+#pragma warning (push, 3)
+
+
+// Disabled warnings.
+//
+#pragma warning (disable:4355) // passing 'this' to a member
+#pragma warning (disable:4584) // is already a base-class
+#pragma warning (disable:4800) // forcing value to bool
+#pragma warning (disable:4275) // non dll-interface base
+#pragma warning (disable:4251) // base needs to have dll-interface
+#pragma warning (disable:4224) // nonstandard extension (/Za option)
+
+
+// Elevated warnings.
+//
+#pragma warning (2:4239) // standard doesn't allow this conversion
diff --git a/libxsd/xsd/cxx/compilers/vc-8/post.hxx b/libxsd/xsd/cxx/compilers/vc-8/post.hxx
new file mode 100644
index 0000000..6a4328f
--- /dev/null
+++ b/libxsd/xsd/cxx/compilers/vc-8/post.hxx
@@ -0,0 +1,6 @@
+// file : xsd/cxx/compilers/vc-8/post.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#pragma warning (pop)
diff --git a/libxsd/xsd/cxx/compilers/vc-8/pre.hxx b/libxsd/xsd/cxx/compilers/vc-8/pre.hxx
new file mode 100644
index 0000000..bd7c890
--- /dev/null
+++ b/libxsd/xsd/cxx/compilers/vc-8/pre.hxx
@@ -0,0 +1,28 @@
+// file : xsd/cxx/compilers/vc-8/pre.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// These warnings had to be disabled "for good".
+//
+#pragma warning (disable:4250) // inherits via dominance
+#pragma warning (disable:4661) // no definition for explicit instantiation
+
+
+// Push warning state.
+//
+#pragma warning (push, 3)
+
+
+// Disabled warnings.
+//
+#pragma warning (disable:4355) // passing 'this' to a member
+#pragma warning (disable:4800) // forcing value to bool
+#pragma warning (disable:4275) // non dll-interface base
+#pragma warning (disable:4251) // base needs to have dll-interface
+#pragma warning (disable:4224) // nonstandard extension (/Za option)
+
+
+// Elevated warnings.
+//
+#pragma warning (2:4239) // standard doesn't allow this conversion
diff --git a/libxsd/xsd/cxx/config.hxx b/libxsd/xsd/cxx/config.hxx
new file mode 100644
index 0000000..feb0e12
--- /dev/null
+++ b/libxsd/xsd/cxx/config.hxx
@@ -0,0 +1,15 @@
+// file : xsd/cxx/config.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_CONFIG_HXX
+#define XSD_CXX_CONFIG_HXX
+
+#include <xsd/cxx/version.hxx>
+
+// Macro to suppress unused variable warning.
+//
+#define XSD_UNUSED(x) (void)x
+
+#endif // XSD_CXX_CONFIG_HXX
diff --git a/libxsd/xsd/cxx/exceptions.hxx b/libxsd/xsd/cxx/exceptions.hxx
new file mode 100644
index 0000000..d6d0ef9
--- /dev/null
+++ b/libxsd/xsd/cxx/exceptions.hxx
@@ -0,0 +1,21 @@
+// file : xsd/cxx/exceptions.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_EXCEPTIONS_HXX
+#define XSD_CXX_EXCEPTIONS_HXX
+
+#include <exception> // std::exception
+
+namespace xsd
+{
+ namespace cxx
+ {
+ struct exception: std::exception
+ {
+ };
+ }
+}
+
+#endif // XSD_CXX_EXCEPTIONS_HXX
diff --git a/libxsd/xsd/cxx/parser/document.hxx b/libxsd/xsd/cxx/parser/document.hxx
new file mode 100644
index 0000000..dd8be4a
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/document.hxx
@@ -0,0 +1,90 @@
+// file : xsd/cxx/parser/document.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_DOCUMENT_HXX
+#define XSD_CXX_PARSER_DOCUMENT_HXX
+
+#include <string>
+#include <cstddef> // std::size_t
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/parser/elements.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // If you want to use a different underlying XML parser, all you
+ // need to do is to route events to this interface.
+ //
+ template <typename C>
+ class document
+ {
+ public:
+ virtual
+ ~document ();
+
+ document (parser_base<C>& root,
+ const std::basic_string<C>& ns,
+ const std::basic_string<C>& name);
+
+ public:
+ // The type argument is a type name and namespace from the
+ // xsi:type attribute in the form "<name> <namespace>" with
+ // the space and namespace part absent if the type does not
+ // have a namespace or 0 if xsi:type is not present.
+ //
+ void
+ start_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type);
+
+ void
+ end_element (const ro_string<C>& ns, const ro_string<C>& name);
+
+ void
+ attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value);
+
+ void
+ characters (const ro_string<C>&);
+
+ protected:
+ document ();
+
+ // This function is called to obtain the root element type parser.
+ // If the returned pointed is 0 then the whole document content
+ // is ignored.
+ //
+ virtual parser_base<C>*
+ start_root_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type);
+
+ // 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<C>& ns,
+ const ro_string<C>& name,
+ parser_base<C>* parser);
+
+ private:
+ parser_base<C>* root_;
+ std::basic_string<C> ns_;
+ std::basic_string<C> name_;
+ std::size_t depth_;
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/parser/document.txx>
+
+#endif // XSD_CXX_PARSER_DOCUMENT_HXX
diff --git a/libxsd/xsd/cxx/parser/document.txx b/libxsd/xsd/cxx/parser/document.txx
new file mode 100644
index 0000000..451eb71
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/document.txx
@@ -0,0 +1,129 @@
+// file : xsd/cxx/parser/document.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cassert>
+
+#include <xsd/cxx/parser/schema-exceptions.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // document
+ //
+ template <typename C>
+ document<C>::
+ ~document ()
+ {
+ }
+
+ template <typename C>
+ document<C>::
+ document (parser_base<C>& root,
+ const std::basic_string<C>& ns,
+ const std::basic_string<C>& name)
+ : root_ (&root), ns_ (ns), name_ (name), depth_ (0)
+ {
+ }
+
+ template <typename C>
+ document<C>::
+ document ()
+ : root_ (0), depth_ (0)
+ {
+ }
+
+ template <typename C>
+ void document<C>::
+ start_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type)
+ {
+ if (depth_++ > 0)
+ {
+ if (root_)
+ root_->_start_element (ns, name, type);
+ }
+ else
+ {
+ root_ = start_root_element (ns, name, type);
+
+ if (root_)
+ {
+ // pre () is called by the user.
+ //
+ root_->_pre_impl ();
+ }
+ }
+ }
+
+ template <typename C>
+ void document<C>::
+ end_element (const ro_string<C>& ns, const ro_string<C>& name)
+ {
+ assert (depth_ > 0);
+
+ if (--depth_ > 0)
+ {
+ if (root_)
+ root_->_end_element (ns, name);
+ }
+ else
+ {
+ if (root_)
+ {
+ root_->_post_impl ();
+ //
+ // post() is called by the user.
+ }
+
+ end_root_element (ns, name, root_);
+ }
+ }
+
+ template <typename C>
+ void document<C>::
+ attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ if (root_)
+ root_->_attribute (ns, name, value);
+ }
+
+ template <typename C>
+ void document<C>::
+ characters (const ro_string<C>& s)
+ {
+ if (root_)
+ root_->_characters (s);
+ }
+
+ template <typename C>
+ parser_base<C>* document<C>::
+ start_root_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>*)
+ {
+ if (name_ == name && ns_ == ns)
+ {
+ return root_;
+ }
+ else
+ throw expected_element<C> (ns_, name_, ns, name);
+ }
+
+ template <typename C>
+ void document<C>::
+ end_root_element (const ro_string<C>&,
+ const ro_string<C>&,
+ parser_base<C>*)
+ {
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/elements.hxx b/libxsd/xsd/cxx/parser/elements.hxx
new file mode 100644
index 0000000..e900189
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/elements.hxx
@@ -0,0 +1,95 @@
+// file : xsd/cxx/parser/elements.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_ELEMENTS_HXX
+#define XSD_CXX_PARSER_ELEMENTS_HXX
+
+#include <xsd/cxx/ro-string.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // pre() and post() are overridable pre/post callbacks, i.e., the
+ // derived parser can override them without calling the base version.
+ // _pre() and _post() are not overridable pre/post callbacks in the
+ // sense that the derived parser may override them but has to call
+ // the base version. The call sequence is as shown below:
+ //
+ // pre ()
+ // _pre ()
+ // _post ()
+ // post ()
+ //
+ template <typename C>
+ class parser_base
+ {
+ public:
+ virtual
+ ~parser_base ();
+
+ virtual void
+ pre ();
+
+ virtual void
+ _pre ();
+
+ // The type argument is a type name and namespace from the
+ // xsi:type attribute in the form "<name> <namespace>" with
+ // the space and namespace part absent if the type does not
+ // have a namespace or 0 if xsi:type is not present.
+ //
+ virtual void
+ _start_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type) = 0;
+
+ virtual void
+ _end_element (const ro_string<C>& ns,
+ const ro_string<C>& name) = 0;
+
+ virtual void
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value) = 0;
+
+ virtual void
+ _characters (const ro_string<C>&) = 0;
+
+ virtual void
+ _post ();
+
+ // The post() signature varies depending on the parser return
+ // type.
+ //
+
+ // Implementation callbacks for _pre and _post. The _pre and _post
+ // callbacks should never be called directly. Instead, the *_impl
+ // versions should be used. By default _pre_impl and _post_impl
+ // simply call _pre and _post respectively.
+ //
+ virtual void
+ _pre_impl ();
+
+ virtual void
+ _post_impl ();
+
+ public:
+ // Dynamic type in the form "<name> <namespace>" with
+ // the space and namespace part absent if the type does
+ // not have a namespace. Used in polymorphism-aware code.
+ //
+ virtual const C*
+ _dynamic_type () const;
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/parser/elements.txx>
+
+#endif // XSD_CXX_PARSER_ELEMENTS_HXX
diff --git a/libxsd/xsd/cxx/parser/elements.txx b/libxsd/xsd/cxx/parser/elements.txx
new file mode 100644
index 0000000..3bfb7be
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/elements.txx
@@ -0,0 +1,60 @@
+// file : xsd/cxx/parser/elements.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // parser_base
+ //
+ template <typename C>
+ parser_base<C>::
+ ~parser_base ()
+ {
+ }
+
+ template <typename C>
+ void parser_base<C>::
+ pre ()
+ {
+ }
+
+ template <typename C>
+ void parser_base<C>::
+ _pre ()
+ {
+ }
+
+ template <typename C>
+ void parser_base<C>::
+ _post ()
+ {
+ }
+
+ template <typename C>
+ void parser_base<C>::
+ _pre_impl ()
+ {
+ _pre ();
+ }
+
+ template <typename C>
+ void parser_base<C>::
+ _post_impl ()
+ {
+ _post ();
+ }
+
+ template <typename C>
+ const C* parser_base<C>::
+ _dynamic_type () const
+ {
+ return 0;
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/error-handler.hxx b/libxsd/xsd/cxx/parser/error-handler.hxx
new file mode 100644
index 0000000..b44974f
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/error-handler.hxx
@@ -0,0 +1,57 @@
+// file : xsd/cxx/parser/error-handler.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_ERROR_HANDLER_HXX
+#define XSD_CXX_PARSER_ERROR_HANDLER_HXX
+
+#include <xsd/cxx/xml/error-handler.hxx>
+
+#include <xsd/cxx/parser/exceptions.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ template <typename C>
+ class error_handler: public xml::error_handler<C>
+ {
+ typedef typename xml::error_handler<C>::severity severity;
+
+ public:
+ error_handler ()
+ : failed_ (false)
+ {
+ }
+
+ virtual bool
+ handle (const std::basic_string<C>& id,
+ unsigned long line,
+ unsigned long column,
+ severity s,
+ const std::basic_string<C>& message);
+
+ void
+ throw_if_failed () const;
+
+ void
+ reset ()
+ {
+ failed_ = false;
+ diagnostics_.clear ();
+ }
+
+ private:
+ bool failed_;
+ diagnostics<C> diagnostics_;
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/parser/error-handler.txx>
+
+#endif // XSD_CXX_PARSER_ERROR_HANDLER_HXX
diff --git a/libxsd/xsd/cxx/parser/error-handler.txx b/libxsd/xsd/cxx/parser/error-handler.txx
new file mode 100644
index 0000000..9b5feb7
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/error-handler.txx
@@ -0,0 +1,41 @@
+// file : xsd/cxx/parser/error-handler.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ template <typename C>
+ bool error_handler<C>::
+ handle (const std::basic_string<C>& id,
+ unsigned long line,
+ unsigned long column,
+ severity s,
+ const std::basic_string<C>& message)
+ {
+ diagnostics_.push_back (
+ error<C> (s == severity::warning
+ ? cxx::parser::severity::warning
+ : cxx::parser::severity::error,
+ id, line, column, message));
+
+ if (!failed_ && s != severity::warning)
+ failed_ = true;
+
+ return true;
+ }
+
+ template <typename C>
+ void error_handler<C>::
+ throw_if_failed () const
+ {
+ if (failed_)
+ throw parsing<C> (diagnostics_);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/exceptions.hxx b/libxsd/xsd/cxx/parser/exceptions.hxx
new file mode 100644
index 0000000..a19fb7d
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/exceptions.hxx
@@ -0,0 +1,153 @@
+// file : xsd/cxx/parser/exceptions.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_EXCEPTIONS_HXX
+#define XSD_CXX_PARSER_EXCEPTIONS_HXX
+
+#include <string>
+#include <vector>
+#include <ostream>
+
+#include <xsd/cxx/exceptions.hxx> // xsd::cxx::exception
+#include <xsd/cxx/ro-string.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ //
+ //
+ template <typename C>
+ struct exception: xsd::cxx::exception
+ {
+ friend
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const exception& e)
+ {
+ e.print (os);
+ return os;
+ }
+
+ protected:
+ virtual void
+ print (std::basic_ostream<C>&) const = 0;
+ };
+
+
+ //
+ //
+ struct severity
+ {
+ enum value
+ {
+ warning,
+ error
+ };
+
+ severity (value v) : v_ (v) {}
+ operator value () const { return v_; }
+
+ private:
+ value v_;
+ };
+
+ template <typename C>
+ struct error
+ {
+ error (cxx::parser::severity,
+ const std::basic_string<C>& id,
+ unsigned long line,
+ unsigned long column,
+ const std::basic_string<C>& message);
+
+ cxx::parser::severity
+ severity () const
+ {
+ return severity_;
+ }
+
+ const std::basic_string<C>&
+ id () const
+ {
+ return id_;
+ }
+
+ unsigned long
+ line () const
+ {
+ return line_;
+ }
+
+ unsigned long
+ column () const
+ {
+ return column_;
+ }
+
+ const std::basic_string<C>&
+ message () const
+ {
+ return message_;
+ }
+
+ private:
+ cxx::parser::severity severity_;
+ std::basic_string<C> id_;
+ unsigned long line_;
+ unsigned long column_;
+ std::basic_string<C> message_;
+ };
+
+ // See exceptions.ixx for operator<< (error).
+
+
+ //
+ //
+ template <typename C>
+ struct diagnostics: std::vector<error<C> >
+ {
+ };
+
+ // See exceptions.ixx for operator<< (diagnostics).
+
+ //
+ //
+ template <typename C>
+ struct parsing: exception<C>
+ {
+ virtual
+ ~parsing () throw ();
+
+ parsing ();
+
+ parsing (const cxx::parser::diagnostics<C>&);
+
+ const cxx::parser::diagnostics<C>&
+ diagnostics () const
+ {
+ return diagnostics_;
+ }
+
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ private:
+ cxx::parser::diagnostics<C> diagnostics_;
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/parser/exceptions.txx>
+
+#endif // XSD_CXX_PARSER_EXCEPTIONS_HXX
+
+#include <xsd/cxx/parser/exceptions.ixx>
diff --git a/libxsd/xsd/cxx/parser/exceptions.ixx b/libxsd/xsd/cxx/parser/exceptions.ixx
new file mode 100644
index 0000000..b583ed0
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/exceptions.ixx
@@ -0,0 +1,129 @@
+// file : xsd/cxx/parser/exceptions.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR)
+
+#ifndef XSD_CXX_PARSER_EXCEPTIONS_IXX_CHAR
+#define XSD_CXX_PARSER_EXCEPTIONS_IXX_CHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // error
+ //
+ inline
+ std::basic_ostream<char>&
+ operator<< (std::basic_ostream<char>& os, const error<char>& e)
+ {
+ return os << e.id () << ':' << e.line () << ':' << e.column ()
+ << (e.severity () == severity::error
+ ? " error: "
+ : " warning: ") << e.message ();
+ }
+
+
+ // diagnostics
+ //
+ inline
+ std::basic_ostream<char>&
+ operator<< (std::basic_ostream<char>& os, const diagnostics<char>& d)
+ {
+ for (diagnostics<char>::const_iterator b (d.begin ()), i (b);
+ i != d.end ();
+ ++i)
+ {
+ if (i != b)
+ os << "\n";
+
+ os << *i;
+ }
+
+ return os;
+ }
+
+ // parsing
+ //
+ template<>
+ inline
+ void parsing<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ if (diagnostics_.empty ())
+ os << "instance document parsing failed";
+ else
+ os << diagnostics_;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_EXCEPTIONS_IXX_CHAR
+#endif // XSD_CXX_PARSER_USE_CHAR
+
+
+#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR)
+
+#ifndef XSD_CXX_PARSER_EXCEPTIONS_IXX_WCHAR
+#define XSD_CXX_PARSER_EXCEPTIONS_IXX_WCHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // error
+ //
+ inline
+ std::basic_ostream<wchar_t>&
+ operator<< (std::basic_ostream<wchar_t>& os, const error<wchar_t>& e)
+ {
+ return os << e.id () << L':' << e.line () << L':' << e.column ()
+ << (e.severity () == severity::error
+ ? L" error: "
+ : L" warning: ") << e.message ();
+ }
+
+ // diagnostics
+ //
+ inline
+ std::basic_ostream<wchar_t>&
+ operator<< (std::basic_ostream<wchar_t>& os,
+ const diagnostics<wchar_t>& d)
+ {
+ for (diagnostics<wchar_t>::const_iterator b (d.begin ()), i (b);
+ i != d.end ();
+ ++i)
+ {
+ if (i != b)
+ os << L"\n";
+
+ os << *i;
+ }
+
+ return os;
+ }
+
+ // parsing
+ //
+ template<>
+ inline
+ void parsing<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ if (diagnostics_.empty ())
+ os << L"instance document parsing failed";
+ else
+ os << diagnostics_;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_EXCEPTIONS_IXX_WCHAR
+#endif // XSD_CXX_PARSER_USE_WCHAR
diff --git a/libxsd/xsd/cxx/parser/exceptions.txx b/libxsd/xsd/cxx/parser/exceptions.txx
new file mode 100644
index 0000000..ddb20b0
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/exceptions.txx
@@ -0,0 +1,59 @@
+// file : xsd/cxx/parser/exceptions.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // error
+ //
+ template <typename C>
+ error<C>::
+ error (cxx::parser::severity s,
+ const std::basic_string<C>& id,
+ unsigned long line,
+ unsigned long column,
+ const std::basic_string<C>& message)
+ : severity_ (s),
+ id_ (id),
+ line_ (line),
+ column_ (column),
+ message_ (message)
+ {
+ }
+
+
+ // parsing
+ //
+ template <typename C>
+ parsing<C>::
+ ~parsing () throw ()
+ {
+ }
+
+ template <typename C>
+ parsing<C>::
+ parsing ()
+ {
+ }
+
+ template <typename C>
+ parsing<C>::
+ parsing (const cxx::parser::diagnostics<C>& diagnostics)
+ : diagnostics_ (diagnostics)
+ {
+ }
+
+ template <typename C>
+ const char* parsing<C>::
+ what () const throw ()
+ {
+ return "instance document parsing failed";
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/expat/elements.hxx b/libxsd/xsd/cxx/parser/expat/elements.hxx
new file mode 100644
index 0000000..a0de3e3
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/expat/elements.hxx
@@ -0,0 +1,344 @@
+// file : xsd/cxx/parser/expat/elements.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_EXPAT_ELEMENTS_HXX
+#define XSD_CXX_PARSER_EXPAT_ELEMENTS_HXX
+
+#include <string>
+#include <iosfwd>
+#include <cstddef> // std::size_t
+#include <vector>
+
+#include <expat.h>
+
+// We only support UTF-8 expat for now.
+//
+#ifdef XML_UNICODE
+#error UTF-16 expat (XML_UNICODE defined) is not supported
+#endif
+
+#include <xsd/cxx/xml/error-handler.hxx>
+
+#include <xsd/cxx/parser/exceptions.hxx>
+#include <xsd/cxx/parser/elements.hxx>
+#include <xsd/cxx/parser/document.hxx>
+#include <xsd/cxx/parser/error-handler.hxx>
+#include <xsd/cxx/parser/schema-exceptions.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace expat
+ {
+ // Simple auto pointer for Expat's XML_Parser object.
+ //
+ struct parser_auto_ptr
+ {
+ ~parser_auto_ptr ()
+ {
+ if (parser_ != 0)
+ XML_ParserFree (parser_);
+ }
+
+ explicit
+ parser_auto_ptr (XML_Parser parser = 0)
+ : parser_ (parser)
+ {
+ }
+
+ parser_auto_ptr&
+ operator= (XML_Parser parser)
+ {
+ if (parser_ != 0)
+ XML_ParserFree (parser_);
+
+ parser_ = parser;
+ return *this;
+ }
+
+ public:
+ operator XML_Parser ()
+ {
+ return parser_;
+ }
+
+ private:
+ parser_auto_ptr (const parser_auto_ptr&);
+
+ parser_auto_ptr&
+ operator= (const parser_auto_ptr&);
+
+ private:
+ XML_Parser parser_;
+ };
+
+
+ //
+ //
+ template <typename C>
+ struct document: cxx::parser::document<C> // VC 7.1 likes it qualified
+ {
+ public:
+ document (parser_base<C>&,
+ const C* root_element_name,
+ bool polymorphic = false);
+
+ document (parser_base<C>&,
+ const std::basic_string<C>& root_element_name,
+ bool polymorphic = false);
+
+ document (parser_base<C>&,
+ const C* root_element_namespace,
+ const C* root_element_name,
+ bool polymorphic = false);
+
+ document (parser_base<C>&,
+ const std::basic_string<C>& root_element_namespace,
+ const std::basic_string<C>& root_element_name,
+ bool polymorphic = false);
+
+ protected:
+ document (bool polymorphic = false);
+
+ public:
+ // Parse a local file. The file is accessed with std::ifstream
+ // in binary mode. The std::ios_base::failure exception is used
+ // to report io errors (badbit and failbit).
+ void
+ parse (const std::basic_string<C>& file);
+
+ // Parse a local file with a user-provided error_handler
+ // object. The file is accessed with std::ifstream in binary
+ // mode. The std::ios_base::failure exception is used to report
+ // io errors (badbit and failbit).
+ //
+ void
+ parse (const std::basic_string<C>& file, xml::error_handler<C>&);
+
+ public:
+ // System id is a "system" identifier of the resources (e.g.,
+ // URI or a full file path). Public id is a "public" identifier
+ // of the resource (e.g., application-specific name or relative
+ // file path). System id is used to resolve relative paths.
+ // In diagnostics messages system id is used if public id is
+ // not available. Otherwise public id is used.
+ //
+
+ // Parse std::istream.
+ //
+ void
+ parse (std::istream&);
+
+ // Parse std::istream with a user-provided error_handler object.
+ //
+ void
+ parse (std::istream&, xml::error_handler<C>&);
+
+ // Parse std::istream with a system id.
+ //
+ void
+ parse (std::istream&, const std::basic_string<C>& system_id);
+
+ // Parse std::istream with a system id and a user-provided
+ // error_handler object.
+ //
+ void
+ parse (std::istream&,
+ const std::basic_string<C>& system_id,
+ xml::error_handler<C>&);
+
+ // Parse std::istream with system and public ids.
+ //
+ void
+ parse (std::istream&,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id);
+
+ // Parse std::istream with system and public ids and a user-provided
+ // error_handler object.
+ //
+ void
+ parse (std::istream&,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id,
+ xml::error_handler<C>&);
+
+ public:
+ // Parse a chunk of input. You can call these functions multiple
+ // times with the last call having the last argument true.
+ //
+ void
+ parse (const void* data, std::size_t size, bool last);
+
+ void
+ parse (const void* data, std::size_t size, bool last,
+ xml::error_handler<C>&);
+
+ void
+ parse (const void* data, std::size_t size, bool last,
+ const std::basic_string<C>& system_id);
+
+ void
+ parse (const void* data, std::size_t size, bool last,
+ const std::basic_string<C>& system_id,
+ xml::error_handler<C>&);
+
+ void
+ parse (const void* data, std::size_t size, bool last,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id);
+
+ void
+ parse (const void* data, std::size_t size, bool last,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id,
+ xml::error_handler<C>&);
+
+ public:
+ // Low-level Expat-specific parsing API. A typical use case
+ // would look like this (pseudo-code):
+ //
+ // xxx_pimpl root;
+ // document doc (root, "root");
+ //
+ // root.pre ();
+ // doc.parse_begin (xml_parser, "file.xml");
+ //
+ // while (more_stuff_to_parse &&)
+ // {
+ // // Call XML_Parse or XML_ParseBuffer.
+ //
+ // if (status == XML_STATUS_ERROR)
+ // break;
+ // }
+ //
+ // // Call parse_end even in case of an error to translate
+ // // XML and Schema errors to exceptions or error_handler
+ // // calls.
+ // //
+ // doc.parse_end ();
+ // result_type result (root.post_xxx ());
+ //
+ // Notes:
+ //
+ // 1. If your XML instances use XML namespaces, the
+ // XML_ParserCreateNS functions should be used to create the
+ // XML parser. Space (XML_Char (' ')) should be used as a
+ // separator (the second argument to XML_ParserCreateNS).
+ //
+ void
+ parse_begin (XML_Parser);
+
+ void
+ parse_begin (XML_Parser, const std::basic_string<C>& public_id);
+
+ void
+ parse_begin (XML_Parser, xml::error_handler<C>&);
+
+ void
+ parse_begin (XML_Parser,
+ const std::basic_string<C>& public_id,
+ xml::error_handler<C>&);
+ void
+ parse_end ();
+
+ // Event routing.
+ //
+ public:
+ static void XMLCALL
+ start_element_thunk_ (void*, const XML_Char*, const XML_Char**);
+
+ static void XMLCALL
+ end_element_thunk_ (void*, const XML_Char*);
+
+ static void XMLCALL
+ characters_thunk_ (void*, const XML_Char*, int);
+
+ static void XMLCALL
+ start_namespace_decl_thunk_ (
+ void*, const XML_Char*, const XML_Char*);
+
+ static void XMLCALL
+ end_namespace_decl_thunk_ (void*, const XML_Char*);
+
+ protected:
+ void
+ start_element_ (const XML_Char* ns_name, const XML_Char** atts);
+
+ void
+ end_element_ (const XML_Char* ns_name);
+
+ void
+ characters_ (const XML_Char* s, std::size_t n);
+
+ void
+ start_namespace_decl_ (const XML_Char* prefix, const XML_Char* ns);
+
+ void
+ end_namespace_decl_ (const XML_Char* prefix);
+
+ protected:
+ void
+ set ();
+
+ void
+ clear ();
+
+ bool
+ parse (std::istream&,
+ const std::basic_string<C>* system_id,
+ const std::basic_string<C>* public_id,
+ xml::error_handler<C>&);
+
+ bool
+ parse (const void* data, std::size_t size, bool last,
+ const std::basic_string<C>* system_id,
+ const std::basic_string<C>* public_id,
+ xml::error_handler<C>&);
+
+
+ void
+ translate_schema_exception (const schema_exception<C>& e);
+
+ protected:
+ XML_Parser xml_parser_;
+ parser_auto_ptr auto_xml_parser_;
+
+ xml::error_handler<C>* eh_;
+ error_handler<C> default_eh_;
+ std::basic_string<C> public_id_;
+
+ bool polymorphic_;
+
+ // Namespace-prefix mapping. Only maintained in the polymorphic
+ // case.
+ //
+ struct ns_decl
+ {
+ ns_decl (const std::basic_string<C>& p,
+ const std::basic_string<C>& n)
+ : prefix (p), ns (n)
+ {
+ }
+
+ std::basic_string<C> prefix;
+ std::basic_string<C> ns;
+ };
+
+ typedef std::vector<ns_decl> ns_decls;
+
+ ns_decls ns_decls_;
+ };
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/parser/expat/elements.txx>
+
+#endif // XSD_CXX_PARSER_EXPAT_ELEMENTS_HXX
diff --git a/libxsd/xsd/cxx/parser/expat/elements.txx b/libxsd/xsd/cxx/parser/expat/elements.txx
new file mode 100644
index 0000000..5a60eb5
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/expat/elements.txx
@@ -0,0 +1,822 @@
+// file : xsd/cxx/parser/expat/elements.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <new> // std::bad_alloc
+#include <istream>
+#include <fstream>
+#include <cstring> // std::strchr
+#include <cassert>
+
+#include <xsd/cxx/xml/bits/literals.hxx> // xml::bits::{xml_prefix, etc}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace expat
+ {
+
+ // document
+ //
+
+ template <typename C>
+ document<C>::
+ document (parser_base<C>& p,
+ const std::basic_string<C>& name,
+ bool polymorphic)
+ : cxx::parser::document<C> (p, std::basic_string<C> (), name),
+ xml_parser_ (0),
+ eh_ (0),
+ polymorphic_ (polymorphic)
+ {
+ }
+
+ template <typename C>
+ document<C>::
+ document (parser_base<C>& p,
+ const C* name,
+ bool polymorphic)
+ : cxx::parser::document<C> (p, std::basic_string<C> (), name),
+ xml_parser_ (0),
+ eh_ (0),
+ polymorphic_ (polymorphic)
+ {
+ }
+
+ template <typename C>
+ document<C>::
+ document (parser_base<C>& p,
+ const C* ns,
+ const C* name,
+ bool polymorphic)
+ : cxx::parser::document<C> (p, ns, name),
+ xml_parser_ (0),
+ eh_ (0),
+ polymorphic_ (polymorphic)
+ {
+ }
+
+ template <typename C>
+ document<C>::
+ document (parser_base<C>& p,
+ const std::basic_string<C>& ns,
+ const std::basic_string<C>& name,
+ bool polymorphic)
+ : cxx::parser::document<C> (p, ns, name),
+ xml_parser_ (0),
+ eh_ (0),
+ polymorphic_ (polymorphic)
+ {
+ }
+
+ template <typename C>
+ document<C>::
+ document (bool polymorphic)
+ : xml_parser_ (0),
+ eh_ (0),
+ polymorphic_ (polymorphic)
+ {
+ }
+
+ // file
+ //
+
+ template <typename C>
+ void document<C>::
+ parse (const std::basic_string<C>& file)
+ {
+ std::ifstream ifs;
+ ifs.exceptions (std::ios_base::badbit | std::ios_base::failbit);
+ ifs.open (file.c_str (), std::ios_base::in | std::ios_base::binary);
+
+ parse (ifs, file);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (const std::basic_string<C>& file, xml::error_handler<C>& eh)
+ {
+ std::ifstream ifs;
+ ifs.exceptions (std::ios_base::badbit | std::ios_base::failbit);
+ ifs.open (file.c_str (), std::ios_base::in | std::ios_base::binary);
+
+ parse (ifs, file, eh);
+ }
+
+
+ // istream
+ //
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is)
+ {
+ parse (is, 0, 0, default_eh_);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is, xml::error_handler<C>& eh)
+ {
+ if (!parse (is, 0, 0, eh))
+ throw parsing<C> ();
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is, const std::basic_string<C>& system_id)
+ {
+ default_eh_.reset ();
+ parse (is, &system_id, 0, default_eh_);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ const std::basic_string<C>& system_id,
+ xml::error_handler<C>& eh)
+ {
+ if (!parse (is, &system_id, 0, eh))
+ throw parsing<C> ();
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id)
+ {
+ default_eh_.reset ();
+ parse (is, &system_id, &public_id, default_eh_);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id,
+ xml::error_handler<C>& eh)
+ {
+ if (!parse (is, &system_id, &public_id, eh))
+ throw parsing<C> ();
+ }
+
+ // data
+ //
+
+ template <typename C>
+ void document<C>::
+ parse (const void* data, std::size_t size, bool last)
+ {
+ default_eh_.reset ();
+ parse (data, size, last, 0, 0, default_eh_);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (const void* data, std::size_t size, bool last,
+ xml::error_handler<C>& eh)
+ {
+ if (!parse (data, size, last, 0, 0, eh))
+ throw parsing<C> ();
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (const void* data, std::size_t size, bool last,
+ const std::basic_string<C>& system_id)
+ {
+ default_eh_.reset ();
+ parse (data, size, last, &system_id, 0, default_eh_);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (const void* data, std::size_t size, bool last,
+ const std::basic_string<C>& system_id,
+ xml::error_handler<C>& eh)
+ {
+ if (!parse (data, size, last, &system_id, 0, eh))
+ throw parsing<C> ();
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (const void* data, std::size_t size, bool last,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id)
+ {
+ default_eh_.reset ();
+ parse (data, size, last, &system_id, &public_id, default_eh_);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (const void* data, std::size_t size, bool last,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id,
+ xml::error_handler<C>& eh)
+ {
+ if (!parse (data, size, last, &system_id, &public_id, eh))
+ throw parsing<C> ();
+ }
+
+ // Implementation details.
+ //
+
+ namespace bits
+ {
+ struct stream_exception_controller
+ {
+ ~stream_exception_controller ()
+ {
+ std::ios_base::iostate s = is_.rdstate ();
+ s &= ~std::ios_base::failbit;
+
+ // If our error state (sans failbit) intersects with the
+ // exception state then that means we have an active
+ // exception and changing error/exception state will
+ // cause another to be thrown.
+ //
+ if (!(old_state_ & s))
+ {
+ // Clear failbit if it was caused by eof.
+ //
+ if (is_.fail () && is_.eof ())
+ is_.clear (s);
+
+ is_.exceptions (old_state_);
+ }
+ }
+
+ stream_exception_controller (std::istream& is)
+ : is_ (is), old_state_ (is_.exceptions ())
+ {
+ is_.exceptions (old_state_ & ~std::ios_base::failbit);
+ }
+
+ private:
+ stream_exception_controller (const stream_exception_controller&);
+
+ stream_exception_controller&
+ operator= (const stream_exception_controller&);
+
+ private:
+ std::istream& is_;
+ std::ios_base::iostate old_state_;
+ };
+ };
+
+ template <typename C>
+ bool document<C>::
+ parse (std::istream& is,
+ const std::basic_string<C>* system_id,
+ const std::basic_string<C>* public_id,
+ xml::error_handler<C>& eh)
+ {
+ parser_auto_ptr parser (XML_ParserCreateNS (0, XML_Char (' ')));
+
+ if (parser == 0)
+ throw std::bad_alloc ();
+
+ if (system_id || public_id)
+ parse_begin (parser, system_id ? *system_id : *public_id, eh);
+ else
+ parse_begin (parser, eh);
+
+ // Temporarily unset the exception failbit. Also clear the
+ // fail bit when we reset the old state if it was caused
+ // by eof.
+ //
+ bits::stream_exception_controller sec (is);
+
+ char buf[16384]; // 4 x page size.
+
+ bool r (true);
+
+ do
+ {
+ is.read (buf, sizeof (buf));
+
+ if (is.bad () || (is.fail () && !is.eof ()))
+ {
+ // If the stream is not using exceptions then the user
+ // will have to test for stream failures before calling
+ // post.
+ //
+ break;
+ }
+
+ if (XML_Parse (
+ parser, buf, is.gcount (), is.eof ()) == XML_STATUS_ERROR)
+ {
+ r = false;
+ break;
+ }
+ } while (!is.eof ());
+
+ parse_end ();
+ return r;
+ }
+
+ template <typename C>
+ bool document<C>::
+ parse (const void* data,
+ std::size_t size,
+ bool last,
+ const std::basic_string<C>* system_id,
+ const std::basic_string<C>* public_id,
+ xml::error_handler<C>& eh)
+ {
+ // First call.
+ //
+ if (auto_xml_parser_ == 0)
+ {
+ auto_xml_parser_ = XML_ParserCreateNS (0, XML_Char (' '));
+
+ if (auto_xml_parser_ == 0)
+ throw std::bad_alloc ();
+
+ if (system_id || public_id)
+ parse_begin (auto_xml_parser_,
+ system_id ? *system_id : *public_id, eh);
+ else
+ parse_begin (auto_xml_parser_, eh);
+ }
+
+ bool r (XML_Parse (xml_parser_,
+ static_cast<const char*> (data),
+ static_cast<int> (size),
+ last) != XML_STATUS_ERROR);
+ parse_end ();
+ return r;
+ }
+
+ // XML_Parser
+ //
+
+ template <typename C>
+ void document<C>::
+ parse_begin (XML_Parser parser)
+ {
+ xml_parser_ = parser;
+ eh_ = &default_eh_;
+ public_id_.clear ();
+ set ();
+ }
+
+ template <typename C>
+ void document<C>::
+ parse_begin (XML_Parser parser,
+ const std::basic_string<C>& public_id)
+ {
+ xml_parser_ = parser;
+ eh_ = &default_eh_;
+ public_id_ = public_id;
+ set ();
+ }
+
+ template <typename C>
+ void document<C>::
+ parse_begin (XML_Parser parser, xml::error_handler<C>& eh)
+ {
+ xml_parser_ = parser;
+ eh_ = &eh;
+ public_id_.clear ();
+ set ();
+ }
+
+ template <typename C>
+ void document<C>::
+ parse_begin (XML_Parser parser,
+ const std::basic_string<C>& public_id,
+ xml::error_handler<C>& eh)
+ {
+ xml_parser_ = parser;
+ eh_ = &eh;
+ public_id_ = public_id;
+ set ();
+ }
+
+ template <typename C>
+ void document<C>::
+ parse_end ()
+ {
+ XML_Error e (XML_GetErrorCode (xml_parser_));
+
+ if (e == XML_ERROR_NONE || e == XML_ERROR_ABORTED)
+ {
+ clear ();
+ xml_parser_ = 0;
+ auto_xml_parser_ = 0;
+ }
+ else
+ {
+ unsigned long l = XML_GetCurrentLineNumber (xml_parser_);
+ unsigned long c = XML_GetCurrentColumnNumber (xml_parser_);
+ std::basic_string<C> message (XML_ErrorString (e));
+
+ eh_->handle (public_id_,
+ l, c,
+ xml::error_handler<C>::severity::fatal,
+ message);
+
+ clear ();
+ xml_parser_ = 0;
+ auto_xml_parser_ = 0;
+
+ // We don't want to throw an empty parsing exception here
+ // since the user probably already knows about the error.
+ }
+
+ if (eh_ == &default_eh_)
+ default_eh_.throw_if_failed ();
+ }
+
+ //
+ //
+ template <typename C>
+ void document<C>::
+ set ()
+ {
+ assert (xml_parser_ != 0);
+
+ XML_SetUserData(xml_parser_, this);
+
+ XML_SetStartElementHandler (xml_parser_, start_element_thunk_);
+ XML_SetEndElementHandler (xml_parser_, end_element_thunk_);
+ XML_SetCharacterDataHandler (xml_parser_, characters_thunk_);
+
+ if (polymorphic_)
+ {
+ XML_SetNamespaceDeclHandler (xml_parser_,
+ start_namespace_decl_thunk_,
+ end_namespace_decl_thunk_);
+ }
+ }
+
+ template <typename C>
+ void document<C>::
+ clear ()
+ {
+ assert (xml_parser_ != 0);
+
+ XML_SetUserData (xml_parser_, 0);
+ XML_SetStartElementHandler (xml_parser_, 0);
+ XML_SetEndElementHandler (xml_parser_, 0);
+ XML_SetCharacterDataHandler (xml_parser_, 0);
+
+ if (polymorphic_)
+ XML_SetNamespaceDeclHandler (xml_parser_, 0, 0);
+ }
+
+ template <typename C>
+ void document<C>::
+ translate_schema_exception (const schema_exception<C>& e)
+ {
+ unsigned long l = XML_GetCurrentLineNumber (xml_parser_);
+ unsigned long c = XML_GetCurrentColumnNumber (xml_parser_);
+
+ eh_->handle (public_id_,
+ l, c,
+ xml::error_handler<C>::severity::fatal,
+ e.message ());
+
+ XML_StopParser (xml_parser_, false);
+ }
+
+ // Event routing.
+ //
+
+ // Expat thunks.
+ //
+ template <typename C>
+ void XMLCALL document<C>::
+ start_element_thunk_ (void* data,
+ const XML_Char* ns_name,
+ const XML_Char** atts)
+ {
+ document& d (*reinterpret_cast<document*> (data));
+ d.start_element_ (ns_name, atts);
+ }
+
+ template <typename C>
+ void XMLCALL document<C>::
+ end_element_thunk_ (void* data, const XML_Char* ns_name)
+ {
+ document& d (*reinterpret_cast<document*> (data));
+ d.end_element_ (ns_name);
+ }
+
+ template <typename C>
+ void XMLCALL document<C>::
+ characters_thunk_ (void* data, const XML_Char* s, int n)
+ {
+ document& d (*reinterpret_cast<document*> (data));
+ d.characters_ (s, static_cast<std::size_t> (n));
+ }
+
+ template <typename C>
+ void XMLCALL document<C>::
+ start_namespace_decl_thunk_ (void* data,
+ const XML_Char* prefix,
+ const XML_Char* ns)
+ {
+ document& d (*reinterpret_cast<document*> (data));
+ d.start_namespace_decl_ (prefix, ns);
+ }
+
+ template <typename C>
+ void XMLCALL document<C>::
+ end_namespace_decl_thunk_ (void* data, const XML_Char* prefix)
+ {
+ document& d (*reinterpret_cast<document*> (data));
+ d.end_namespace_decl_ (prefix);
+ }
+
+ namespace bits
+ {
+ inline void
+ split_name (const XML_Char* s,
+ const char*& ns, std::size_t& ns_s,
+ const char*& name, std::size_t& name_s)
+ {
+ const char* p (std::strchr (s, ' '));
+
+ if (p)
+ {
+ ns = s;
+ ns_s = p - s;
+ name = p + 1;
+ }
+ else
+ {
+ ns = s;
+ ns_s = 0;
+ name = s;
+ }
+
+ name_s = std::char_traits<char>::length (name);
+ }
+ }
+
+ template <typename C>
+ void document<C>::
+ start_element_ (const XML_Char* ns_name, const XML_Char** atts)
+ {
+ // Current Expat (2.0.0) has a (mis)-feature of a possibility of
+ // calling callbacks even after the non-resumable XML_StopParser
+ // call. The following code accounts for this.
+ //
+ {
+ XML_ParsingStatus s;
+ XML_GetParsingStatus (xml_parser_, &s);
+ if (s.parsing == XML_FINISHED)
+ return;
+ }
+
+ typedef std::basic_string<C> string;
+
+ const char* ns_p;
+ const char* name_p;
+ size_t ns_s, name_s;
+
+ bits::split_name (ns_name, ns_p, ns_s, name_p, name_s);
+
+ {
+ const ro_string<C> ns (ns_p, ns_s), name (name_p, name_s);
+
+ if (!polymorphic_)
+ {
+ try
+ {
+ start_element (ns, name, 0);
+ }
+ catch (const schema_exception<C>& e)
+ {
+ translate_schema_exception (e);
+ return;
+ }
+ }
+ else
+ {
+ // Search for the xsi:type attribute.
+ //
+ const XML_Char** p = atts; // VC8 can't handle p (atts)
+ for (; *p != 0; p += 2)
+ {
+ bits::split_name (*p, ns_p, ns_s, name_p, name_s);
+ const ro_string<C> ns (ns_p, ns_s), name (name_p, name_s);
+
+ if (name == xml::bits::type<C> () &&
+ ns == xml::bits::xsi_namespace<C> ())
+ break;
+ }
+
+ if (*p == 0)
+ {
+ try
+ {
+ start_element (ns, name, 0);
+ }
+ catch (const schema_exception<C>& e)
+ {
+ translate_schema_exception (e);
+ return;
+ }
+ }
+ else
+ {
+ // @@ Need proper QName validation.
+ //
+ // Get the qualified type name and try to resolve it.
+ //
+ ro_string<C> qn (*(p + 1));
+
+ ro_string<C> tp, tn;
+ typename ro_string<C>::size_type pos (qn.find (C (':')));
+
+ try
+ {
+ if (pos != ro_string<C>::npos)
+ {
+ tp.assign (qn.data (), pos);
+ tn.assign (qn.data () + pos + 1);
+
+ if (tp.empty ())
+ throw dynamic_type<C> (qn);
+ }
+ else
+ tn.assign (qn.data (), qn.size ());
+
+ if (tn.empty ())
+ throw dynamic_type<C> (qn);
+
+ // Search our namespace declaration stack. Note that
+ // we need to do this even if prefix is empty. Sun CC
+ // 5.7 blows if we use const_reverse_iterator.
+ //
+ ro_string<C> tns;
+ for (typename ns_decls::reverse_iterator
+ it (ns_decls_.rbegin ()), e (ns_decls_.rend ());
+ it != e; ++it)
+ {
+ if (it->prefix == tp)
+ {
+ tns.assign (it->ns);
+ break;
+ }
+ }
+
+ if (!tp.empty () && tns.empty ())
+ {
+ // The 'xml' prefix requires special handling.
+ //
+ if (tp == xml::bits::xml_prefix<C> ())
+ tns.assign (xml::bits::xml_namespace<C> ());
+ else
+ throw dynamic_type<C> (qn);
+ }
+
+ // Construct the compound type id.
+ //
+ string id (tn.data (), tn.size ());
+
+ if (!tns.empty ())
+ {
+ id += C (' ');
+ id.append (tns.data (), tns.size ());
+ }
+
+ ro_string<C> ro_id (id);
+ start_element (ns, name, &ro_id);
+ }
+ catch (const schema_exception<C>& e)
+ {
+ translate_schema_exception (e);
+ return;
+ }
+ }
+ }
+ }
+
+ for (; *atts != 0; atts += 2)
+ {
+ bits::split_name (*atts, ns_p, ns_s, name_p, name_s);
+
+ const ro_string<C> ns (ns_p, ns_s), name (name_p, name_s);
+ const ro_string<C> value (*(atts + 1));
+
+ try
+ {
+ attribute (ns, name, value);
+ }
+ catch (const schema_exception<C>& e)
+ {
+ translate_schema_exception (e);
+ break;
+ }
+ }
+ }
+
+ template <typename C>
+ void document<C>::
+ end_element_ (const XML_Char* ns_name)
+ {
+ // Current Expat (2.0.0) has a (mis)-feature of a possibility of
+ // calling callbacks even after the non-resumable XML_StopParser
+ // call. The following code accounts for this.
+ //
+ {
+ XML_ParsingStatus s;
+ XML_GetParsingStatus (xml_parser_, &s);
+ if (s.parsing == XML_FINISHED)
+ return;
+ }
+
+ const char* ns_p;
+ const char* name_p;
+ size_t ns_s, name_s;
+
+ bits::split_name (ns_name, ns_p, ns_s, name_p, name_s);
+
+ const ro_string<C> ns (ns_p, ns_s), name (name_p, name_s);
+
+ try
+ {
+ end_element (ns, name);
+ }
+ catch (const schema_exception<C>& e)
+ {
+ translate_schema_exception (e);
+ }
+ }
+
+ template <typename C>
+ void document<C>::
+ characters_ (const XML_Char* s, std::size_t n)
+ {
+ // Current Expat (2.0.0) has a (mis)-feature of a possibility of
+ // calling callbacks even after the non-resumable XML_StopParser
+ // call. The following code accounts for this.
+ //
+ {
+ XML_ParsingStatus s;
+ XML_GetParsingStatus (xml_parser_, &s);
+ if (s.parsing == XML_FINISHED)
+ return;
+ }
+
+ if (n != 0)
+ {
+ const ro_string<C> str (s, n);
+
+ try
+ {
+ characters (str);
+ }
+ catch (const schema_exception<C>& e)
+ {
+ translate_schema_exception (e);
+ }
+ }
+ }
+
+ template <typename C>
+ void document<C>::
+ start_namespace_decl_ (const XML_Char* p, const XML_Char* ns)
+ {
+ // prefix is 0 for default namespace
+ // namespace is 0 when unsetting default namespace
+ //
+ if (polymorphic_)
+ ns_decls_.push_back (ns_decl ((p ? p : ""), (ns ? ns : "")));
+ }
+
+ template <typename C>
+ void document<C>::
+ end_namespace_decl_ (const XML_Char* p)
+ {
+ // prefix is 0 for default namespace
+ //
+ if (polymorphic_)
+ {
+ // Here we assume the prefixes are removed in the reverse
+ // order of them being added. This appears to how every
+ // sensible implementation works.
+ //
+ assert (p
+ ? ns_decls_.back ().prefix == p
+ : ns_decls_.back ().prefix.empty ());
+
+ ns_decls_.pop_back ();
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/map.hxx b/libxsd/xsd/cxx/parser/map.hxx
new file mode 100644
index 0000000..7d3696a
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/map.hxx
@@ -0,0 +1,79 @@
+// file : xsd/cxx/parser/map.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_MAP_HXX
+#define XSD_CXX_PARSER_MAP_HXX
+
+#include <map>
+#include <string>
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/parser/elements.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // Parser map. Used in the polymorphic document parsing.
+ //
+ template <typename C>
+ struct parser_map
+ {
+ virtual
+ ~parser_map ();
+
+ // The type argument is the type name and namespace from the
+ // xsi:type attribute or substitution group map in the form
+ // "<name> <namespace>" with the space and namespace part
+ // absent if the type does not have a namespace.
+ //
+ virtual parser_base<C>*
+ find (const ro_string<C>& type) const = 0;
+ };
+
+
+ // Parser map implementation.
+ //
+ template <typename C>
+ struct parser_map_impl: parser_map<C>
+ {
+ parser_map_impl ();
+
+ void
+ insert (parser_base<C>&);
+
+ virtual parser_base<C>*
+ find (const ro_string<C>& type) const;
+
+ private:
+ parser_map_impl (const parser_map_impl&);
+
+ parser_map_impl&
+ operator= (const parser_map_impl&);
+
+ private:
+ struct string_comparison
+ {
+ bool
+ operator() (const C* x, const C* y) const
+ {
+ ro_string<C> s (x);
+ return s.compare (y) < 0;
+ }
+ };
+
+ typedef std::map<const C*, parser_base<C>*, string_comparison> map;
+ map map_;
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/parser/map.ixx>
+#include <xsd/cxx/parser/map.txx>
+
+#endif // XSD_CXX_PARSER_MAP_HXX
diff --git a/libxsd/xsd/cxx/parser/map.ixx b/libxsd/xsd/cxx/parser/map.ixx
new file mode 100644
index 0000000..17ac4e4
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/map.ixx
@@ -0,0 +1,27 @@
+// file : xsd/cxx/parser/map.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // parser_map_impl
+ //
+ template <typename C>
+ inline parser_map_impl<C>::parser_map_impl ()
+ {
+ }
+
+ template <typename C>
+ inline void parser_map_impl<C>::
+ insert (parser_base<C>& parser)
+ {
+ map_[parser._dynamic_type ()] = &parser;
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/map.txx b/libxsd/xsd/cxx/parser/map.txx
new file mode 100644
index 0000000..5d31894
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/map.txx
@@ -0,0 +1,31 @@
+// file : xsd/cxx/parser/map.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // parser_map
+ //
+ template <typename C>
+ parser_map<C>::
+ ~parser_map ()
+ {
+ }
+
+ // parser_map_impl
+ //
+ template <typename C>
+ parser_base<C>* parser_map_impl<C>::
+ find (const ro_string<C>& type) const
+ {
+ typename map::const_iterator i (map_.find (type.data ()));
+ return i != map_.end () ? i->second : 0;
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/non-validating/parser.hxx b/libxsd/xsd/cxx/parser/non-validating/parser.hxx
new file mode 100644
index 0000000..480d8ab
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/non-validating/parser.hxx
@@ -0,0 +1,248 @@
+// file : xsd/cxx/parser/non-validating/parser.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_NON_VALIDATING_PARSER_HXX
+#define XSD_CXX_PARSER_NON_VALIDATING_PARSER_HXX
+
+#include <stack>
+#include <string>
+#include <cstddef> // std::size_t
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/parser/elements.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace non_validating
+ {
+ //
+ //
+ template <typename C>
+ struct empty_content: parser_base<C>
+ {
+ // The _*_any_* functions are called when wildcard content
+ // is encountered. Use them to handle mixed content models,
+ // any/anyAttribute, and anyType/anySimpleType. By default
+ // these functions do nothing.
+ //
+
+ // The type argument is a type name and namespace from the
+ // xsi:type attribute in the form "<name> <namespace>" with
+ // the space and namespace part absent if the type does not
+ // have a namespace or 0 if xsi:type is not present.
+ //
+ virtual void
+ _start_any_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type);
+
+ virtual void
+ _end_any_element (const ro_string<C>& ns,
+ const ro_string<C>& name);
+
+ virtual void
+ _any_attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value);
+
+ virtual void
+ _any_characters (const ro_string<C>&);
+
+
+ //
+ //
+ virtual bool
+ _start_element_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>*);
+
+ virtual bool
+ _end_element_impl (const ro_string<C>&,
+ const ro_string<C>&);
+
+ virtual bool
+ _attribute_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&);
+
+ virtual bool
+ _characters_impl (const ro_string<C>&);
+
+
+ //
+ //
+ virtual void
+ _start_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type);
+
+ virtual void
+ _end_element (const ro_string<C>& ns,
+ const ro_string<C>& name);
+
+ virtual void
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value);
+
+ virtual void
+ _characters (const ro_string<C>& s);
+ };
+
+
+ //
+ //
+ template <typename C>
+ struct simple_content: empty_content<C>
+ {
+ //
+ //
+ virtual void
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value);
+
+ virtual void
+ _characters (const ro_string<C>&);
+ };
+
+
+ //
+ //
+ template <typename C>
+ struct complex_content: empty_content<C>
+ {
+ //
+ //
+ virtual void
+ _start_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type);
+
+ virtual void
+ _end_element (const ro_string<C>& ns,
+ const ro_string<C>& name);
+
+ virtual void
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value);
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+
+ //
+ //
+ virtual void
+ _pre_impl ();
+
+ virtual void
+ _post_impl ();
+
+ protected:
+ struct state
+ {
+ state ()
+ : any_ (false), depth_ (0), parser_ (0)
+ {
+ }
+
+ bool any_;
+ std::size_t depth_;
+ parser_base<C>* parser_;
+ };
+
+ // Optimized state stack for non-recursive case (one element).
+ //
+ struct state_stack
+ {
+ state_stack ()
+ : size_ (0)
+ {
+ }
+
+ void
+ push (const state& s)
+ {
+ if (size_ > 0)
+ rest_.push (top_);
+
+ top_ = s;
+ ++size_;
+ }
+
+ void
+ pop ()
+ {
+ if (size_ > 1)
+ {
+ top_ = rest_.top ();
+ rest_.pop ();
+ }
+
+ --size_;
+ }
+
+ const state&
+ top () const
+ {
+ return top_;
+ }
+
+ state&
+ top ()
+ {
+ return top_;
+ }
+
+ state&
+ under_top ()
+ {
+ return rest_.top ();
+ }
+
+ private:
+ state top_;
+ std::stack<state> rest_;
+ std::size_t size_;
+ };
+
+ state_stack context_;
+ };
+
+
+ // Base for xsd:list.
+ //
+ template <typename C>
+ struct list_base: simple_content<C>
+ {
+ virtual void
+ _xsd_parse_item (const ro_string<C>&) = 0;
+
+ virtual void
+ _pre_impl ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post_impl ();
+
+ protected:
+ std::basic_string<C> buf_;
+ };
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/parser/non-validating/parser.txx>
+
+#endif // XSD_CXX_PARSER_NON_VALIDATING_PARSER_HXX
diff --git a/libxsd/xsd/cxx/parser/non-validating/parser.txx b/libxsd/xsd/cxx/parser/non-validating/parser.txx
new file mode 100644
index 0000000..d379d7a
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/non-validating/parser.txx
@@ -0,0 +1,464 @@
+// file : xsd/cxx/parser/non-validating/parser.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cassert>
+
+#include <xsd/cxx/xml/bits/literals.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace non_validating
+ {
+
+ // empty_content
+ //
+
+ template <typename C>
+ void empty_content<C>::
+ _start_any_element (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>*)
+ {
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _end_any_element (const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _any_attribute (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _any_characters (const ro_string<C>&)
+ {
+ }
+
+ //
+ //
+ template <typename C>
+ bool empty_content<C>::
+ _start_element_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>*)
+ {
+ return false;
+ }
+
+ template <typename C>
+ bool empty_content<C>::
+ _end_element_impl (const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ return false;
+ }
+
+ template <typename C>
+ bool empty_content<C>::
+ _attribute_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ return false;
+ }
+
+ template <typename C>
+ bool empty_content<C>::
+ _characters_impl (const ro_string<C>&)
+ {
+ return false;
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _start_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type)
+ {
+ if (!_start_element_impl (ns, name, type))
+ _start_any_element (ns, name, type);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _end_element (const ro_string<C>& ns,
+ const ro_string<C>& name)
+ {
+ if (!_end_element_impl (ns, name))
+ _end_any_element (ns, name);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ // Weed out special attributes: xsi:type, xsi:nil,
+ // xsi:schemaLocation and noNamespaceSchemaLocation.
+ // See section 3.2.7 in Structures for details.
+ //
+ if (ns == xml::bits::xsi_namespace<C> () &&
+ (name == xml::bits::type<C> () ||
+ name == xml::bits::nil<C> () ||
+ name == xml::bits::schema_location<C> () ||
+ name == xml::bits::no_namespace_schema_location<C> ()))
+ return;
+
+ // Also some parsers (notably Xerces-C++) supplies us with
+ // namespace-prefix mapping attributes.
+ //
+ if (ns == xml::bits::xmlns_namespace<C> ())
+ return;
+
+ if (!_attribute_impl (ns, name, value))
+ _any_attribute (ns, name, value);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (!_characters_impl (s))
+ _any_characters (s);
+ }
+
+
+ // simple_content
+ //
+
+ template <typename C>
+ void simple_content<C>::
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ // Weed out special attributes: xsi:type, xsi:nil,
+ // xsi:schemaLocation and xsi:noNamespaceSchemaLocation.
+ // See section 3.2.7 in Structures for details.
+ //
+ if (ns == xml::bits::xsi_namespace<C> () &&
+ (name == xml::bits::type<C> () ||
+ name == xml::bits::nil<C> () ||
+ name == xml::bits::schema_location<C> () ||
+ name == xml::bits::no_namespace_schema_location<C> ()))
+ return;
+
+ // Also some parsers (notably Xerces-C++) supplies us with
+ // namespace-prefix mapping attributes.
+ //
+ if (ns == xml::bits::xmlns_namespace<C> ())
+ return;
+
+ if (!_attribute_impl (ns, name, value))
+ _any_attribute (ns, name, value);
+ }
+
+ template <typename C>
+ void simple_content<C>::
+ _characters (const ro_string<C>& str)
+ {
+ _characters_impl (str);
+ }
+
+
+ // complex_content
+ //
+
+ template <typename C>
+ void complex_content<C>::
+ _start_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type)
+ {
+ state& s (context_.top ());
+
+ if (s.depth_++ > 0)
+ {
+ if (s.any_)
+ _start_any_element (ns, name, type);
+ else if (s.parser_)
+ s.parser_->_start_element (ns, name, type);
+ }
+ else
+ {
+ if (!_start_element_impl (ns, name, type))
+ {
+ _start_any_element (ns, name, type);
+ s.any_ = true;
+ }
+ else if (s.parser_ != 0)
+ s.parser_->_pre_impl ();
+ }
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _end_element (const ro_string<C>& ns,
+ const ro_string<C>& name)
+ {
+ // To understand what's going on here it is helpful to think of
+ // a "total depth" as being the sum of individual depths over
+ // all elements.
+ //
+
+ if (context_.top ().depth_ == 0)
+ {
+ state& s (context_.under_top ()); // One before last.
+
+ if (--s.depth_ > 0)
+ {
+ // Indirect recursion.
+ //
+ if (s.parser_)
+ s.parser_->_end_element (ns, name);
+ }
+ else
+ {
+ // Direct recursion.
+ //
+ assert (this == s.parser_);
+
+ this->_post_impl ();
+
+ if (!_end_element_impl (ns, name))
+ assert (false);
+ }
+ }
+ else
+ {
+ state& s (context_.top ());
+
+ if (--s.depth_ > 0)
+ {
+ if (s.any_)
+ _end_any_element (ns, name);
+ else if (s.parser_)
+ s.parser_->_end_element (ns, name);
+ }
+ else
+ {
+ if (s.parser_ != 0 && !s.any_)
+ s.parser_->_post_impl ();
+
+ if (!_end_element_impl (ns, name))
+ {
+ s.any_ = false;
+ _end_any_element (ns, name);
+ }
+ }
+ }
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ // Weed out special attributes: xsi:type, xsi:nil,
+ // xsi:schemaLocation and xsi:noNamespaceSchemaLocation.
+ // See section 3.2.7 in Structures for details.
+ //
+ if (ns == xml::bits::xsi_namespace<C> () &&
+ (name == xml::bits::type<C> () ||
+ name == xml::bits::nil<C> () ||
+ name == xml::bits::schema_location<C> () ||
+ name == xml::bits::no_namespace_schema_location<C> ()))
+ return;
+
+ // Also some parsers (notably Xerces-C++) supplies us with
+ // namespace-prefix mapping attributes.
+ //
+ if (ns == xml::bits::xmlns_namespace<C> ())
+ return;
+
+ state& s (context_.top ());
+
+ if (s.depth_ > 0)
+ {
+ if (s.any_)
+ _any_attribute (ns, name, value);
+ else if (s.parser_)
+ s.parser_->_attribute (ns, name, value);
+ }
+ else
+ {
+ if (!_attribute_impl (ns, name, value))
+ _any_attribute (ns, name, value);
+ }
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _characters (const ro_string<C>& str)
+ {
+ state& s (context_.top ());
+
+ if (s.depth_ > 0)
+ {
+ if (s.any_)
+ _any_characters (str);
+ else if (s.parser_)
+ s.parser_->_characters (str);
+ }
+ else
+ {
+ if (!_characters_impl (str))
+ _any_characters (str);
+ }
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _pre_impl ()
+ {
+ context_.push (state ());
+ this->_pre ();
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _post_impl ()
+ {
+ this->_post ();
+ context_.pop ();
+ }
+
+ // list_base
+ //
+ namespace bits
+ {
+ // Find first non-space character.
+ //
+ template <typename C>
+ typename ro_string<C>::size_type
+ find_ns (const C* s,
+ typename ro_string<C>::size_type size,
+ typename ro_string<C>::size_type pos)
+ {
+ while (pos < size &&
+ (s[pos] == C (0x20) || s[pos] == C (0x0A) ||
+ s[pos] == C (0x0D) || s[pos] == C (0x09)))
+ ++pos;
+
+ return pos < size ? pos : ro_string<C>::npos;
+ }
+
+ // Find first space character.
+ //
+ template <typename C>
+ typename ro_string<C>::size_type
+ find_s (const C* s,
+ typename ro_string<C>::size_type size,
+ typename ro_string<C>::size_type pos)
+ {
+ while (pos < size &&
+ s[pos] != C (0x20) && s[pos] != C (0x0A) &&
+ s[pos] != C (0x0D) && s[pos] != C (0x09))
+ ++pos;
+
+ return pos < size ? pos : ro_string<C>::npos;
+ }
+ }
+
+ // Relevant XML Schema Part 2: Datatypes sections: 4.2.1.2, 4.3.6.
+ //
+
+ template <typename C>
+ void list_base<C>::
+ _pre_impl ()
+ {
+ simple_content<C>::_pre_impl ();
+ buf_.clear ();
+ }
+
+ template <typename C>
+ void list_base<C>::
+ _characters (const ro_string<C>& s)
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ const C* data (s.data ());
+ size_type size (s.size ());
+
+ // Handle the previous chunk if we start with a ws.
+ //
+ if (!buf_.empty () &&
+ (data[0] == C (0x20) || data[0] == C (0x0A) ||
+ data[0] == C (0x0D) || data[0] == C (0x09)))
+ {
+ ro_string<C> tmp (buf_); // Private copy ctor.
+ _xsd_parse_item (tmp);
+ buf_.clear ();
+ }
+
+ // Traverse the data while logically collapsing spaces.
+ //
+ for (size_type i (bits::find_ns (data, size, 0));
+ i != ro_string<C>::npos;)
+ {
+ size_type j (bits::find_s (data, size, i));
+
+ if (j != ro_string<C>::npos)
+ {
+ if (buf_.empty ())
+ {
+ ro_string<C> tmp (data + i, j - i); // Private copy ctor.
+ _xsd_parse_item (tmp);
+ }
+ else
+ {
+ // Assemble the first item in str from buf_ and s.
+ //
+ std::basic_string<C> str;
+ str.swap (buf_);
+ str.append (data + i, j - i);
+ ro_string<C> tmp (str); // Private copy ctor.
+ _xsd_parse_item (tmp);
+ }
+
+ i = bits::find_ns (data, size, j);
+ }
+ else
+ {
+ // Last fragment, append it to the buf_.
+ //
+ buf_.append (data + i, size - i);
+ break;
+ }
+ }
+ }
+
+ template <typename C>
+ void list_base<C>::
+ _post_impl ()
+ {
+ // Handle the last item.
+ //
+ if (!buf_.empty ())
+ {
+ ro_string<C> tmp (buf_); // Private copy ctor.
+ _xsd_parse_item (tmp);
+ }
+
+ simple_content<C>::_post_impl ();
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.hxx b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.hxx
new file mode 100644
index 0000000..0e8443d
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.hxx
@@ -0,0 +1,791 @@
+// file : xsd/cxx/parser/non-validating/xml-schema-pimpl.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_HXX
+#define XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_HXX
+
+#include <string>
+
+#include <xsd/cxx/parser/non-validating/xml-schema-pskel.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace non_validating
+ {
+ // any_type
+ //
+ template <typename C>
+ struct any_type_pimpl: virtual any_type_pskel<C>
+ {
+ virtual void
+ post_any_type ();
+ };
+
+ // any_simple_type
+ //
+ template <typename C>
+ struct any_simple_type_pimpl: virtual any_simple_type_pskel<C>
+ {
+ virtual void
+ post_any_simple_type ();
+ };
+
+ // boolean
+ //
+ template <typename C>
+ struct boolean_pimpl: virtual boolean_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual bool
+ post_boolean ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+
+ // 8-bit
+ //
+ template <typename C>
+ struct byte_pimpl: virtual byte_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual signed char
+ post_byte ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+
+ template <typename C>
+ struct unsigned_byte_pimpl: virtual unsigned_byte_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual unsigned char
+ post_unsigned_byte ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+
+ // 16-bit
+ //
+ template <typename C>
+ struct short_pimpl: virtual short_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual short
+ post_short ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+
+ template <typename C>
+ struct unsigned_short_pimpl: virtual unsigned_short_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual unsigned short
+ post_unsigned_short ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+
+ // 32-bit
+ //
+ template <typename C>
+ struct int_pimpl: virtual int_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual int
+ post_int ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+
+ template <typename C>
+ struct unsigned_int_pimpl: virtual unsigned_int_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual unsigned int
+ post_unsigned_int ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+
+ // 64-bit
+ //
+ template <typename C>
+ struct long_pimpl: virtual long_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual long long
+ post_long ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+
+ template <typename C>
+ struct unsigned_long_pimpl: virtual unsigned_long_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual unsigned long long
+ post_unsigned_long ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+
+ // Arbitrary-length integers.
+ //
+ template <typename C>
+ struct integer_pimpl: virtual integer_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual long long
+ post_integer ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct negative_integer_pimpl: virtual negative_integer_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual long long
+ post_negative_integer ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct non_positive_integer_pimpl: virtual non_positive_integer_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual long long
+ post_non_positive_integer ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct positive_integer_pimpl: virtual positive_integer_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual unsigned long long
+ post_positive_integer ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct non_negative_integer_pimpl: virtual non_negative_integer_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual unsigned long long
+ post_non_negative_integer ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+
+ // Floats.
+ //
+ template <typename C>
+ struct float_pimpl: virtual float_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual float
+ post_float ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+
+ template <typename C>
+ struct double_pimpl: virtual double_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual double
+ post_double ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+
+ template <typename C>
+ struct decimal_pimpl: virtual decimal_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual double
+ post_decimal ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+
+ // Strings.
+ //
+ template <typename C>
+ struct string_pimpl: virtual string_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_string ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct normalized_string_pimpl: virtual normalized_string_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_normalized_string ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct token_pimpl: virtual token_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_token ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct name_pimpl: virtual name_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_name ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct nmtoken_pimpl: virtual nmtoken_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_nmtoken ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct nmtokens_pimpl: virtual nmtokens_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _xsd_parse_item (const ro_string<C>&);
+
+ virtual string_sequence<C>
+ post_nmtokens ();
+
+ protected:
+ string_sequence<C> seq_;
+ nmtoken_pimpl<C> parser_;
+ };
+
+ template <typename C>
+ struct ncname_pimpl: virtual ncname_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_ncname ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct id_pimpl: virtual id_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_id ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct idref_pimpl: virtual idref_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_idref ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct idrefs_pimpl: virtual idrefs_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _xsd_parse_item (const ro_string<C>&);
+
+ virtual string_sequence<C>
+ post_idrefs ();
+
+ protected:
+ string_sequence<C> seq_;
+ idref_pimpl<C> parser_;
+ };
+
+ // language
+ //
+ template <typename C>
+ struct language_pimpl: virtual language_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_language ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // anyURI
+ //
+ template <typename C>
+ struct uri_pimpl: virtual uri_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_uri ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // QName
+ //
+ template <typename C>
+ struct qname_pimpl: virtual qname_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual qname<C>
+ post_qname ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // base64Binary
+ //
+ template <typename C>
+ struct base64_binary_pimpl: virtual base64_binary_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::auto_ptr<buffer>
+ post_base64_binary ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // hexBinary
+ //
+ template <typename C>
+ struct hex_binary_pimpl: virtual hex_binary_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::auto_ptr<buffer>
+ post_hex_binary ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // gday
+ //
+ template <typename C>
+ struct gday_pimpl: virtual gday_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual gday
+ post_gday ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // gmonth
+ //
+ template <typename C>
+ struct gmonth_pimpl: virtual gmonth_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual gmonth
+ post_gmonth ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // gyear
+ //
+ template <typename C>
+ struct gyear_pimpl: virtual gyear_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual gyear
+ post_gyear ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // gmonth_day
+ //
+ template <typename C>
+ struct gmonth_day_pimpl: virtual gmonth_day_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual gmonth_day
+ post_gmonth_day ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // gyear_month
+ //
+ template <typename C>
+ struct gyear_month_pimpl: virtual gyear_month_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual gyear_month
+ post_gyear_month ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // date
+ //
+ template <typename C>
+ struct date_pimpl: virtual date_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual date
+ post_date ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // time
+ //
+ template <typename C>
+ struct time_pimpl: virtual time_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual time
+ post_time ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // date_time
+ //
+ template <typename C>
+ struct date_time_pimpl: virtual date_time_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual date_time
+ post_date_time ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // duration
+ //
+ template <typename C>
+ struct duration_pimpl: virtual duration_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual duration
+ post_duration ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ //
+ //
+ namespace bits
+ {
+ // float literals: INF -INF NaN
+ //
+ template<typename C>
+ const C*
+ positive_inf ();
+
+ template<typename C>
+ const C*
+ negative_inf ();
+
+ template<typename C>
+ const C*
+ nan ();
+
+ // boolean literals
+ //
+ template<typename C>
+ const C*
+ true_ ();
+
+ template<typename C>
+ const C*
+ one ();
+ }
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/parser/non-validating/xml-schema-pimpl.txx>
+
+#endif // XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_HXX
+
+#include <xsd/cxx/parser/non-validating/xml-schema-pimpl.ixx>
diff --git a/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.ixx b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.ixx
new file mode 100644
index 0000000..0220117
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.ixx
@@ -0,0 +1,129 @@
+// file : xsd/cxx/parser/non-validating/xml-schema-pimpl.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR)
+
+#ifndef XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_IXX_CHAR
+#define XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_IXX_CHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace non_validating
+ {
+ namespace bits
+ {
+ //
+ //
+ template<>
+ inline const char*
+ positive_inf<char> ()
+ {
+ return "INF";
+ }
+
+ template<>
+ inline const char*
+ negative_inf<char> ()
+ {
+ return "-INF";
+ }
+
+ template<>
+ inline const char*
+ nan<char> ()
+ {
+ return "NaN";
+ }
+
+ //
+ //
+ template<>
+ inline const char*
+ true_<char> ()
+ {
+ return "true";
+ }
+
+ template<>
+ inline const char*
+ one<char> ()
+ {
+ return "1";
+ }
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_IXX_CHAR
+#endif // XSD_CXX_PARSER_USE_CHAR
+
+
+#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR)
+
+#ifndef XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_IXX_WCHAR
+#define XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_IXX_WCHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace non_validating
+ {
+ namespace bits
+ {
+ //
+ //
+ template<>
+ inline const wchar_t*
+ positive_inf<wchar_t> ()
+ {
+ return L"INF";
+ }
+
+ template<>
+ inline const wchar_t*
+ negative_inf<wchar_t> ()
+ {
+ return L"-INF";
+ }
+
+ template<>
+ inline const wchar_t*
+ nan<wchar_t> ()
+ {
+ return L"NaN";
+ }
+
+ //
+ //
+ template<>
+ inline const wchar_t*
+ true_<wchar_t> ()
+ {
+ return L"true";
+ }
+
+ template<>
+ inline const wchar_t*
+ one<wchar_t> ()
+ {
+ return L"1";
+ }
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PIMPL_IXX_WCHAR
+#endif // XSD_CXX_PARSER_USE_WCHAR
diff --git a/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.txx b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.txx
new file mode 100644
index 0000000..5ce50d6
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pimpl.txx
@@ -0,0 +1,2068 @@
+// file : xsd/cxx/parser/non-validating/xml-schema-pimpl.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <limits>
+#include <locale>
+
+#include <xsd/cxx/zc-istream.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace non_validating
+ {
+ // Note that most of the types implemented here cannot have
+ // whitespaces in the value. 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.
+ //
+
+ // any_type
+ //
+
+ template <typename C>
+ void any_type_pimpl<C>::
+ post_any_type ()
+ {
+ }
+
+ // any_simple_type
+ //
+
+ template <typename C>
+ void any_simple_type_pimpl<C>::
+ post_any_simple_type ()
+ {
+ }
+
+ // boolean
+ //
+ template <typename C>
+ void boolean_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void boolean_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ bool boolean_pimpl<C>::
+ post_boolean ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ return str == bits::true_<C> () || str == bits::one<C> ();
+ }
+
+ // byte
+ //
+
+ template <typename C>
+ void byte_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void byte_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ signed char byte_pimpl<C>::
+ post_byte ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ short t;
+ zc_istream<C> is (str);
+ is >> t;
+
+ return static_cast<signed char> (t);
+ }
+
+ // unsigned_byte
+ //
+
+ template <typename C>
+ void unsigned_byte_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void unsigned_byte_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ unsigned char unsigned_byte_pimpl<C>::
+ post_unsigned_byte ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ unsigned short t;
+ zc_istream<C> is (str);
+ is >> t;
+
+ return static_cast<unsigned char> (t);
+ }
+
+ // short
+ //
+
+ template <typename C>
+ void short_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void short_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ short short_pimpl<C>::
+ post_short ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ short t;
+ zc_istream<C> is (str);
+ is >> t;
+
+ return t;
+ }
+
+ // unsigned_short
+ //
+
+ template <typename C>
+ void unsigned_short_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void unsigned_short_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ unsigned short unsigned_short_pimpl<C>::
+ post_unsigned_short ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ unsigned short t;
+ zc_istream<C> is (str);
+ is >> t;
+
+ return t;
+ }
+
+ // int
+ //
+
+ template <typename C>
+ void int_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void int_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ int int_pimpl<C>::
+ post_int ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ int t;
+ zc_istream<C> is (str);
+ is >> t;
+
+ return t;
+ }
+
+ // unsigned_int
+ //
+
+ template <typename C>
+ void unsigned_int_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void unsigned_int_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ unsigned int unsigned_int_pimpl<C>::
+ post_unsigned_int ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ unsigned int t;
+ zc_istream<C> is (str);
+ is >> t;
+
+ return t;
+ }
+
+ // long
+ //
+ template <typename C>
+ void long_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void long_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ long long long_pimpl<C>::
+ post_long ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ long long t;
+ zc_istream<C> is (str);
+ is >> t;
+
+ return t;
+ }
+
+ // unsigned_long
+ //
+ template <typename C>
+ void unsigned_long_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void unsigned_long_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ unsigned long long unsigned_long_pimpl<C>::
+ post_unsigned_long ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ unsigned long long t;
+ zc_istream<C> is (str);
+ is >> t;
+
+ return t;
+ }
+
+ // integer
+ //
+ template <typename C>
+ void integer_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void integer_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ long long integer_pimpl<C>::
+ post_integer ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ long long t;
+ zc_istream<C> is (str);
+ is >> t;
+
+ return t;
+ }
+
+ // negative_integer
+ //
+ template <typename C>
+ void negative_integer_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void negative_integer_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ long long negative_integer_pimpl<C>::
+ post_negative_integer ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ long long t;
+ zc_istream<C> is (str);
+ is >> t;
+
+ return t;
+ }
+
+ // non_positive_integer
+ //
+ template <typename C>
+ void non_positive_integer_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void non_positive_integer_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ long long non_positive_integer_pimpl<C>::
+ post_non_positive_integer ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ long long t;
+ zc_istream<C> is (str);
+ is >> t;
+
+ return t;
+ }
+
+ // positive_integer
+ //
+ template <typename C>
+ void positive_integer_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void positive_integer_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ unsigned long long positive_integer_pimpl<C>::
+ post_positive_integer ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ unsigned long long t;
+ zc_istream<C> is (str);
+ is >> t;
+
+ return t;
+ }
+
+ // non_negative_integer
+ //
+ template <typename C>
+ void non_negative_integer_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void non_negative_integer_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ unsigned long long non_negative_integer_pimpl<C>::
+ post_non_negative_integer ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ unsigned long long t;
+ zc_istream<C> is (str);
+ is >> t;
+
+ return t;
+ }
+
+ // float
+ //
+ template <typename C>
+ void float_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void float_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ float float_pimpl<C>::
+ post_float ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ if (str == bits::positive_inf<C> ())
+ return std::numeric_limits<float>::infinity ();
+
+ if (str == bits::negative_inf<C> ())
+ return -std::numeric_limits<float>::infinity ();
+
+ if (str == bits::nan<C> ())
+ return std::numeric_limits<float>::quiet_NaN ();
+
+ float t;
+ zc_istream<C> is (str);
+ is.imbue (std::locale::classic ());
+ is >> t;
+
+ return t;
+ }
+
+ // double
+ //
+ template <typename C>
+ void double_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void double_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ double double_pimpl<C>::
+ post_double ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ if (str == bits::positive_inf<C> ())
+ return std::numeric_limits<double>::infinity ();
+
+ if (str == bits::negative_inf<C> ())
+ return -std::numeric_limits<double>::infinity ();
+
+ if (str == bits::nan<C> ())
+ return std::numeric_limits<double>::quiet_NaN ();
+
+ double t;
+ zc_istream<C> is (str);
+ is.imbue (std::locale::classic ());
+ is >> t;
+
+ return t;
+ }
+
+ // decimal
+ //
+ template <typename C>
+ void decimal_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void decimal_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ double decimal_pimpl<C>::
+ post_decimal ()
+ {
+ std::basic_string<C> tmp;
+ tmp.swap (str_);
+
+ ro_string<C> str (tmp);
+ trim (str);
+
+ double t;
+ zc_istream<C> is (str);
+ is.imbue (std::locale::classic ());
+ is >> t;
+
+ return t;
+ }
+
+
+ // string
+ //
+ template <typename C>
+ void string_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void string_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> string_pimpl<C>::
+ post_string ()
+ {
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // normalized_string
+ //
+ template <typename C>
+ void normalized_string_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void normalized_string_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> normalized_string_pimpl<C>::
+ post_normalized_string ()
+ {
+ typedef typename std::basic_string<C>::size_type size_type;
+
+ size_type size (str_.size ());
+
+ for (size_type i (0); i < size; ++i)
+ {
+ C& c = str_[i];
+
+ if (c == C (0x0A) || c == C (0x0D) || c == C (0x09))
+ c = C (0x20);
+ }
+
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // token
+ //
+ template <typename C>
+ void token_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void token_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> token_pimpl<C>::
+ post_token ()
+ {
+ typedef typename std::basic_string<C>::size_type size_type;
+
+ size_type size (str_.size ());
+ size_type j (0);
+
+ bool subs (false);
+
+ for (size_type i (0); i < size; ++i)
+ {
+ C c = str_[i];
+
+ if (c == C (0x20) || c == C (0x0A) ||
+ c == C (0x0D) || c == C (0x09))
+ {
+ subs = true;
+ }
+ else
+ {
+ if (subs)
+ {
+ subs = false;
+ str_[j++] = C (0x20);
+ }
+
+ str_[j++] = c;
+ }
+ }
+
+ str_.resize (j);
+
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // name
+ //
+ template <typename C>
+ void name_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void name_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> name_pimpl<C>::
+ post_name ()
+ {
+ ro_string<C> tmp (str_);
+ str_.resize (trim_right (tmp));
+
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // nmtoken
+ //
+ template <typename C>
+ void nmtoken_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void nmtoken_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> nmtoken_pimpl<C>::
+ post_nmtoken ()
+ {
+ ro_string<C> tmp (str_);
+ str_.resize (trim_right (tmp));
+
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // nmtokens
+ //
+ template <typename C>
+ void nmtokens_pimpl<C>::
+ _pre ()
+ {
+ nmtokens_pskel<C>::_pre ();
+ seq_.clear ();
+ }
+
+ template <typename C>
+ string_sequence<C> nmtokens_pimpl<C>::
+ post_nmtokens ()
+ {
+ string_sequence<C> r;
+ r.swap (seq_);
+ return r;
+ }
+
+ template <typename C>
+ void nmtokens_pimpl<C>::
+ _xsd_parse_item (const ro_string<C>& s)
+ {
+ parser_.pre ();
+ parser_._pre ();
+ parser_._characters (s);
+ parser_._post ();
+ seq_.push_back (parser_.post_nmtoken ());
+ }
+
+ // ncname
+ //
+ template <typename C>
+ void ncname_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void ncname_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> ncname_pimpl<C>::
+ post_ncname ()
+ {
+ ro_string<C> tmp (str_);
+ str_.resize (trim_right (tmp));
+
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // id
+ //
+ template <typename C>
+ void id_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void id_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> id_pimpl<C>::
+ post_id ()
+ {
+ ro_string<C> tmp (str_);
+ str_.resize (trim_right (tmp));
+
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // idref
+ //
+ template <typename C>
+ void idref_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void idref_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> idref_pimpl<C>::
+ post_idref ()
+ {
+ ro_string<C> tmp (str_);
+ str_.resize (trim_right (tmp));
+
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // idrefs
+ //
+ template <typename C>
+ void idrefs_pimpl<C>::
+ _pre ()
+ {
+ idrefs_pskel<C>::_pre ();
+ seq_.clear ();
+ }
+
+ template <typename C>
+ string_sequence<C> idrefs_pimpl<C>::
+ post_idrefs ()
+ {
+ string_sequence<C> r;
+ r.swap (seq_);
+ return r;
+ }
+
+ template <typename C>
+ void idrefs_pimpl<C>::
+ _xsd_parse_item (const ro_string<C>& s)
+ {
+ parser_.pre ();
+ parser_._pre ();
+ parser_._characters (s);
+ parser_._post ();
+ seq_.push_back (parser_.post_idref ());
+ }
+
+ // language
+ //
+ template <typename C>
+ void language_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void language_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> language_pimpl<C>::
+ post_language ()
+ {
+ ro_string<C> tmp (str_);
+ str_.resize (trim_right (tmp));
+
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // uri
+ //
+ template <typename C>
+ void uri_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void uri_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> uri_pimpl<C>::
+ post_uri ()
+ {
+ ro_string<C> tmp (str_);
+ str_.resize (trim_right (tmp));
+
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // qname
+ //
+ template <typename C>
+ void qname_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void qname_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ qname<C> qname_pimpl<C>::
+ post_qname ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ size_type pos (tmp.find (C (':')));
+
+ if (pos != ro_string<C>::npos)
+ {
+ std::basic_string<C> prefix (tmp.data (), pos++);
+ std::basic_string<C> name (tmp.data () + pos, size - pos);
+ return qname<C> (prefix, name);
+ }
+ else
+ {
+ str_.resize (size);
+ return qname<C> (str_);
+ }
+ }
+
+ // base64_binary
+ //
+ template <typename C>
+ void base64_binary_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void base64_binary_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ namespace bits
+ {
+ template <typename C>
+ inline unsigned char
+ base64_decode (C c)
+ {
+ unsigned char r (0xFF);
+
+ if (c >= C('A') && c <= C ('Z'))
+ r = static_cast<unsigned char> (c - C ('A'));
+ else if (c >= C('a') && c <= C ('z'))
+ r = static_cast<unsigned char> (c - C ('a') + 26);
+ else if (c >= C('0') && c <= C ('9'))
+ r = static_cast<unsigned char> (c - C ('0') + 52);
+ else if (c == C ('+'))
+ r = 62;
+ else if (c == C ('/'))
+ r = 63;
+
+ return r;
+ }
+ }
+
+ template <typename C>
+ std::auto_ptr<buffer> base64_binary_pimpl<C>::
+ post_base64_binary ()
+ {
+ typedef typename std::basic_string<C>::size_type size_type;
+
+ size_type size (str_.size ());
+ const C* src (str_.c_str ());
+
+ // Remove all whitespaces.
+ //
+ {
+ size_type j (0);
+
+ bool subs (false);
+
+ for (size_type i (0); i < size; ++i)
+ {
+ C c = str_[i];
+
+ if (c == C (0x20) || c == C (0x0A) ||
+ c == C (0x0D) || c == C (0x09))
+ {
+ subs = true;
+ }
+ else
+ {
+ if (subs)
+ subs = false;
+
+ str_[j++] = c;
+ }
+ }
+
+ size = j;
+ str_.resize (size);
+ }
+
+ // Our length should be a multiple of four.
+ //
+ size_type quad_count (size / 4);
+ size_type capacity (quad_count * 3 + 1);
+
+ std::auto_ptr<buffer> buf (new buffer (capacity, capacity));
+ char* dst (buf->data ());
+
+ size_type si (0), di (0); // Source and destination indexes.
+
+ // Process all quads except the last one.
+ //
+ unsigned char b1, b2, b3, b4;
+
+ for (size_type q (0); q < quad_count - 1; ++q)
+ {
+ b1 = bits::base64_decode (src[si++]);
+ b2 = bits::base64_decode (src[si++]);
+ b3 = bits::base64_decode (src[si++]);
+ b4 = bits::base64_decode (src[si++]);
+
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ dst[di++] = (b2 << 4) | (b3 >> 2);
+ dst[di++] = (b3 << 6) | b4;
+ }
+
+ // Process the last quad. The first two octets are always there.
+ //
+ b1 = bits::base64_decode (src[si++]);
+ b2 = bits::base64_decode (src[si++]);
+
+ C e3 (src[si++]);
+ C e4 (src[si++]);
+
+ if (e4 == C ('='))
+ {
+ if (e3 == C ('='))
+ {
+ // Two pads. Last 4 bits in b2 should be zero.
+ //
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ }
+ else
+ {
+ // One pad. Last 2 bits in b3 should be zero.
+ //
+ b3 = bits::base64_decode (e3);
+
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ dst[di++] = (b2 << 4) | (b3 >> 2);
+ }
+ }
+ else
+ {
+ // No pads.
+ //
+ b3 = bits::base64_decode (e3);
+ b4 = bits::base64_decode (e4);
+
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ dst[di++] = (b2 << 4) | (b3 >> 2);
+ dst[di++] = (b3 << 6) | b4;
+ }
+
+ // Set the real size.
+ //
+ buf->size (di);
+
+ return buf;
+ }
+
+ // hex_binary
+ //
+ template <typename C>
+ void hex_binary_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void hex_binary_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ namespace bits
+ {
+ template <typename C>
+ inline unsigned char
+ hex_decode (C c)
+ {
+ unsigned char r (0xFF);
+
+ if (c >= C('0') && c <= C ('9'))
+ r = static_cast<unsigned char> (c - C ('0'));
+ else if (c >= C ('A') && c <= C ('F'))
+ r = static_cast<unsigned char> (10 + (c - C ('A')));
+ else if (c >= C ('a') && c <= C ('f'))
+ r = static_cast<unsigned char> (10 + (c - C ('a')));
+
+ return r;
+ }
+ }
+
+ template <typename C>
+ std::auto_ptr<buffer> hex_binary_pimpl<C>::
+ post_hex_binary ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+
+ buffer::size_t n (size / 2);
+ std::auto_ptr<buffer> buf (new buffer (n));
+
+ const C* src (tmp.data ());
+ char* dst (buf->data ());
+
+ for (buffer::size_t i (0); i < n; ++i)
+ {
+ unsigned char h (bits::hex_decode (src[2 * i]));
+ unsigned char l (bits::hex_decode (src[2 * i + 1]));
+ dst[i] = (h << 4) | l;
+ }
+
+ return buf;
+ }
+
+ // time_zone
+ //
+ namespace bits
+ {
+ // Datatypes 3.2.7.3.
+ //
+ template <typename C>
+ void
+ parse_tz (const C* s,
+ typename std::basic_string<C>::size_type n,
+ short& h, short& m)
+ {
+ // time_zone := Z|(+|-)HH:MM
+ //
+ if (n == 0)
+ {
+ return;
+ }
+ else if (s[0] == 'Z')
+ {
+ h = 0;
+ m = 0;
+ }
+ else if (n == 6)
+ {
+ // Parse hours.
+ //
+ h = 10 * (s[1] - '0') + (s[2] - '0');
+
+ // Parse minutes.
+ //
+ m = 10 * (s[4] - '0') + (s[5] - '0');
+
+ if (s[0] == '-')
+ {
+ h = -h;
+ m = -m;
+ }
+ }
+ }
+ }
+
+ // gday
+ //
+ template <typename C>
+ void gday_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void gday_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ gday gday_pimpl<C>::
+ post_gday ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ unsigned short day (0);
+ bool z (false);
+ short zh (0), zm (0);
+
+ // gday := ---DD[Z|(+|-)HH:MM]
+ //
+ if (size >= 5)
+ {
+ day = 10 * (s[3] - '0') + (s[4] - '0');
+
+ if (size > 5)
+ {
+ bits::parse_tz (s + 5, size - 5, zh, zm);
+ z = true;
+ }
+ }
+
+ return z ? gday (day, zh, zm) : gday (day);
+ }
+
+ // gmonth
+ //
+ template <typename C>
+ void gmonth_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void gmonth_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ gmonth gmonth_pimpl<C>::
+ post_gmonth ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ unsigned short month (0);
+ bool z (false);
+ short zh (0), zm (0);
+
+ // gmonth := --MM[Z|(+|-)HH:MM]
+ //
+ if (size >= 4)
+ {
+ month = 10 * (s[2] - '0') + (s[3] - '0');
+
+ if (size > 4)
+ {
+ bits::parse_tz (s + 4, size - 4, zh, zm);
+ z = true;
+ }
+ }
+
+ return z ? gmonth (month, zh, zm) : gmonth (month);
+ }
+
+ // gyear
+ //
+ template <typename C>
+ void gyear_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void gyear_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ gyear gyear_pimpl<C>::
+ post_gyear ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ int year (0);
+ bool z (false);
+ short zh (0), zm (0);
+
+ // gyear := [-]CCYY[N]*[Z|(+|-)HH:MM]
+ //
+
+ if (size >= 4)
+ {
+ // Find the end of the year token.
+ //
+ size_type pos (4);
+ for (; pos < size; ++pos)
+ {
+ C c (s[pos]);
+
+ if (c == C ('Z') || c == C ('+') || c == C ('-'))
+ break;
+ }
+
+ ro_string<C> year_fragment (s, pos);
+ zc_istream<C> is (year_fragment);
+ is >> year;
+
+ if (pos < size)
+ {
+ bits::parse_tz (s + pos, size - pos, zh, zm);
+ z = true;
+ }
+ }
+
+ return z ? gyear (year, zh, zm) : gyear (year);
+ }
+
+ // gmonth_day
+ //
+ template <typename C>
+ void gmonth_day_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void gmonth_day_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ gmonth_day gmonth_day_pimpl<C>::
+ post_gmonth_day ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ unsigned short month (0), day (0);
+ bool z (false);
+ short zh (0), zm (0);
+
+ // gmonth_day := --MM-DD[Z|(+|-)HH:MM]
+ //
+ if (size >= 7)
+ {
+ month = 10 * (s[2] - '0') + (s[3] - '0');
+ day = 10 * (s[5] - '0') + (s[6] - '0');
+
+ if (size > 7)
+ {
+ bits::parse_tz (s + 7, size - 7, zh, zm);
+ z = true;
+ }
+ }
+
+ return z
+ ? gmonth_day (month, day, zh, zm)
+ : gmonth_day (month, day);
+ }
+
+ // gyear_month
+ //
+ template <typename C>
+ void gyear_month_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void gyear_month_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ gyear_month gyear_month_pimpl<C>::
+ post_gyear_month ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ int year (0);
+ unsigned short month (0);
+ bool z (false);
+ short zh (0), zm (0);
+
+ // gyear_month := [-]CCYY[N]*-MM[Z|(+|-)HH:MM]
+ //
+
+ if (size >= 7)
+ {
+ // Find the end of the year token.
+ //
+ size_type pos (tmp.find (C ('-'), 4));
+
+ if (pos != ro_string<C>::npos && (size - pos - 1) >= 2)
+ {
+ ro_string<C> year_fragment (s, pos);
+ zc_istream<C> yis (year_fragment);
+ yis >> year;
+
+ month = 10 * (s[pos + 1] - '0') + (s[pos + 2] - '0');
+
+ pos += 3;
+
+ if (pos < size)
+ {
+ bits::parse_tz (s + pos, size - pos, zh, zm);
+ z = true;
+ }
+ }
+ }
+
+ return z
+ ? gyear_month (year, month, zh, zm)
+ : gyear_month (year, month);
+ }
+
+ // date
+ //
+ template <typename C>
+ void date_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void date_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ date date_pimpl<C>::
+ post_date ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ int year (0);
+ unsigned short month (0), day (0);
+ bool z (false);
+ short zh (0), zm (0);
+
+ // date := [-]CCYY[N]*-MM-DD[Z|(+|-)HH:MM]
+ //
+
+ if (size >= 10)
+ {
+ // Find the end of the year token.
+ //
+ size_type pos (tmp.find (C ('-'), 4));
+
+ if (pos != ro_string<C>::npos && (size - pos - 1) >= 5)
+ {
+ ro_string<C> year_fragment (s, pos);
+ zc_istream<C> yis (year_fragment);
+ yis >> year;
+
+ month = 10 * (s[pos + 1] - '0') + (s[pos + 2] - '0');
+ day = 10 * (s[pos + 4] - '0') + (s[pos + 5] - '0');
+
+ pos += 6;
+
+ if (pos < size)
+ {
+ bits::parse_tz (s + pos, size - pos, zh, zm);
+ z = true;
+ }
+ }
+ }
+
+ return z
+ ? date (year, month, day, zh, zm)
+ : date (year, month, day);
+ }
+
+ // time
+ //
+ template <typename C>
+ void time_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void time_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ time time_pimpl<C>::
+ post_time ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ unsigned short hours (0), minutes (0);
+ double seconds (0.0);
+ bool z (false);
+ short zh (0), zm (0);
+
+ // time := HH:MM:SS[.S+][Z|(+|-)HH:MM]
+ //
+
+ if (size >= 8)
+ {
+ hours = 10 * (s[0] - '0') + (s[1] - '0');
+ minutes = 10 * (s[3] - '0') + (s[4] - '0');
+
+ // Find the end of the seconds fragment.
+ //
+ size_type pos (8);
+ for (; pos < size; ++pos)
+ {
+ C c (s[pos]);
+
+ if (c == C ('Z') || c == C ('+') || c == C ('-'))
+ break;
+ }
+
+ ro_string<C> seconds_fragment (s + 6, pos - 6);
+ zc_istream<C> sis (seconds_fragment);
+ sis >> seconds;
+
+ if (pos < size)
+ {
+ bits::parse_tz (s + pos, size - pos, zh, zm);
+ z = true;
+ }
+ }
+
+ return z
+ ? time (hours, minutes, seconds, zh, zm)
+ : time (hours, minutes, seconds);
+ }
+
+
+ // date_time
+ //
+ template <typename C>
+ void date_time_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void date_time_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ date_time date_time_pimpl<C>::
+ post_date_time ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ int year (0);
+ unsigned short month (0), day (0), hours (0), minutes (0);
+ double seconds (0.0);
+ bool z (false);
+ short zh (0), zm (0);
+
+ // date_time := [-]CCYY[N]*-MM-DDTHH:MM:SS[.S+][Z|(+|-)HH:MM]
+ //
+
+ if (size >= 19)
+ {
+ // Find the end of the year token.
+ //
+ size_type pos (tmp.find (C ('-'), 4));
+
+ if (pos != ro_string<C>::npos && (size - pos - 1) >= 14)
+ {
+ ro_string<C> year_fragment (s, pos);
+ zc_istream<C> yis (year_fragment);
+ yis >> year;
+
+ month = 10 * (s[pos + 1] - '0') + (s[pos + 2] - '0');
+ day = 10 * (s[pos + 4] - '0') + (s[pos + 5] - '0');
+
+ pos += 7; // Point to the first H.
+
+ hours = 10 * (s[pos] - '0') + (s[pos + 1] - '0');
+ minutes = 10 * (s[pos + 3] - '0') + (s[pos + 4] - '0');
+
+ // Find the end of the seconds fragment.
+ //
+ pos += 6; // Point to the first S.
+
+ size_type sec_end (pos + 2);
+ for (; sec_end < size; ++sec_end)
+ {
+ C c (s[sec_end]);
+
+ if (c == C ('Z') || c == C ('+') || c == C ('-'))
+ break;
+ }
+
+ ro_string<C> seconds_fragment (s + pos, sec_end - pos);
+ zc_istream<C> sis (seconds_fragment);
+ sis >> seconds;
+
+ if (sec_end < size)
+ {
+ bits::parse_tz (s + sec_end, size - sec_end, zh, zm);
+ z = true;
+ }
+ }
+ }
+
+ return z
+ ? date_time (year, month, day, hours, minutes, seconds, zh, zm)
+ : date_time (year, month, day, hours, minutes, seconds);
+ }
+
+ // duration
+ //
+ template <typename C>
+ void duration_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void duration_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ namespace bits
+ {
+ template <typename C>
+ inline typename ro_string<C>::size_type
+ duration_delim (const C* s,
+ typename ro_string<C>::size_type pos,
+ typename ro_string<C>::size_type size)
+ {
+ const C* p (s + pos);
+ for (; p < (s + size); ++p)
+ {
+ if (*p == C ('Y') || *p == C ('D') || *p == C ('M') ||
+ *p == C ('H') || *p == C ('M') || *p == C ('S') ||
+ *p == C ('T'))
+ break;
+ }
+
+ return p - s;
+ }
+ }
+
+ template <typename C>
+ duration duration_pimpl<C>::
+ post_duration ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+
+ bool negative (false);
+ unsigned int years (0), months (0), days (0), hours (0), minutes (0);
+ double seconds (0.0);
+
+ // duration := [-]P[nY][nM][nD][TnHnMn[.n+]S]
+ //
+ const C* s (tmp.data ());
+
+ if (size >= 3)
+ {
+ size_type pos (0);
+
+ if (s[0] == C ('-'))
+ {
+ negative = true;
+ pos++;
+ }
+
+ pos++; // Skip 'P'.
+
+ size_type del (bits::duration_delim (s, pos, size));
+
+ if (del != size && s[del] == C ('Y'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+ is >> years;
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, size);
+ }
+
+ if (del != size && s[del] == C ('M'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+ is >> months;
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, size);
+ }
+
+ if (del != size && s[del] == C ('D'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+ is >> days;
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, size);
+ }
+
+ if (del != size && s[del] == C ('T'))
+ {
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, size);
+
+ if (del != size && s[del] == C ('H'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+ is >> hours;
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, size);
+ }
+
+ if (del != size && s[del] == C ('M'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+ is >> minutes;
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, size);
+ }
+
+ if (del != size && s[del] == C ('S'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+ is >> seconds;
+ }
+ }
+ }
+
+ return duration (
+ negative, years, months, days, hours, minutes, seconds);
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.hxx b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.hxx
new file mode 100644
index 0000000..7b90b91
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.hxx
@@ -0,0 +1,647 @@
+// file : xsd/cxx/parser/non-validating/xml-schema-pskel.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_HXX
+#define XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_HXX
+
+#include <string>
+#include <memory> // auto_ptr
+
+#include <xsd/cxx/parser/xml-schema.hxx>
+#include <xsd/cxx/parser/non-validating/parser.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace non_validating
+ {
+ // anyType and anySimpleType. All events are routed to the
+ // _any_* callbacks.
+ //
+ template <typename C>
+ struct any_type_pskel: complex_content<C>
+ {
+ virtual bool
+ _start_element_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>*);
+
+ virtual bool
+ _end_element_impl (const ro_string<C>&,
+ const ro_string<C>&);
+
+ virtual bool
+ _attribute_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&);
+
+ virtual bool
+ _characters_impl (const ro_string<C>&);
+
+ virtual void
+ post_any_type () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct any_simple_type_pskel: simple_content<C>
+ {
+ virtual bool
+ _characters_impl (const ro_string<C>&);
+
+ virtual void
+ post_any_simple_type () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // Boolean.
+ //
+ template <typename C>
+ struct boolean_pskel: simple_content<C>
+ {
+ virtual bool
+ post_boolean () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // 8-bit
+ //
+ template <typename C>
+ struct byte_pskel: simple_content<C>
+ {
+ virtual signed char
+ post_byte () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct unsigned_byte_pskel: simple_content<C>
+ {
+ virtual unsigned char
+ post_unsigned_byte () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // 16-bit
+ //
+ template <typename C>
+ struct short_pskel: simple_content<C>
+ {
+ virtual short
+ post_short () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct unsigned_short_pskel: simple_content<C>
+ {
+ virtual unsigned short
+ post_unsigned_short () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // 32-bit
+ //
+ template <typename C>
+ struct int_pskel: simple_content<C>
+ {
+ virtual int
+ post_int () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct unsigned_int_pskel: simple_content<C>
+ {
+ virtual unsigned int
+ post_unsigned_int () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // 64-bit
+ //
+ template <typename C>
+ struct long_pskel: simple_content<C>
+ {
+ virtual long long
+ post_long () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct unsigned_long_pskel: simple_content<C>
+ {
+ virtual unsigned long long
+ post_unsigned_long () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // Arbitrary-length integers.
+ //
+ template <typename C>
+ struct integer_pskel: simple_content<C>
+ {
+ virtual long long
+ post_integer () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct negative_integer_pskel: simple_content<C>
+ {
+ virtual long long
+ post_negative_integer () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct non_positive_integer_pskel: simple_content<C>
+ {
+ virtual long long
+ post_non_positive_integer () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct positive_integer_pskel: simple_content<C>
+ {
+ virtual unsigned long long
+ post_positive_integer () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct non_negative_integer_pskel: simple_content<C>
+ {
+ virtual unsigned long long
+ post_non_negative_integer () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // Floats.
+ //
+ template <typename C>
+ struct float_pskel: simple_content<C>
+ {
+ virtual float
+ post_float () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct double_pskel: simple_content<C>
+ {
+ virtual double
+ post_double () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct decimal_pskel: simple_content<C>
+ {
+ virtual double
+ post_decimal () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // Strings.
+ //
+ template <typename C>
+ struct string_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_string () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct normalized_string_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_normalized_string () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct token_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_token () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct name_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_name () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct nmtoken_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_nmtoken () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct nmtokens_pskel: list_base<C>
+ {
+ virtual string_sequence<C>
+ post_nmtokens () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct ncname_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_ncname () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct id_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_id () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct idref_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_idref () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct idrefs_pskel: list_base<C>
+ {
+ virtual string_sequence<C>
+ post_idrefs () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ // Language.
+ //
+ template <typename C>
+ struct language_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_language () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ // URI.
+ //
+ template <typename C>
+ struct uri_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_uri () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ // QName.
+ //
+ template <typename C>
+ struct qname_pskel: simple_content<C>
+ {
+ virtual qname<C>
+ post_qname () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ // Base64 and hex binaries.
+ //
+ template <typename C>
+ struct base64_binary_pskel: simple_content<C>
+ {
+ virtual std::auto_ptr<buffer>
+ post_base64_binary () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct hex_binary_pskel: simple_content<C>
+ {
+ virtual std::auto_ptr<buffer>
+ post_hex_binary () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ // Time and date types.
+ //
+ template <typename C>
+ struct gday_pskel: simple_content<C>
+ {
+ virtual gday
+ post_gday () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct gmonth_pskel: simple_content<C>
+ {
+ virtual gmonth
+ post_gmonth () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct gyear_pskel: simple_content<C>
+ {
+ virtual gyear
+ post_gyear () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct gmonth_day_pskel: simple_content<C>
+ {
+ virtual gmonth_day
+ post_gmonth_day () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct gyear_month_pskel: simple_content<C>
+ {
+ virtual gyear_month
+ post_gyear_month () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct date_pskel: simple_content<C>
+ {
+ virtual date
+ post_date () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct time_pskel: simple_content<C>
+ {
+ virtual time
+ post_time () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct date_time_pskel: simple_content<C>
+ {
+ virtual date_time
+ post_date_time () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct duration_pskel: simple_content<C>
+ {
+ virtual duration
+ post_duration () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/parser/non-validating/xml-schema-pskel.txx>
+
+#endif // XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_HXX
+
+#include <xsd/cxx/parser/non-validating/xml-schema-pskel.ixx>
diff --git a/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.ixx b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.ixx
new file mode 100644
index 0000000..3a42c9d
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.ixx
@@ -0,0 +1,1249 @@
+// file : xsd/cxx/parser/non-validating/xml-schema-pskel.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR)
+
+#ifndef XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_IXX_CHAR
+#define XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_IXX_CHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace non_validating
+ {
+ template<>
+ inline const char* any_type_pskel<char>::
+ _static_type ()
+ {
+ return "anyType http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* any_type_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* any_simple_type_pskel<char>::
+ _static_type ()
+ {
+ return "anySimpleType http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* any_simple_type_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* boolean_pskel<char>::
+ _static_type ()
+ {
+ return "boolean http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* boolean_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* byte_pskel<char>::
+ _static_type ()
+ {
+ return "byte http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* byte_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* unsigned_byte_pskel<char>::
+ _static_type ()
+ {
+ return "unsignedByte http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* unsigned_byte_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* short_pskel<char>::
+ _static_type ()
+ {
+ return "short http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* short_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* unsigned_short_pskel<char>::
+ _static_type ()
+ {
+ return "unsignedShort http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* unsigned_short_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* int_pskel<char>::
+ _static_type ()
+ {
+ return "int http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* int_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* unsigned_int_pskel<char>::
+ _static_type ()
+ {
+ return "unsignedInt http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* unsigned_int_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* long_pskel<char>::
+ _static_type ()
+ {
+ return "long http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* long_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* unsigned_long_pskel<char>::
+ _static_type ()
+ {
+ return "unsignedLong http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* unsigned_long_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* integer_pskel<char>::
+ _static_type ()
+ {
+ return "integer http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* integer_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* negative_integer_pskel<char>::
+ _static_type ()
+ {
+ return "negativeInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* negative_integer_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* non_positive_integer_pskel<char>::
+ _static_type ()
+ {
+ return "nonPositiveInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* non_positive_integer_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* positive_integer_pskel<char>::
+ _static_type ()
+ {
+ return "positiveInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* positive_integer_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* non_negative_integer_pskel<char>::
+ _static_type ()
+ {
+ return "nonNegativeInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* non_negative_integer_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* float_pskel<char>::
+ _static_type ()
+ {
+ return "float http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* float_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* double_pskel<char>::
+ _static_type ()
+ {
+ return "double http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* double_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* decimal_pskel<char>::
+ _static_type ()
+ {
+ return "decimal http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* decimal_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* string_pskel<char>::
+ _static_type ()
+ {
+ return "string http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* string_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* normalized_string_pskel<char>::
+ _static_type ()
+ {
+ return "normalizedString http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* normalized_string_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* token_pskel<char>::
+ _static_type ()
+ {
+ return "token http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* token_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* name_pskel<char>::
+ _static_type ()
+ {
+ return "Name http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* name_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* nmtoken_pskel<char>::
+ _static_type ()
+ {
+ return "NMTOKEN http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* nmtoken_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* nmtokens_pskel<char>::
+ _static_type ()
+ {
+ return "NMTOKENS http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* nmtokens_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* ncname_pskel<char>::
+ _static_type ()
+ {
+ return "NCName http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* ncname_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* id_pskel<char>::
+ _static_type ()
+ {
+ return "ID http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* id_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* idref_pskel<char>::
+ _static_type ()
+ {
+ return "IDREF http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* idref_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* idrefs_pskel<char>::
+ _static_type ()
+ {
+ return "IDREFS http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* idrefs_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* language_pskel<char>::
+ _static_type ()
+ {
+ return "language http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* language_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* uri_pskel<char>::
+ _static_type ()
+ {
+ return "anyURI http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* uri_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* qname_pskel<char>::
+ _static_type ()
+ {
+ return "QName http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* qname_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* base64_binary_pskel<char>::
+ _static_type ()
+ {
+ return "base64Binary http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* base64_binary_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* hex_binary_pskel<char>::
+ _static_type ()
+ {
+ return "hexBinary http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* hex_binary_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* gday_pskel<char>::
+ _static_type ()
+ {
+ return "gDay http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* gday_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* gmonth_pskel<char>::
+ _static_type ()
+ {
+ return "gMonth http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* gmonth_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* gyear_pskel<char>::
+ _static_type ()
+ {
+ return "gYear http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* gyear_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* gmonth_day_pskel<char>::
+ _static_type ()
+ {
+ return "gMonthDay http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* gmonth_day_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* gyear_month_pskel<char>::
+ _static_type ()
+ {
+ return "gYearMonth http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* gyear_month_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* date_pskel<char>::
+ _static_type ()
+ {
+ return "date http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* date_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* time_pskel<char>::
+ _static_type ()
+ {
+ return "time http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* time_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* date_time_pskel<char>::
+ _static_type ()
+ {
+ return "dateTime http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* date_time_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* duration_pskel<char>::
+ _static_type ()
+ {
+ return "duration http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* duration_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_IXX_CHAR
+#endif // XSD_CXX_PARSER_USE_CHAR
+
+
+#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR)
+
+#ifndef XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_IXX_WCHAR
+#define XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_IXX_WCHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace non_validating
+ {
+ template<>
+ inline const wchar_t* any_type_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"anyType http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* any_type_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* any_simple_type_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"anySimpleType http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* any_simple_type_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* boolean_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"boolean http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* boolean_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* byte_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"byte http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* byte_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* unsigned_byte_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"unsignedByte http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* unsigned_byte_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* short_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"short http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* short_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* unsigned_short_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"unsignedShort http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* unsigned_short_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* int_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"int http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* int_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* unsigned_int_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"unsignedInt http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* unsigned_int_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* long_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"long http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* long_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* unsigned_long_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"unsignedLong http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* unsigned_long_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* integer_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"integer http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* integer_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* negative_integer_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"negativeInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* negative_integer_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* non_positive_integer_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"nonPositiveInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* non_positive_integer_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* positive_integer_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"positiveInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* positive_integer_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* non_negative_integer_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"nonNegativeInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* non_negative_integer_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* float_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"float http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* float_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* double_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"double http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* double_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* decimal_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"decimal http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* decimal_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* string_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"string http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* string_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* normalized_string_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"normalizedString http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* normalized_string_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* token_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"token http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* token_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* name_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"Name http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* name_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* nmtoken_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"NMTOKEN http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* nmtoken_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* nmtokens_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"NMTOKENS http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* nmtokens_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* ncname_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"NCName http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* ncname_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* id_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"ID http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* id_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* idref_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"IDREF http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* idref_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* idrefs_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"IDREFS http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* idrefs_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* language_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"language http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* language_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* uri_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"anyURI http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* uri_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* qname_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"QName http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* qname_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* base64_binary_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"base64Binary http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* base64_binary_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* hex_binary_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"hexBinary http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* hex_binary_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* gday_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"gDay http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* gday_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* gmonth_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"gMonth http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* gmonth_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* gyear_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"gYear http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* gyear_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* gmonth_day_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"gMonthDay http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* gmonth_day_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* gyear_month_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"gYearMonth http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* gyear_month_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* date_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"date http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* date_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* time_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"time http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* time_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* date_time_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"dateTime http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* date_time_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* duration_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"duration http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* duration_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_NON_VALIDATING_XML_SCHEMA_PSKEL_IXX_WCHAR
+#endif // XSD_CXX_PARSER_USE_WCHAR
diff --git a/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.txx b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.txx
new file mode 100644
index 0000000..899eae6
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/non-validating/xml-schema-pskel.txx
@@ -0,0 +1,69 @@
+// file : xsd/cxx/parser/non-validating/xml-schema-pskel.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace non_validating
+ {
+ // any_type
+ //
+
+ template <typename C>
+ bool any_type_pskel<C>::
+ _start_element_impl (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type)
+ {
+ _start_any_element (ns, name, type);
+ this->complex_content<C>::context_.top ().any_ = true;
+ return true;
+ }
+
+ template <typename C>
+ bool any_type_pskel<C>::
+ _end_element_impl (const ro_string<C>& ns, const ro_string<C>& name)
+ {
+ this->complex_content<C>::context_.top ().any_ = false;
+ _end_any_element (ns, name);
+ return true;
+ }
+
+
+ template <typename C>
+ bool any_type_pskel<C>::
+ _attribute_impl (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ _any_attribute (ns, name, value);
+ return true;
+ }
+
+ template <typename C>
+ bool any_type_pskel<C>::
+ _characters_impl (const ro_string<C>& s)
+ {
+ _any_characters (s);
+ return true;
+ }
+
+ // any_simple_type
+ //
+
+ template <typename C>
+ bool any_simple_type_pskel<C>::
+ _characters_impl (const ro_string<C>& s)
+ {
+ _any_characters (s);
+ return true;
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/schema-exceptions.hxx b/libxsd/xsd/cxx/parser/schema-exceptions.hxx
new file mode 100644
index 0000000..f1fb358
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/schema-exceptions.hxx
@@ -0,0 +1,187 @@
+// file : xsd/cxx/parser/schema-exceptions.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_HXX
+#define XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_HXX
+
+#include <string>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ template <typename C>
+ struct schema_exception
+ {
+ public:
+ virtual
+ ~schema_exception ()
+ {
+ }
+
+ unsigned long
+ line () const
+ {
+ return line_;
+ }
+
+ void
+ line (unsigned long l)
+ {
+ line_ = l;
+ }
+
+ unsigned long
+ column () const
+ {
+ return column_;
+ }
+
+ void
+ column (unsigned long c)
+ {
+ column_ = c;
+ }
+
+ const std::basic_string<C>&
+ id () const
+ {
+ return id_;
+ }
+
+ void
+ id (const std::basic_string<C>& id)
+ {
+ id_ = id;
+ }
+
+ virtual std::basic_string<C>
+ message () const = 0;
+
+ protected:
+ unsigned long line_;
+ unsigned long column_;
+ std::basic_string<C> id_;
+ };
+
+ //
+ //
+ template <typename C>
+ struct expected_element: schema_exception<C>
+ {
+ virtual
+ ~expected_element ();
+
+ expected_element (const std::basic_string<C>& expected_namespace,
+ const std::basic_string<C>& expected_name);
+
+ expected_element (const std::basic_string<C>& expected_namespace,
+ const std::basic_string<C>& expected_name,
+ const std::basic_string<C>& encountered_namespace,
+ const std::basic_string<C>& encountered_name);
+
+ const std::basic_string<C>&
+ expected_namespace () const
+ {
+ return expected_namespace_;
+ }
+
+ const std::basic_string<C>&
+ expected_name () const
+ {
+ return expected_name_;
+ }
+
+ // Encountered element namespace and name are empty if none
+ // encountered.
+ //
+ const std::basic_string<C>&
+ encountered_namespace () const
+ {
+ return encountered_namespace_;
+ }
+
+ const std::basic_string<C>&
+ encountered_name () const
+ {
+ return encountered_name_;
+ }
+
+ virtual std::basic_string<C>
+ message () const;
+
+ private:
+ std::basic_string<C> expected_namespace_;
+ std::basic_string<C> expected_name_;
+
+ std::basic_string<C> encountered_namespace_;
+ std::basic_string<C> encountered_name_;
+ };
+
+
+ //
+ //
+ template <typename C>
+ struct unexpected_element: schema_exception<C>
+ {
+ virtual
+ ~unexpected_element ();
+
+ unexpected_element (const std::basic_string<C>& encountered_namespace,
+ const std::basic_string<C>& encountered_name);
+
+ const std::basic_string<C>&
+ encountered_namespace () const
+ {
+ return encountered_namespace_;
+ }
+
+ const std::basic_string<C>&
+ encountered_name () const
+ {
+ return encountered_name_;
+ }
+
+ virtual std::basic_string<C>
+ message () const;
+
+ private:
+ std::basic_string<C> encountered_namespace_;
+ std::basic_string<C> encountered_name_;
+ };
+
+ //
+ //
+ template <typename C>
+ struct dynamic_type: schema_exception<C>
+ {
+ virtual
+ ~dynamic_type () throw ();
+
+ dynamic_type (const std::basic_string<C>& type);
+
+ const std::basic_string<C>&
+ type () const
+ {
+ return type_;
+ }
+
+ virtual std::basic_string<C>
+ message () const;
+
+ private:
+ std::basic_string<C> type_;
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/parser/schema-exceptions.txx>
+
+#endif // XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_HXX
+
+#include <xsd/cxx/parser/schema-exceptions.ixx>
diff --git a/libxsd/xsd/cxx/parser/schema-exceptions.ixx b/libxsd/xsd/cxx/parser/schema-exceptions.ixx
new file mode 100644
index 0000000..98cc2db
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/schema-exceptions.ixx
@@ -0,0 +1,145 @@
+// file : xsd/cxx/parser/schema-exceptions.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR)
+
+#ifndef XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_IXX_CHAR
+#define XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_IXX_CHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // expected_element
+ //
+ template<>
+ inline
+ std::basic_string<char> expected_element<char>::
+ message () const
+ {
+ std::basic_string<char> r ("expected element '");
+ r += expected_namespace_;
+ r += expected_namespace_.empty () ? "" : "#";
+ r += expected_name_;
+ r += "'";
+
+ if (!encountered_name_.empty ())
+ {
+ r += " instead of '";
+ r += encountered_namespace_;
+ r += encountered_namespace_.empty () ? "" : "#";
+ r += encountered_name_;
+ r += "'";
+ }
+
+ return r;
+ }
+
+ // unexpected_element
+ //
+ template<>
+ inline
+ std::basic_string<char> unexpected_element<char>::
+ message () const
+ {
+ std::basic_string<char> r ("unexpected element '");
+ r += encountered_namespace_;
+ r += encountered_namespace_.empty () ? "" : "#";
+ r += encountered_name_;
+ r += "'";
+ return r;
+ }
+
+ // dynamic_type
+ //
+ template<>
+ inline
+ std::basic_string<char> dynamic_type<char>::
+ message () const
+ {
+ std::basic_string<char> r ("invalid xsi:type '");
+ r += type_;
+ r += "'";
+ return r;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_IXX_CHAR
+#endif // XSD_CXX_PARSER_USE_CHAR
+
+
+#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR)
+
+#ifndef XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_IXX_WCHAR
+#define XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_IXX_WCHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // expected_element
+ //
+ template<>
+ inline
+ std::basic_string<wchar_t> expected_element<wchar_t>::
+ message () const
+ {
+ std::basic_string<wchar_t> r (L"expected element '");
+ r += expected_namespace_;
+ r += expected_namespace_.empty () ? L"" : L"#";
+ r += expected_name_;
+ r += L"'";
+
+ if (!encountered_name_.empty ())
+ {
+ r += L" instead of '";
+ r += encountered_namespace_;
+ r += encountered_namespace_.empty () ? L"" : L"#";
+ r += encountered_name_;
+ r += L"'";
+ }
+
+ return r;
+ }
+
+ // unexpected_element
+ //
+ template<>
+ inline
+ std::basic_string<wchar_t> unexpected_element<wchar_t>::
+ message () const
+ {
+ std::basic_string<wchar_t> r (L"unexpected element '");
+ r += encountered_namespace_;
+ r += encountered_namespace_.empty () ? L"" : L"#";
+ r += encountered_name_;
+ r += L"'";
+ return r;
+ }
+
+ // dynamic_type
+ //
+ template<>
+ inline
+ std::basic_string<wchar_t> dynamic_type<wchar_t>::
+ message () const
+ {
+ std::basic_string<wchar_t> r (L"invalid xsi:type '");
+ r += type_;
+ r += L"'";
+ return r;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_SCHEMA_EXCEPTIONS_IXX_WCHAR
+#endif // XSD_CXX_PARSER_USE_WCHAR
diff --git a/libxsd/xsd/cxx/parser/schema-exceptions.txx b/libxsd/xsd/cxx/parser/schema-exceptions.txx
new file mode 100644
index 0000000..0d19604
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/schema-exceptions.txx
@@ -0,0 +1,75 @@
+// file : xsd/cxx/parser/schema-exceptions.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // expected_element
+ //
+ template <typename C>
+ expected_element<C>::
+ ~expected_element ()
+ {
+ }
+
+ template <typename C>
+ expected_element<C>::
+ expected_element (const std::basic_string<C>& expected_namespace,
+ const std::basic_string<C>& expected_name)
+ : expected_namespace_ (expected_namespace),
+ expected_name_ (expected_name)
+ {
+ }
+
+ template <typename C>
+ expected_element<C>::
+ expected_element (const std::basic_string<C>& expected_namespace,
+ const std::basic_string<C>& expected_name,
+ const std::basic_string<C>& encountered_namespace,
+ const std::basic_string<C>& encountered_name)
+ : expected_namespace_ (expected_namespace),
+ expected_name_ (expected_name),
+ encountered_namespace_ (encountered_namespace),
+ encountered_name_ (encountered_name)
+ {
+ }
+
+ // unexpected_element
+ //
+ template <typename C>
+ unexpected_element<C>::
+ ~unexpected_element ()
+ {
+ }
+
+ template <typename C>
+ unexpected_element<C>::
+ unexpected_element (const std::basic_string<C>& encountered_namespace,
+ const std::basic_string<C>& encountered_name)
+ : encountered_namespace_ (encountered_namespace),
+ encountered_name_ (encountered_name)
+ {
+ }
+
+ // dynamic_type
+ //
+ template <typename C>
+ dynamic_type<C>::
+ ~dynamic_type () throw ()
+ {
+ }
+
+ template <typename C>
+ dynamic_type<C>::
+ dynamic_type (const std::basic_string<C>& type)
+ : type_ (type)
+ {
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/substitution-map.hxx b/libxsd/xsd/cxx/parser/substitution-map.hxx
new file mode 100644
index 0000000..60c0ec8
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/substitution-map.hxx
@@ -0,0 +1,230 @@
+// file : xsd/cxx/parser/substitution-map.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_SUBSTITUTION_MAP_HXX
+#define XSD_CXX_PARSER_SUBSTITUTION_MAP_HXX
+
+#include <map>
+#include <cstddef> // std::size_t
+
+#include <xsd/cxx/ro-string.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ template <typename C>
+ struct substitution_map_key
+ {
+ substitution_map_key (const C* ns, const C* name)
+ : ns_ (ns), name_ (name)
+ {
+ }
+
+ substitution_map_key (const ro_string<C>& ns,
+ const ro_string<C>& name)
+ : ns_ (ns.data (), ns.size ()),
+ name_ (name.data (), name.size ())
+ {
+ }
+
+ substitution_map_key (const substitution_map_key& x)
+ : ns_ (x.ns_.data (), x.ns_.size ()),
+ name_ (x.name_.data (), x.name_.size ())
+ {
+ }
+
+ private:
+ substitution_map_key&
+ operator= (const substitution_map_key&);
+
+ public:
+ const ro_string<C>&
+ ns () const
+ {
+ return ns_;
+ }
+
+ const ro_string<C>&
+ name () const
+ {
+ return name_;
+ }
+
+ private:
+ const ro_string<C> ns_;
+ const ro_string<C> name_;
+ };
+
+ template <typename C>
+ inline bool
+ operator< (const substitution_map_key<C>& x,
+ const substitution_map_key<C>& y)
+ {
+ int r (x.name ().compare (y.name ()));
+ return r < 0 || (r == 0 && x.ns () < y.ns ());
+ }
+
+ template <typename C>
+ struct substitution_map_value
+ {
+ substitution_map_value (const C* ns, const C* name, const C* type)
+ : ns_ (ns), name_ (name), type_ (type)
+ {
+ }
+
+ substitution_map_value (const substitution_map_value& x)
+ : ns_ (x.ns_.data (), x.ns_.size ()),
+ name_ (x.name_.data (), x.name_.size ()),
+ type_ (x.type_.data (), x.type_.size ())
+ {
+ }
+
+ substitution_map_value&
+ operator= (const substitution_map_value& x)
+ {
+ if (this != &x)
+ {
+ ns_.assign (x.ns_.data (), x.ns_.size ());
+ name_.assign (x.name_.data (), x.name_.size ());
+ type_.assign (x.type_.data (), x.type_.size ());
+ }
+
+ return *this;
+ }
+
+ public:
+ const ro_string<C>&
+ ns () const
+ {
+ return ns_;
+ }
+
+ const ro_string<C>&
+ name () const
+ {
+ return name_;
+ }
+
+ const ro_string<C>&
+ type () const
+ {
+ return type_;
+ }
+
+ private:
+ ro_string<C> ns_;
+ ro_string<C> name_;
+ ro_string<C> type_;
+ };
+
+ template <typename C>
+ struct substitution_map
+ {
+ void
+ insert (const C* member_ns,
+ const C* member_name,
+ const C* root_ns,
+ const C* root_name,
+ const C* member_type)
+ {
+ key k (member_ns, member_name);
+ value v (root_ns, root_name, member_type);
+ map_.insert (std::pair<key, value> (k, v));
+ }
+
+ // Check and get the type set if found.
+ //
+ bool
+ check (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const C* root_ns,
+ const C* root_name,
+ const ro_string<C>*& type) const
+ {
+
+ return map_.empty ()
+ ? false
+ : check_ (ns, name, root_ns, root_name, &type);
+ }
+
+ // Check but don't care about the type.
+ //
+ bool
+ check (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const C* root_ns,
+ const C* root_name) const
+ {
+
+ return map_.empty ()
+ ? false
+ : check_ (ns, name, root_ns, root_name, 0);
+ }
+
+ private:
+ bool
+ check_ (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const C* root_ns,
+ const C* root_name,
+ const ro_string<C>** type) const;
+
+ private:
+ typedef substitution_map_key<C> key;
+ typedef substitution_map_value<C> value;
+ typedef std::map<key, value> map;
+
+ map map_;
+ };
+
+
+ // Translation unit initializer.
+ //
+ template<typename C>
+ struct substitution_map_init
+ {
+ static substitution_map<C>* map;
+ static std::size_t count;
+
+ substitution_map_init ();
+ ~substitution_map_init ();
+ };
+
+ template<typename C>
+ substitution_map<C>* substitution_map_init<C>::map = 0;
+
+ template<typename C>
+ std::size_t substitution_map_init<C>::count = 0;
+
+ template<typename C>
+ inline substitution_map<C>&
+ substitution_map_instance ()
+ {
+ return *substitution_map_init<C>::map;
+ }
+
+
+ // Map entry initializer.
+ //
+ template<typename C>
+ struct substitution_map_entry
+ {
+ substitution_map_entry (const C* member_ns,
+ const C* member_name,
+ const C* root_ns,
+ const C* root_name,
+ const C* member_type);
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/parser/substitution-map.txx>
+
+#endif // XSD_CXX_PARSER_SUBSTITUTION_MAP_HXX
+
diff --git a/libxsd/xsd/cxx/parser/substitution-map.txx b/libxsd/xsd/cxx/parser/substitution-map.txx
new file mode 100644
index 0000000..c9d4cb1
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/substitution-map.txx
@@ -0,0 +1,76 @@
+// file : xsd/cxx/parser/substitution-map.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ template <typename C>
+ bool substitution_map<C>::
+ check_ (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const C* root_ns,
+ const C* root_name,
+ const ro_string<C>** type) const
+ {
+ key k (ns, name);
+ typename map::const_iterator i (map_.find (k));
+
+ if (i == map_.end ())
+ return false;
+
+ const value& v (i->second);
+
+ bool r (false);
+
+ if (v.name () == root_name && v.ns () == root_ns)
+ r = true;
+ else
+ r = check_ (v.ns (), v.name (), root_ns, root_name, 0);
+
+ if (r && type != 0 && *type == 0)
+ *type = &v.type ();
+
+ return r;
+ }
+
+ // substitution_map_init
+ //
+ template<typename C>
+ substitution_map_init<C>::
+ substitution_map_init ()
+ {
+ if (count == 0)
+ map = new substitution_map<C>;
+
+ ++count;
+ }
+
+ template<typename C>
+ substitution_map_init<C>::
+ ~substitution_map_init ()
+ {
+ if (--count == 0)
+ delete map;
+ }
+
+ // substitution_map_entry
+ //
+ template<typename C>
+ substitution_map_entry<C>::
+ substitution_map_entry (const C* member_ns,
+ const C* member_name,
+ const C* root_ns,
+ const C* root_name,
+ const C* member_type)
+ {
+ substitution_map_instance<C> ().insert (
+ member_ns, member_name, root_ns, root_name, member_type);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/validating/exceptions.hxx b/libxsd/xsd/cxx/parser/validating/exceptions.hxx
new file mode 100644
index 0000000..1112c60
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/validating/exceptions.hxx
@@ -0,0 +1,153 @@
+// file : xsd/cxx/parser/validating/exceptions.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_HXX
+#define XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_HXX
+
+#include <string>
+
+#include <xsd/cxx/parser/schema-exceptions.hxx>
+#include <xsd/cxx/ro-string.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ //
+ //
+ template <typename C>
+ struct expected_attribute: schema_exception<C>
+ {
+ virtual
+ ~expected_attribute ();
+
+ expected_attribute (const std::basic_string<C>& expected_namespace,
+ const std::basic_string<C>& expected_name);
+
+ const std::basic_string<C>&
+ expected_namespace () const
+ {
+ return expected_namespace_;
+ }
+
+ const std::basic_string<C>&
+ expected_name () const
+ {
+ return expected_name_;
+ }
+
+ virtual std::basic_string<C>
+ message () const;
+
+ private:
+ std::basic_string<C> expected_namespace_;
+ std::basic_string<C> expected_name_;
+ };
+
+ //
+ //
+ template <typename C>
+ struct unexpected_attribute: schema_exception<C>
+ {
+ virtual
+ ~unexpected_attribute ();
+
+ unexpected_attribute (
+ const std::basic_string<C>& encountered_namespace,
+ const std::basic_string<C>& encountered_name);
+
+
+ const std::basic_string<C>&
+ encountered_namespace () const
+ {
+ return encountered_namespace_;
+ }
+
+ const std::basic_string<C>&
+ encountered_name () const
+ {
+ return encountered_name_;
+ }
+
+ virtual std::basic_string<C>
+ message () const;
+
+ private:
+ std::basic_string<C> encountered_namespace_;
+ std::basic_string<C> encountered_name_;
+ };
+
+
+ //
+ //
+ template <typename C>
+ struct unexpected_characters: schema_exception<C>
+ {
+ virtual
+ ~unexpected_characters ();
+
+ unexpected_characters (const std::basic_string<C>& s);
+
+ const std::basic_string<C>&
+ characters () const
+ {
+ return characters_;
+ }
+
+ virtual std::basic_string<C>
+ message () const;
+
+ private:
+ std::basic_string<C> characters_;
+ };
+
+ //
+ //
+ template <typename C>
+ struct invalid_value: schema_exception<C>
+ {
+ virtual
+ ~invalid_value ();
+
+ invalid_value (const C* type, const std::basic_string<C>& value);
+
+ invalid_value (const C* type, const ro_string<C>& value);
+
+ invalid_value (const std::basic_string<C>& type,
+ const std::basic_string<C>& value);
+
+ const std::basic_string<C>&
+ type () const
+ {
+ return type_;
+ }
+
+ const std::basic_string<C>&
+ value () const
+ {
+ return value_;
+ }
+
+ virtual std::basic_string<C>
+ message () const;
+
+ private:
+ std::basic_string<C> type_;
+ std::basic_string<C> value_;
+ };
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/parser/validating/exceptions.txx>
+
+#endif // XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_HXX
+
+#include <xsd/cxx/parser/validating/exceptions.ixx>
diff --git a/libxsd/xsd/cxx/parser/validating/exceptions.ixx b/libxsd/xsd/cxx/parser/validating/exceptions.ixx
new file mode 100644
index 0000000..6535cb8
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/validating/exceptions.ixx
@@ -0,0 +1,163 @@
+// file : xsd/cxx/parser/validating/exceptions.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR)
+
+#ifndef XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_IXX_CHAR
+#define XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_IXX_CHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ // expected_attribute
+ //
+ template<>
+ inline
+ std::basic_string<char> expected_attribute<char>::
+ message () const
+ {
+ std::basic_string<char> r ("expected attribute '");
+ r += expected_namespace_;
+ r += expected_namespace_.empty () ? "" : "#";
+ r += expected_name_;
+ r += "'";
+ return r;
+ }
+
+ // unexpected_attribute
+ //
+ template<>
+ inline
+ std::basic_string<char> unexpected_attribute<char>::
+ message () const
+ {
+ std::basic_string<char> r ("unexpected attribute '");
+ r += encountered_namespace_;
+ r += encountered_namespace_.empty () ? "" : "#";
+ r += encountered_name_;
+ r += "'";
+ return r;
+ }
+
+ // unexpected_characters
+ //
+ template<>
+ inline
+ std::basic_string<char> unexpected_characters<char>::
+ message () const
+ {
+ std::basic_string<char> r ("unexpected characters '");
+ r += characters_;
+ r += "'";
+ return r;
+ }
+
+ // invalid_value
+ //
+ template<>
+ inline
+ std::basic_string<char> invalid_value<char>::
+ message () const
+ {
+ std::basic_string<char> r ("'");
+ r += value_;
+ r += "' is not a valid value representation ";
+ r += "for type '";
+ r += type_;
+ r += "'";
+ return r;
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_IXX_CHAR
+#endif // XSD_CXX_PARSER_USE_CHAR
+
+
+#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR)
+
+#ifndef XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_IXX_WCHAR
+#define XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_IXX_WCHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ // expected_attribute
+ //
+ template<>
+ inline
+ std::basic_string<wchar_t> expected_attribute<wchar_t>::
+ message () const
+ {
+ std::basic_string<wchar_t> r (L"expected attribute '");
+ r += expected_namespace_;
+ r += expected_namespace_.empty () ? L"" : L"#";
+ r += expected_name_;
+ r += L"'";
+ return r;
+ }
+
+ // unexpected_attribute
+ //
+ template<>
+ inline
+ std::basic_string<wchar_t> unexpected_attribute<wchar_t>::
+ message () const
+ {
+ std::basic_string<wchar_t> r (L"unexpected attribute '");
+ r += encountered_namespace_;
+ r += encountered_namespace_.empty () ? L"" : L"#";
+ r += encountered_name_;
+ r += L"'";
+ return r;
+ }
+
+ // unexpected_characters
+ //
+ template<>
+ inline
+ std::basic_string<wchar_t> unexpected_characters<wchar_t>::
+ message () const
+ {
+ std::basic_string<wchar_t> r (L"unexpected characters '");
+ r += characters_;
+ r += L"'";
+ return r;
+ }
+
+ // invalid_value
+ //
+ template<>
+ inline
+ std::basic_string<wchar_t> invalid_value<wchar_t>::
+ message () const
+ {
+ std::basic_string<wchar_t> r (L"'");
+ r += value_;
+ r += L"' is not a valid value representation ";
+ r += L"for type '";
+ r += type_;
+ r += L"'";
+ return r;
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_VALIDATING_EXCEPTIONS_IXX_WCHAR
+#endif // XSD_CXX_PARSER_USE_WCHAR
diff --git a/libxsd/xsd/cxx/parser/validating/exceptions.txx b/libxsd/xsd/cxx/parser/validating/exceptions.txx
new file mode 100644
index 0000000..f8ffe80
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/validating/exceptions.txx
@@ -0,0 +1,97 @@
+// file : xsd/cxx/parser/validating/exceptions.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ // expected_attribute
+ //
+ template <typename C>
+ expected_attribute<C>::
+ ~expected_attribute ()
+ {
+ }
+
+ template <typename C>
+ expected_attribute<C>::
+ expected_attribute (const std::basic_string<C>& expected_namespace,
+ const std::basic_string<C>& expected_name)
+ : expected_namespace_ (expected_namespace),
+ expected_name_ (expected_name)
+ {
+ }
+
+ // unexpected_attribute
+ //
+ template <typename C>
+ unexpected_attribute<C>::
+ ~unexpected_attribute ()
+ {
+ }
+
+ template <typename C>
+ unexpected_attribute<C>::
+ unexpected_attribute (const std::basic_string<C>& encountered_namespace,
+ const std::basic_string<C>& encountered_name)
+ : encountered_namespace_ (encountered_namespace),
+ encountered_name_ (encountered_name)
+ {
+ }
+
+ // unexpected_characters
+ //
+ template <typename C>
+ unexpected_characters<C>::
+ ~unexpected_characters ()
+ {
+ }
+
+ template <typename C>
+ unexpected_characters<C>::
+ unexpected_characters (const std::basic_string<C>& s)
+ : characters_ (s)
+ {
+ }
+
+ // invalid_value
+ //
+ template <typename C>
+ invalid_value<C>::
+ ~invalid_value ()
+ {
+ }
+
+ template <typename C>
+ invalid_value<C>::
+ invalid_value (const C* type,
+ const std::basic_string<C>& value)
+ : type_ (type), value_ (value)
+ {
+ }
+
+ template <typename C>
+ invalid_value<C>::
+ invalid_value (const C* type,
+ const ro_string<C>& value)
+ : type_ (type), value_ (value)
+ {
+ }
+
+ template <typename C>
+ invalid_value<C>::
+ invalid_value (const std::basic_string<C>& type,
+ const std::basic_string<C>& value)
+ : type_ (type), value_ (value)
+ {
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/validating/inheritance-map.hxx b/libxsd/xsd/cxx/parser/validating/inheritance-map.hxx
new file mode 100644
index 0000000..ebd1d03
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/validating/inheritance-map.hxx
@@ -0,0 +1,92 @@
+// file : xsd/cxx/parser/validating/inheritance-map.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_VALIDATING_INHERITANCE_MAP_HXX
+#define XSD_CXX_PARSER_VALIDATING_INHERITANCE_MAP_HXX
+
+#include <map>
+#include <cstddef> // std::size_t
+
+#include <xsd/cxx/ro-string.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ template <typename C>
+ struct string_comparison
+ {
+ bool
+ operator() (const C* x, const C* y) const
+ {
+ ro_string<C> s (x);
+ return s.compare (y) < 0;
+ }
+ };
+
+ template <typename C>
+ struct inheritance_map
+ {
+ void
+ insert (const C* derived, const C* base)
+ {
+ map_[derived] = base;
+ }
+
+ bool
+ check (const C* derived, const ro_string<C>& base) const;
+
+ private:
+ typedef std::map<const C*, const C*, string_comparison<C> > map;
+ map map_;
+ };
+
+
+ // Translation unit initializer.
+ //
+ template<typename C>
+ struct inheritance_map_init
+ {
+ static inheritance_map<C>* map;
+ static std::size_t count;
+
+ inheritance_map_init ();
+ ~inheritance_map_init ();
+ };
+
+ template<typename C>
+ inheritance_map<C>* inheritance_map_init<C>::map = 0;
+
+ template<typename C>
+ std::size_t inheritance_map_init<C>::count = 0;
+
+ template<typename C>
+ inline inheritance_map<C>&
+ inheritance_map_instance ()
+ {
+ return *inheritance_map_init<C>::map;
+ }
+
+
+ // Map entry initializer.
+ //
+ template<typename C>
+ struct inheritance_map_entry
+ {
+ inheritance_map_entry (const C* derived, const C* base);
+ };
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/parser/validating/inheritance-map.txx>
+
+#endif // XSD_CXX_PARSER_VALIDATING_INHERITANCE_MAP_HXX
+
diff --git a/libxsd/xsd/cxx/parser/validating/inheritance-map.txx b/libxsd/xsd/cxx/parser/validating/inheritance-map.txx
new file mode 100644
index 0000000..5e70409
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/validating/inheritance-map.txx
@@ -0,0 +1,65 @@
+// file : xsd/cxx/parser/validating/inheritance-map.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ template <typename C>
+ bool inheritance_map<C>::
+ check (const C* derived, const ro_string<C>& base) const
+ {
+ if (base == derived)
+ return true;
+
+ typename map::const_iterator i (map_.find (derived));
+
+ if (i != map_.end ())
+ {
+ if (base == i->second)
+ return true;
+ else
+ return check (i->second, base);
+ }
+
+ return false;
+ }
+
+ // inheritance_map_init
+ //
+ template<typename C>
+ inheritance_map_init<C>::
+ inheritance_map_init ()
+ {
+ if (count == 0)
+ map = new inheritance_map<C>;
+
+ ++count;
+ }
+
+ template<typename C>
+ inheritance_map_init<C>::
+ ~inheritance_map_init ()
+ {
+ if (--count == 0)
+ delete map;
+ }
+
+ // inheritance_map_entry
+ //
+ template<typename C>
+ inheritance_map_entry<C>::
+ inheritance_map_entry (const C* derived, const C* base)
+ {
+ inheritance_map_instance<C> ().insert (derived, base);
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/validating/parser.hxx b/libxsd/xsd/cxx/parser/validating/parser.hxx
new file mode 100644
index 0000000..4feb898
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/validating/parser.hxx
@@ -0,0 +1,471 @@
+// file : xsd/cxx/parser/validating/parser.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_VALIDATING_PARSER_HXX
+#define XSD_CXX_PARSER_VALIDATING_PARSER_HXX
+
+#include <stack>
+#include <cstddef> // std::size_t
+#include <cstring> // std::memcpy
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/parser/elements.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ //
+ //
+ template <typename C>
+ struct empty_content: parser_base<C>
+ {
+ // These functions are called when wildcard content
+ // is encountered. Use them to handle mixed content
+ // models, any/anyAttribute, and anyType/anySimpleType.
+ // By default these functions do nothing.
+ //
+
+ // The type argument is a type name and namespace from the
+ // xsi:type attribute in the form "<name> <namespace>" with
+ // the space and namespace part absent if the type does not
+ // have a namespace or 0 if xsi:type is not present.
+ //
+ virtual void
+ _start_any_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type);
+
+ virtual void
+ _end_any_element (const ro_string<C>& ns,
+ const ro_string<C>& name);
+
+ virtual void
+ _any_attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value);
+
+ virtual void
+ _any_characters (const ro_string<C>&);
+
+
+ //
+ //
+ virtual bool
+ _start_element_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>*);
+
+ virtual bool
+ _end_element_impl (const ro_string<C>&,
+ const ro_string<C>&);
+
+ virtual bool
+ _attribute_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&);
+
+ virtual bool
+ _characters_impl (const ro_string<C>&);
+
+
+ //
+ //
+ virtual void
+ _start_element (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>*);
+
+ virtual void
+ _end_element (const ro_string<C>&,
+ const ro_string<C>&);
+
+ virtual void
+ _attribute (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&);
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+
+ //
+ //
+ virtual void
+ _expected_element (const C* expected_ns,
+ const C* expected_name);
+
+ virtual void
+ _expected_element (const C* expected_ns,
+ const C* expected_name,
+ const ro_string<C>& encountered_ns,
+ const ro_string<C>& encountered_name);
+
+ virtual void
+ _unexpected_element (const ro_string<C>& ns,
+ const ro_string<C>& name);
+
+ virtual void
+ _expected_attribute (const C* expected_ns,
+ const C* expected_name);
+
+ virtual void
+ _unexpected_attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value);
+
+ virtual void
+ _unexpected_characters (const ro_string<C>&);
+ };
+
+
+ //
+ //
+ template <typename C>
+ struct simple_content: empty_content<C>
+ {
+ //
+ //
+ virtual void
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value);
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ //
+ //
+ virtual bool
+ _attribute_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&);
+
+ //
+ //
+ virtual void
+ _pre_impl ();
+
+ virtual void
+ _post_impl ();
+
+
+ // Implementation callbacks.
+ //
+ virtual void
+ _pre_a_validate ();
+
+ virtual void
+ _post_a_validate ();
+
+
+ // Attribute validation: during phase one we are searching for
+ // matching attributes (Structures, section 3.4.4, clause 2.1).
+ // During phase two we are searching for attribute wildcards
+ // (section 3.4.4, clause 2.2). Both phases run across
+ // inheritance hierarchy from derived to base for extension
+ // only. Both functions return true if the match was found and
+ // validation has been performed.
+ //
+ virtual bool
+ _attribute_impl_phase_one (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value);
+
+ virtual bool
+ _attribute_impl_phase_two (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value);
+ };
+
+
+ //
+ //
+ template <typename C>
+ struct complex_content: empty_content<C>
+ {
+ //
+ //
+ virtual void
+ _start_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type);
+
+ virtual void
+ _end_element (const ro_string<C>& ns,
+ const ro_string<C>& name);
+
+ virtual void
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value);
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ //
+ //
+ virtual bool
+ _attribute_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&);
+
+ //
+ //
+ virtual void
+ _pre_impl ();
+
+ virtual void
+ _post_impl ();
+
+
+ // Implementation callbacks.
+ //
+ virtual void
+ _pre_e_validate ();
+
+ virtual void
+ _post_e_validate ();
+
+ virtual void
+ _pre_a_validate ();
+
+ virtual void
+ _post_a_validate ();
+
+
+ // Attribute validation: during phase one we are searching for
+ // matching attributes (Structures, section 3.4.4, clause 2.1).
+ // During phase two we are searching for attribute wildcards
+ // (section 3.4.4, clause 2.2). Both phases run across
+ // inheritance hierarchy from derived to base for extension
+ // only. Both functions return true if the match was found and
+ // validation has been performed.
+ //
+ virtual bool
+ _attribute_impl_phase_one (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value);
+
+ virtual bool
+ _attribute_impl_phase_two (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value);
+ protected:
+ struct state
+ {
+ state ()
+ : any_ (false), depth_ (0), parser_ (0)
+ {
+ }
+
+ bool any_;
+ std::size_t depth_;
+ parser_base<C>* parser_;
+ };
+
+ // Optimized state stack for non-recursive case (one element).
+ //
+ struct state_stack
+ {
+ state_stack ()
+ : size_ (0)
+ {
+ }
+
+ void
+ push (const state& s)
+ {
+ if (size_ > 0)
+ rest_.push (top_);
+
+ top_ = s;
+ ++size_;
+ }
+
+ void
+ pop ()
+ {
+ if (size_ > 1)
+ {
+ top_ = rest_.top ();
+ rest_.pop ();
+ }
+
+ --size_;
+ }
+
+ const state&
+ top () const
+ {
+ return top_;
+ }
+
+ state&
+ top ()
+ {
+ return top_;
+ }
+
+ state&
+ under_top ()
+ {
+ return rest_.top ();
+ }
+
+ private:
+ state top_;
+ std::stack<state> rest_;
+ std::size_t size_;
+ };
+
+ state_stack context_;
+ };
+
+ // Base for xsd:list.
+ //
+ template <typename C>
+ struct list_base: simple_content<C>
+ {
+ virtual void
+ _xsd_parse_item (const ro_string<C>&) = 0;
+
+ virtual void
+ _pre_impl ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post_impl ();
+
+ protected:
+ std::basic_string<C> buf_;
+ };
+ }
+
+ // POD stack with pre-allocated first element. You may
+ // need to pad your elements to get the proper alignment.
+ //
+ struct pod_stack
+ {
+ ~pod_stack ()
+ {
+ delete[] data_;
+ }
+
+ pod_stack (std::size_t element_size, void* first_element)
+ : el_size_ (element_size), first_ (first_element),
+ data_ (0), size_ (0), capacity_ (0)
+ {
+ }
+
+ public:
+ void
+ pop ()
+ {
+ --size_;
+ }
+
+ void
+ push ()
+ {
+ if (size_ > capacity_)
+ grow ();
+
+ ++size_;
+ }
+
+ void*
+ top ()
+ {
+ return size_ == 1 ? first_ : data_ + (size_ - 1) * el_size_;
+ }
+
+ void*
+ under_top ()
+ {
+ return size_ == 2 ? first_ : data_ + (size_ - 2) * el_size_;
+ }
+
+ std::size_t
+ element_size () const
+ {
+ return el_size_;
+ }
+
+ private:
+ void
+ grow ()
+ {
+ std::size_t c (capacity_ ? capacity_ * 2 : 8);
+ char* d (new char[c * el_size_]);
+
+ if (size_ > 1)
+ std::memcpy (d, data_, (size_ - 1) * el_size_);
+
+ delete[] data_;
+
+ data_ = d;
+ capacity_ = c;
+ }
+
+ private:
+ std::size_t el_size_;
+ void* first_;
+ char* data_;
+ std::size_t size_;
+ std::size_t capacity_;
+ };
+
+ namespace validating
+ {
+ // Validation state stack for the 'all' particle.
+ //
+ struct all_stack
+ {
+ all_stack (std::size_t n, unsigned char* first)
+ : stack_ (n, first)
+ {
+ }
+
+ void
+ push ()
+ {
+ stack_.push ();
+
+ unsigned char* p (static_cast<unsigned char*> (stack_.top ()));
+
+ for (std::size_t i (0); i < stack_.element_size (); ++i)
+ p[i] = 0;
+ }
+
+ void
+ pop ()
+ {
+ stack_.pop ();
+ }
+
+ unsigned char*
+ top ()
+ {
+ return static_cast<unsigned char*> (stack_.top ());
+ }
+
+ private:
+ pod_stack stack_;
+ };
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/parser/validating/parser.txx>
+
+#endif // XSD_CXX_PARSER_VALIDATING_PARSER_HXX
diff --git a/libxsd/xsd/cxx/parser/validating/parser.txx b/libxsd/xsd/cxx/parser/validating/parser.txx
new file mode 100644
index 0000000..4cf9b7e
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/validating/parser.txx
@@ -0,0 +1,667 @@
+// file : xsd/cxx/parser/validating/parser.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cassert>
+
+#include <xsd/cxx/xml/bits/literals.hxx>
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+
+ // empty_content
+ //
+
+
+ template <typename C>
+ void empty_content<C>::
+ _start_any_element (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>*)
+ {
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _end_any_element (const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _any_attribute (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _any_characters (const ro_string<C>&)
+ {
+ }
+
+ //
+ //
+ template <typename C>
+ bool empty_content<C>::
+ _start_element_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>*)
+ {
+ return false;
+ }
+
+ template <typename C>
+ bool empty_content<C>::
+ _end_element_impl (const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ return false;
+ }
+
+ template <typename C>
+ bool empty_content<C>::
+ _attribute_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ return false;
+ }
+
+ template <typename C>
+ bool empty_content<C>::
+ _characters_impl (const ro_string<C>&)
+ {
+ return false;
+ }
+
+ //
+ //
+ template <typename C>
+ void empty_content<C>::
+ _start_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type)
+ {
+ if (!_start_element_impl (ns, name, type))
+ _unexpected_element (ns, name);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _end_element (const ro_string<C>& ns,
+ const ro_string<C>& name)
+ {
+ if (!_end_element_impl (ns, name))
+ _unexpected_element (ns, name);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ // Weed out special attributes: xsi:type, xsi:nil,
+ // xsi:schemaLocation and noNamespaceSchemaLocation.
+ // See section 3.2.7 in Structures for details.
+ //
+ if (ns == xml::bits::xsi_namespace<C> () &&
+ (name == xml::bits::type<C> () ||
+ name == xml::bits::nil<C> () ||
+ name == xml::bits::schema_location<C> () ||
+ name == xml::bits::no_namespace_schema_location<C> ()))
+ return;
+
+ // Also some parsers (notably Xerces-C++) supplies us with
+ // namespace-prefix mapping attributes.
+ //
+ if (ns == xml::bits::xmlns_namespace<C> ())
+ return;
+
+ if (!_attribute_impl (ns, name, value))
+ _unexpected_attribute (ns, name, value);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (!_characters_impl (s))
+ _unexpected_characters (s);
+ }
+
+ //
+ //
+ template <typename C>
+ void empty_content<C>::
+ _expected_element (const C* ex_ns, const C* ex_name)
+ {
+ throw expected_element<C> (ex_ns, ex_name);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _expected_element (const C* ex_ns,
+ const C* ex_name,
+ const ro_string<C>& en_ns,
+ const ro_string<C>& en_name)
+ {
+ throw expected_element<C> (ex_ns, ex_name, en_ns, en_name);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _unexpected_element (const ro_string<C>& ns,
+ const ro_string<C>& name)
+ {
+ throw unexpected_element<C> (ns, name);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _expected_attribute (const C* ex_ns, const C* ex_name)
+ {
+ throw expected_attribute<C> (ex_ns, ex_name);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _unexpected_attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>&)
+ {
+ throw unexpected_attribute<C> (ns, name);
+ }
+
+ template <typename C>
+ void empty_content<C>::
+ _unexpected_characters (const ro_string<C>& s)
+ {
+ throw unexpected_characters<C> (s);
+ }
+
+
+ // simple_content
+ //
+
+ template <typename C>
+ void simple_content<C>::
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ // Weed out special attributes: xsi:type, xsi:nil,
+ // xsi:schemaLocation and xsi:noNamespaceSchemaLocation.
+ // See section 3.2.7 in Structures for details.
+ //
+ if (ns == xml::bits::xsi_namespace<C> () &&
+ (name == xml::bits::type<C> () ||
+ name == xml::bits::nil<C> () ||
+ name == xml::bits::schema_location<C> () ||
+ name == xml::bits::no_namespace_schema_location<C> ()))
+ return;
+
+ // Also some parsers (notably Xerces-C++) supplies us with
+ // namespace-prefix mapping attributes.
+ //
+ if (ns == xml::bits::xmlns_namespace<C> ())
+ return;
+
+ if (!_attribute_impl (ns, name, value))
+ _unexpected_attribute (ns, name, value);
+ }
+
+ template <typename C>
+ void simple_content<C>::
+ _characters (const ro_string<C>& str)
+ {
+ if (!_characters_impl (str))
+ {
+ // Mixed content is implemented in the generated code
+ // by overriding _characters_impl and forwarding to
+ // _any_characters.
+ //
+
+ // Scan the string for any non-whitespace characters
+ // (Structures, section 3.4.4, clause 1.3).
+ //
+ for (typename ro_string<C>::size_type i (0), e (str.size ());
+ i < e; ++i)
+ {
+ C c (str[i]);
+
+ if (c != C (0x20) && // space
+ c != C (0x0D) && // carriage return
+ c != C (0x09) && // tab
+ c != C (0x0A))
+ _unexpected_characters (str);
+ }
+ }
+ }
+
+ template <typename C>
+ void simple_content<C>::
+ _pre_impl ()
+ {
+ this->_pre ();
+ _pre_a_validate ();
+ }
+
+ template <typename C>
+ void simple_content<C>::
+ _post_impl ()
+ {
+ _post_a_validate ();
+ this->_post ();
+ }
+
+ template <typename C>
+ void simple_content<C>::
+ _pre_a_validate ()
+ {
+ }
+
+ template <typename C>
+ void simple_content<C>::
+ _post_a_validate ()
+ {
+ }
+
+ template <typename C>
+ bool simple_content<C>::
+ _attribute_impl (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ return _attribute_impl_phase_one (ns, name, value) ||
+ _attribute_impl_phase_two (ns, name, value);
+ }
+
+ template <typename C>
+ bool simple_content<C>::
+ _attribute_impl_phase_one (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ return false;
+ }
+
+ template <typename C>
+ bool simple_content<C>::
+ _attribute_impl_phase_two (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ return false;
+ }
+
+
+ // complex_content
+ //
+
+
+ template <typename C>
+ void complex_content<C>::
+ _start_element (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type)
+ {
+ state& s (context_.top ());
+
+ if (s.depth_++ > 0)
+ {
+ if (s.any_)
+ _start_any_element (ns, name, type);
+ else if (s.parser_)
+ s.parser_->_start_element (ns, name, type);
+ }
+ else
+ {
+ if (!_start_element_impl (ns, name, type))
+ _unexpected_element (ns, name);
+ else if (s.parser_ != 0)
+ s.parser_->_pre_impl ();
+ }
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _end_element (const ro_string<C>& ns,
+ const ro_string<C>& name)
+ {
+ // To understand what's going on here it is helpful to think of
+ // a "total depth" as being the sum of individual depths over
+ // all elements.
+ //
+
+ if (context_.top ().depth_ == 0)
+ {
+ state& s (context_.under_top ()); // One before last.
+
+ if (--s.depth_ > 0)
+ {
+ // Indirect recursion.
+ //
+ if (s.parser_)
+ s.parser_->_end_element (ns, name);
+ }
+ else
+ {
+ // Direct recursion.
+ //
+ assert (this == s.parser_);
+
+ this->_post_impl ();
+
+ if (!_end_element_impl (ns, name))
+ assert (false);
+ }
+ }
+ else
+ {
+ state& s (context_.top ());
+
+ if (--s.depth_ > 0)
+ {
+ if (s.any_)
+ _end_any_element (ns, name);
+ else if (s.parser_)
+ s.parser_->_end_element (ns, name);
+ }
+ else
+ {
+ if (s.parser_ != 0 && !s.any_)
+ s.parser_->_post_impl ();
+
+ if (!_end_element_impl (ns, name))
+ _unexpected_element (ns, name);
+ }
+ }
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _attribute (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ // Weed out special attributes: xsi:type, xsi:nil,
+ // xsi:schemaLocation and xsi:noNamespaceSchemaLocation.
+ // See section 3.2.7 in Structures for details.
+ //
+ if (ns == xml::bits::xsi_namespace<C> () &&
+ (name == xml::bits::type<C> () ||
+ name == xml::bits::nil<C> () ||
+ name == xml::bits::schema_location<C> () ||
+ name == xml::bits::no_namespace_schema_location<C> ()))
+ return;
+
+ // Also some parsers (notably Xerces-C++) supplies us with
+ // namespace-prefix mapping attributes.
+ //
+ if (ns == xml::bits::xmlns_namespace<C> ())
+ return;
+
+ const state& s (context_.top ());
+
+ if (s.depth_ > 0)
+ {
+ if (s.any_)
+ _any_attribute (ns, name, value);
+ else if (s.parser_)
+ s.parser_->_attribute (ns, name, value);
+ }
+ else
+ {
+ if (!_attribute_impl (ns, name, value))
+ _unexpected_attribute (ns, name, value);
+ }
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _characters (const ro_string<C>& str)
+ {
+ const state& s (context_.top ());
+
+ if (s.depth_ > 0)
+ {
+ if (s.any_)
+ _any_characters (str);
+ else if (s.parser_)
+ s.parser_->_characters (str);
+ }
+ else
+ {
+ if (!_characters_impl (str))
+ {
+ // Mixed content is implemented in the generated code
+ // by overriding _characters_impl and forwarding to
+ // _any_characters.
+ //
+
+ // Scan the string for any non-whitespace characters
+ // (Structures, section 3.4.4, clause 1.3).
+ //
+ for (typename ro_string<C>::size_type i (0), e (str.size ());
+ i < e; ++i)
+ {
+ C c (str[i]);
+
+ if (c != C (0x20) && // space
+ c != C (0x0D) && // carriage return
+ c != C (0x09) && // tab
+ c != C (0x0A))
+ _unexpected_characters (str);
+ }
+ }
+ }
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _pre_impl ()
+ {
+ context_.push (state ());
+ this->_pre ();
+ _pre_a_validate ();
+ _pre_e_validate ();
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _post_impl ()
+ {
+ _post_e_validate ();
+ _post_a_validate ();
+ this->_post ();
+ context_.pop ();
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _pre_e_validate ()
+ {
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _post_e_validate ()
+ {
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _pre_a_validate ()
+ {
+ }
+
+ template <typename C>
+ void complex_content<C>::
+ _post_a_validate ()
+ {
+ }
+
+ template <typename C>
+ bool complex_content<C>::
+ _attribute_impl (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ return _attribute_impl_phase_one (ns, name, value) ||
+ _attribute_impl_phase_two (ns, name, value);
+ }
+
+ template <typename C>
+ bool complex_content<C>::
+ _attribute_impl_phase_one (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ return false;
+ }
+
+ template <typename C>
+ bool complex_content<C>::
+ _attribute_impl_phase_two (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&)
+ {
+ return false;
+ }
+
+
+ // list_base
+ //
+ namespace bits
+ {
+ // Find first non-space character.
+ //
+ template <typename C>
+ typename ro_string<C>::size_type
+ find_ns (const C* s,
+ typename ro_string<C>::size_type size,
+ typename ro_string<C>::size_type pos)
+ {
+ while (pos < size &&
+ (s[pos] == C (0x20) || s[pos] == C (0x0A) ||
+ s[pos] == C (0x0D) || s[pos] == C (0x09)))
+ ++pos;
+
+ return pos < size ? pos : ro_string<C>::npos;
+ }
+
+ // Find first space character.
+ //
+ template <typename C>
+ typename ro_string<C>::size_type
+ find_s (const C* s,
+ typename ro_string<C>::size_type size,
+ typename ro_string<C>::size_type pos)
+ {
+ while (pos < size &&
+ s[pos] != C (0x20) && s[pos] != C (0x0A) &&
+ s[pos] != C (0x0D) && s[pos] != C (0x09))
+ ++pos;
+
+ return pos < size ? pos : ro_string<C>::npos;
+ }
+ }
+
+ // Relevant XML Schema Part 2: Datatypes sections: 4.2.1.2, 4.3.6.
+ //
+
+ template <typename C>
+ void list_base<C>::
+ _pre_impl ()
+ {
+ simple_content<C>::_pre_impl ();
+ buf_.clear ();
+ }
+
+ template <typename C>
+ void list_base<C>::
+ _characters (const ro_string<C>& s)
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ const C* data (s.data ());
+ size_type size (s.size ());
+
+ // Handle the previous chunk if we start with a ws.
+ //
+ if (!buf_.empty () &&
+ (data[0] == C (0x20) || data[0] == C (0x0A) ||
+ data[0] == C (0x0D) || data[0] == C (0x09)))
+ {
+ ro_string<C> tmp (buf_); // Private copy ctor.
+ _xsd_parse_item (tmp);
+ buf_.clear ();
+ }
+
+ // Traverse the data while logically collapsing spaces.
+ //
+ for (size_type i (bits::find_ns (data, size, 0));
+ i != ro_string<C>::npos;)
+ {
+ size_type j (bits::find_s (data, size, i));
+
+ if (j != ro_string<C>::npos)
+ {
+ if (buf_.empty ())
+ {
+ ro_string<C> tmp (data + i, j - i); // Private copy ctor.
+ _xsd_parse_item (tmp);
+ }
+ else
+ {
+ // Assemble the first item in str from buf_ and s.
+ //
+ std::basic_string<C> str;
+ str.swap (buf_);
+ str.append (data + i, j - i);
+ ro_string<C> tmp (str); // Private copy ctor.
+ _xsd_parse_item (tmp);
+ }
+
+ i = bits::find_ns (data, size, j);
+ }
+ else
+ {
+ // Last fragment, append it to the buf_.
+ //
+ buf_.append (data + i, size - i);
+ break;
+ }
+ }
+ }
+
+ template <typename C>
+ void list_base<C>::
+ _post_impl ()
+ {
+ // Handle the last item.
+ //
+ if (!buf_.empty ())
+ {
+ ro_string<C> tmp (buf_); // Private copy ctor.
+ _xsd_parse_item (tmp);
+ }
+
+ simple_content<C>::_post_impl ();
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.hxx b/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.hxx
new file mode 100644
index 0000000..5f2f03f
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.hxx
@@ -0,0 +1,1121 @@
+// file : xsd/cxx/parser/validating/xml-schema-pimpl.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_HXX
+#define XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_HXX
+
+#include <string>
+
+#include <xsd/cxx/parser/validating/xml-schema-pskel.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ // any_type
+ //
+ template <typename C>
+ struct any_type_pimpl: virtual any_type_pskel<C>
+ {
+ virtual void
+ post_any_type ();
+ };
+
+ // any_simple_type
+ //
+ template <typename C>
+ struct any_simple_type_pimpl: virtual any_simple_type_pskel<C>
+ {
+ virtual void
+ post_any_simple_type ();
+ };
+
+ // boolean
+ //
+ template <typename C>
+ struct boolean_pimpl: virtual boolean_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual bool
+ post_boolean ();
+
+ protected:
+ std::basic_string<C> str_;
+ bool value_;
+ };
+
+
+ // 8-bit
+ //
+ template <typename C>
+ struct byte_pimpl: virtual byte_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual signed char
+ post_byte ();
+
+ protected:
+ std::basic_string<C> str_;
+ signed char value_;
+ };
+
+
+ template <typename C>
+ struct unsigned_byte_pimpl: virtual unsigned_byte_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual unsigned char
+ post_unsigned_byte ();
+
+ protected:
+ std::basic_string<C> str_;
+ unsigned char value_;
+ };
+
+
+ // 16-bit
+ //
+ template <typename C>
+ struct short_pimpl: virtual short_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual short
+ post_short ();
+
+ protected:
+ std::basic_string<C> str_;
+ short value_;
+ };
+
+
+ template <typename C>
+ struct unsigned_short_pimpl: virtual unsigned_short_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual unsigned short
+ post_unsigned_short ();
+
+ protected:
+ std::basic_string<C> str_;
+ unsigned short value_;
+ };
+
+
+ // 32-bit
+ //
+ template <typename C>
+ struct int_pimpl: virtual int_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual int
+ post_int ();
+
+ protected:
+ std::basic_string<C> str_;
+ int value_;
+ };
+
+
+ template <typename C>
+ struct unsigned_int_pimpl: virtual unsigned_int_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual unsigned int
+ post_unsigned_int ();
+
+ protected:
+ std::basic_string<C> str_;
+ unsigned int value_;
+ };
+
+
+ // 64-bit
+ //
+ template <typename C>
+ struct long_pimpl: virtual long_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual long long
+ post_long ();
+
+ protected:
+ std::basic_string<C> str_;
+ long long value_;
+ };
+
+
+ template <typename C>
+ struct unsigned_long_pimpl: virtual unsigned_long_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual unsigned long long
+ post_unsigned_long ();
+
+ protected:
+ std::basic_string<C> str_;
+ unsigned long long value_;
+ };
+
+
+ // Arbitrary-length integers.
+ //
+ template <typename C>
+ struct integer_pimpl: virtual integer_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual long long
+ post_integer ();
+
+ protected:
+ std::basic_string<C> str_;
+ long long value_;
+ };
+
+ template <typename C>
+ struct negative_integer_pimpl: virtual negative_integer_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual long long
+ post_negative_integer ();
+
+ protected:
+ std::basic_string<C> str_;
+ long long value_;
+ };
+
+ template <typename C>
+ struct non_positive_integer_pimpl: virtual non_positive_integer_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual long long
+ post_non_positive_integer ();
+
+ protected:
+ std::basic_string<C> str_;
+ long long value_;
+ };
+
+ template <typename C>
+ struct positive_integer_pimpl: virtual positive_integer_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual unsigned long long
+ post_positive_integer ();
+
+ protected:
+ std::basic_string<C> str_;
+ unsigned long long value_;
+ };
+
+ template <typename C>
+ struct non_negative_integer_pimpl: virtual non_negative_integer_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual unsigned long long
+ post_non_negative_integer ();
+
+ protected:
+ std::basic_string<C> str_;
+ unsigned long long value_;
+ };
+
+
+ // Floats.
+ //
+ template <typename C>
+ struct float_pimpl: virtual float_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual float
+ post_float ();
+
+ protected:
+ std::basic_string<C> str_;
+ float value_;
+ };
+
+
+ template <typename C>
+ struct double_pimpl: virtual double_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual double
+ post_double ();
+
+ protected:
+ std::basic_string<C> str_;
+ double value_;
+ };
+
+
+ template <typename C>
+ struct decimal_pimpl: virtual decimal_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual double
+ post_decimal ();
+
+ protected:
+ std::basic_string<C> str_;
+ double value_;
+ };
+
+
+ // Strings.
+ //
+ template <typename C>
+ struct string_pimpl: virtual string_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_string ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct normalized_string_pimpl: virtual normalized_string_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_normalized_string ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct token_pimpl: virtual token_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_token ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct name_pimpl: virtual name_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual std::basic_string<C>
+ post_name ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct nmtoken_pimpl: virtual nmtoken_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual std::basic_string<C>
+ post_nmtoken ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct nmtokens_pimpl: virtual nmtokens_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _xsd_parse_item (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual string_sequence<C>
+ post_nmtokens ();
+
+ protected:
+ string_sequence<C> seq_;
+ nmtoken_pimpl<C> parser_;
+ };
+
+ template <typename C>
+ struct ncname_pimpl: virtual ncname_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual std::basic_string<C>
+ post_ncname ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct id_pimpl: virtual id_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual std::basic_string<C>
+ post_id ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct idref_pimpl: virtual idref_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual std::basic_string<C>
+ post_idref ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ template <typename C>
+ struct idrefs_pimpl: virtual idrefs_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _xsd_parse_item (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual string_sequence<C>
+ post_idrefs ();
+
+ protected:
+ string_sequence<C> seq_;
+ idref_pimpl<C> parser_;
+ };
+
+ // language
+ //
+ template <typename C>
+ struct language_pimpl: virtual language_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual std::basic_string<C>
+ post_language ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // anyURI
+ //
+ template <typename C>
+ struct uri_pimpl: virtual uri_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual std::basic_string<C>
+ post_uri ();
+
+ protected:
+ std::basic_string<C> str_;
+ };
+
+ // QName
+ //
+ template <typename C>
+ struct qname_pimpl: virtual qname_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual qname<C>
+ post_qname ();
+
+ protected:
+ std::basic_string<C> str_;
+ std::basic_string<C> name_;
+ std::basic_string<C> prefix_;
+ };
+
+ // base64Binary
+ //
+ template <typename C>
+ struct base64_binary_pimpl: virtual base64_binary_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual std::auto_ptr<buffer>
+ post_base64_binary ();
+
+ protected:
+ std::basic_string<C> str_;
+ std::auto_ptr<buffer> buf_;
+ };
+
+ // hexBinary
+ //
+ template <typename C>
+ struct hex_binary_pimpl: virtual hex_binary_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual std::auto_ptr<buffer>
+ post_hex_binary ();
+
+ protected:
+ std::basic_string<C> str_;
+ std::auto_ptr<buffer> buf_;
+ };
+
+ // gday
+ //
+ template <typename C>
+ struct gday_pimpl: virtual gday_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual gday
+ post_gday ();
+
+ protected:
+ std::basic_string<C> str_;
+ unsigned short day_;
+ bool z_;
+ short zh_, zm_;
+ };
+
+ // gmonth
+ //
+ template <typename C>
+ struct gmonth_pimpl: virtual gmonth_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual gmonth
+ post_gmonth ();
+
+ protected:
+ std::basic_string<C> str_;
+ unsigned short month_;
+ bool z_;
+ short zh_, zm_;
+ };
+
+ // gyear
+ //
+ template <typename C>
+ struct gyear_pimpl: virtual gyear_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual gyear
+ post_gyear ();
+
+ protected:
+ std::basic_string<C> str_;
+ int year_;
+ bool z_;
+ short zh_, zm_;
+ };
+
+ // gmonth_day
+ //
+ template <typename C>
+ struct gmonth_day_pimpl: virtual gmonth_day_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual gmonth_day
+ post_gmonth_day ();
+
+ protected:
+ std::basic_string<C> str_;
+ unsigned short month_;
+ unsigned short day_;
+ bool z_;
+ short zh_, zm_;
+ };
+
+ // gyear_month
+ //
+ template <typename C>
+ struct gyear_month_pimpl: virtual gyear_month_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual gyear_month
+ post_gyear_month ();
+
+ protected:
+ std::basic_string<C> str_;
+ int year_;
+ unsigned short month_;
+ bool z_;
+ short zh_, zm_;
+ };
+
+ // date
+ //
+ template <typename C>
+ struct date_pimpl: virtual date_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual date
+ post_date ();
+
+ protected:
+ std::basic_string<C> str_;
+ int year_;
+ unsigned short month_;
+ unsigned short day_;
+ bool z_;
+ short zh_, zm_;
+ };
+
+ // time
+ //
+ template <typename C>
+ struct time_pimpl: virtual time_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual time
+ post_time ();
+
+ protected:
+ std::basic_string<C> str_;
+ unsigned short hours_;
+ unsigned short minutes_;
+ double seconds_;
+ bool z_;
+ short zh_, zm_;
+ };
+
+ // date_time
+ //
+ template <typename C>
+ struct date_time_pimpl: virtual date_time_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual date_time
+ post_date_time ();
+
+ protected:
+ std::basic_string<C> str_;
+ int year_;
+ unsigned short month_;
+ unsigned short day_;
+ unsigned short hours_;
+ unsigned short minutes_;
+ double seconds_;
+ bool z_;
+ short zh_, zm_;
+ };
+
+ // duration
+ //
+ template <typename C>
+ struct duration_pimpl: virtual duration_pskel<C>
+ {
+ virtual void
+ _pre ();
+
+ virtual void
+ _characters (const ro_string<C>&);
+
+ virtual void
+ _post ();
+
+ virtual duration
+ post_duration ();
+
+ protected:
+ std::basic_string<C> str_;
+ bool negative_;
+ unsigned int years_;
+ unsigned int months_;
+ unsigned int days_;
+ unsigned int hours_;
+ unsigned int minutes_;
+ double seconds_;
+ };
+
+ // Literals.
+ //
+ namespace bits
+ {
+ template<typename C>
+ const C*
+ boolean ();
+
+ template<typename C>
+ const C*
+ byte ();
+
+ template<typename C>
+ const C*
+ unsigned_byte ();
+
+ template<typename C>
+ const C*
+ short_ ();
+
+ template<typename C>
+ const C*
+ unsigned_short ();
+
+ template<typename C>
+ const C*
+ int_ ();
+
+ template<typename C>
+ const C*
+ unsigned_int ();
+
+ template<typename C>
+ const C*
+ long_ ();
+
+ template<typename C>
+ const C*
+ unsigned_long ();
+
+ template<typename C>
+ const C*
+ integer ();
+
+ template<typename C>
+ const C*
+ negative_integer ();
+
+ template<typename C>
+ const C*
+ non_positive_integer ();
+
+ template<typename C>
+ const C*
+ non_negative_integer ();
+
+ template<typename C>
+ const C*
+ positive_integer ();
+
+ template<typename C>
+ const C*
+ float_ ();
+
+ template<typename C>
+ const C*
+ double_ ();
+
+ template<typename C>
+ const C*
+ decimal ();
+
+ template<typename C>
+ const C*
+ name ();
+
+ template<typename C>
+ const C*
+ nmtoken ();
+
+ template<typename C>
+ const C*
+ nmtokens ();
+
+ template<typename C>
+ const C*
+ ncname ();
+
+ template<typename C>
+ const C*
+ id ();
+
+ template<typename C>
+ const C*
+ idref ();
+
+ template<typename C>
+ const C*
+ idrefs ();
+
+ template<typename C>
+ const C*
+ language ();
+
+ template<typename C>
+ const C*
+ qname ();
+
+ template<typename C>
+ const C*
+ base64_binary ();
+
+ template<typename C>
+ const C*
+ hex_binary ();
+
+ template<typename C>
+ const C*
+ gday ();
+
+ template<typename C>
+ const C*
+ gmonth ();
+
+ template<typename C>
+ const C*
+ gyear ();
+
+ template<typename C>
+ const C*
+ gmonth_day ();
+
+ template<typename C>
+ const C*
+ gyear_month ();
+
+ template<typename C>
+ const C*
+ date ();
+
+ template<typename C>
+ const C*
+ time ();
+
+ template<typename C>
+ const C*
+ date_time ();
+
+ template<typename C>
+ const C*
+ duration ();
+
+ // float literals: INF -INF NaN
+ //
+ template<typename C>
+ const C*
+ positive_inf ();
+
+ template<typename C>
+ const C*
+ negative_inf ();
+
+ template<typename C>
+ const C*
+ nan ();
+
+ // boolean literals
+ //
+ template<typename C>
+ const C*
+ true_ ();
+
+ template<typename C>
+ const C*
+ false_ ();
+
+ template<typename C>
+ const C*
+ one ();
+
+ template<typename C>
+ const C*
+ zero ();
+ }
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.txx>
+
+#endif // XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_HXX
+
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.ixx>
diff --git a/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.ixx b/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.ixx
new file mode 100644
index 0000000..61bbafb
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.ixx
@@ -0,0 +1,676 @@
+// file : xsd/cxx/parser/validating/xml-schema-pimpl.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR)
+
+#ifndef XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_IXX_CHAR
+#define XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_IXX_CHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ namespace bits
+ {
+ template<>
+ inline const char*
+ boolean<char> ()
+ {
+ return "boolean";
+ }
+
+ template<>
+ inline const char*
+ byte<char> ()
+ {
+ return "byte";
+ }
+
+ template<>
+ inline const char*
+ unsigned_byte<char> ()
+ {
+ return "unsignedByte";
+ }
+
+ template<>
+ inline const char*
+ short_<char> ()
+ {
+ return "short";
+ }
+
+ template<>
+ inline const char*
+ unsigned_short<char> ()
+ {
+ return "unsignedShort";
+ }
+
+ template<>
+ inline const char*
+ int_<char> ()
+ {
+ return "int";
+ }
+
+ template<>
+ inline const char*
+ unsigned_int<char> ()
+ {
+ return "unsignedInt";
+ }
+
+ template<>
+ inline const char*
+ long_<char> ()
+ {
+ return "long";
+ }
+
+ template<>
+ inline const char*
+ unsigned_long<char> ()
+ {
+ return "unsignedLong";
+ }
+
+ template<>
+ inline const char*
+ integer<char> ()
+ {
+ return "integer";
+ }
+
+ template<>
+ inline const char*
+ negative_integer<char> ()
+ {
+ return "negativeInteger";
+ }
+
+ template<>
+ inline const char*
+ non_positive_integer<char> ()
+ {
+ return "nonPositiveInteger";
+ }
+
+ template<>
+ inline const char*
+ non_negative_integer<char> ()
+ {
+ return "nonNegativeInteger";
+ }
+
+ template<>
+ inline const char*
+ positive_integer<char> ()
+ {
+ return "positiveInteger";
+ }
+
+ template<>
+ inline const char*
+ float_<char> ()
+ {
+ return "float";
+ }
+
+ template<>
+ inline const char*
+ double_<char> ()
+ {
+ return "double";
+ }
+
+ template<>
+ inline const char*
+ decimal<char> ()
+ {
+ return "decimal";
+ }
+
+ template<>
+ inline const char*
+ name<char> ()
+ {
+ return "Name";
+ }
+
+ template<>
+ inline const char*
+ nmtoken<char> ()
+ {
+ return "NMTOKEN";
+ }
+
+ template<>
+ inline const char*
+ nmtokens<char> ()
+ {
+ return "NMTOKENS";
+ }
+
+ template<>
+ inline const char*
+ ncname<char> ()
+ {
+ return "NCName";
+ }
+
+ template<>
+ inline const char*
+ id<char> ()
+ {
+ return "ID";
+ }
+
+ template<>
+ inline const char*
+ idref<char> ()
+ {
+ return "IDREF";
+ }
+
+ template<>
+ inline const char*
+ idrefs<char> ()
+ {
+ return "IDREFS";
+ }
+
+ template<>
+ inline const char*
+ language<char> ()
+ {
+ return "language";
+ }
+
+ template<>
+ inline const char*
+ qname<char> ()
+ {
+ return "QName";
+ }
+
+ template<>
+ inline const char*
+ base64_binary<char> ()
+ {
+ return "base64Binary";
+ }
+
+ template<>
+ inline const char*
+ hex_binary<char> ()
+ {
+ return "hexBinary";
+ }
+
+ template<>
+ inline const char*
+ gday<char> ()
+ {
+ return "gDay";
+ }
+
+ template<>
+ inline const char*
+ gmonth<char> ()
+ {
+ return "gMonth";
+ }
+
+ template<>
+ inline const char*
+ gyear<char> ()
+ {
+ return "gYear";
+ }
+
+ template<>
+ inline const char*
+ gmonth_day<char> ()
+ {
+ return "gMonthDay";
+ }
+
+ template<>
+ inline const char*
+ gyear_month<char> ()
+ {
+ return "gYearMonth";
+ }
+
+ template<>
+ inline const char*
+ date<char> ()
+ {
+ return "date";
+ }
+
+ template<>
+ inline const char*
+ time<char> ()
+ {
+ return "time";
+ }
+
+ template<>
+ inline const char*
+ date_time<char> ()
+ {
+ return "dateTime";
+ }
+
+ template<>
+ inline const char*
+ duration<char> ()
+ {
+ return "duration";
+ }
+
+ //
+ //
+ template<>
+ inline const char*
+ positive_inf<char> ()
+ {
+ return "INF";
+ }
+
+ template<>
+ inline const char*
+ negative_inf<char> ()
+ {
+ return "-INF";
+ }
+
+ template<>
+ inline const char*
+ nan<char> ()
+ {
+ return "NaN";
+ }
+
+ //
+ //
+ template<>
+ inline const char*
+ true_<char> ()
+ {
+ return "true";
+ }
+
+ template<>
+ inline const char*
+ false_<char> ()
+ {
+ return "false";
+ }
+
+ template<>
+ inline const char*
+ one<char> ()
+ {
+ return "1";
+ }
+
+ template<>
+ inline const char*
+ zero<char> ()
+ {
+ return "0";
+ }
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_IXX_CHAR
+#endif // XSD_CXX_PARSER_USE_CHAR
+
+
+#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR)
+
+#ifndef XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_IXX_WCHAR
+#define XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_IXX_WCHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ namespace bits
+ {
+ template<>
+ inline const wchar_t*
+ boolean<wchar_t> ()
+ {
+ return L"boolean";
+ }
+
+ template<>
+ inline const wchar_t*
+ byte<wchar_t> ()
+ {
+ return L"byte";
+ }
+
+ template<>
+ inline const wchar_t*
+ unsigned_byte<wchar_t> ()
+ {
+ return L"unsignedByte";
+ }
+
+ template<>
+ inline const wchar_t*
+ short_<wchar_t> ()
+ {
+ return L"short";
+ }
+
+ template<>
+ inline const wchar_t*
+ unsigned_short<wchar_t> ()
+ {
+ return L"unsignedShort";
+ }
+
+ template<>
+ inline const wchar_t*
+ int_<wchar_t> ()
+ {
+ return L"int";
+ }
+
+ template<>
+ inline const wchar_t*
+ unsigned_int<wchar_t> ()
+ {
+ return L"unsignedInt";
+ }
+
+ template<>
+ inline const wchar_t*
+ long_<wchar_t> ()
+ {
+ return L"long";
+ }
+
+ template<>
+ inline const wchar_t*
+ unsigned_long<wchar_t> ()
+ {
+ return L"unsignedLong";
+ }
+
+ template<>
+ inline const wchar_t*
+ integer<wchar_t> ()
+ {
+ return L"integer";
+ }
+
+ template<>
+ inline const wchar_t*
+ negative_integer<wchar_t> ()
+ {
+ return L"negativeInteger";
+ }
+
+ template<>
+ inline const wchar_t*
+ non_positive_integer<wchar_t> ()
+ {
+ return L"nonPositiveInteger";
+ }
+
+ template<>
+ inline const wchar_t*
+ non_negative_integer<wchar_t> ()
+ {
+ return L"nonNegativeInteger";
+ }
+
+ template<>
+ inline const wchar_t*
+ positive_integer<wchar_t> ()
+ {
+ return L"positiveInteger";
+ }
+
+ template<>
+ inline const wchar_t*
+ float_<wchar_t> ()
+ {
+ return L"float";
+ }
+
+ template<>
+ inline const wchar_t*
+ double_<wchar_t> ()
+ {
+ return L"double";
+ }
+
+ template<>
+ inline const wchar_t*
+ decimal<wchar_t> ()
+ {
+ return L"decimal";
+ }
+
+ template<>
+ inline const wchar_t*
+ name<wchar_t> ()
+ {
+ return L"Name";
+ }
+
+ template<>
+ inline const wchar_t*
+ nmtoken<wchar_t> ()
+ {
+ return L"NMTOKEN";
+ }
+
+ template<>
+ inline const wchar_t*
+ nmtokens<wchar_t> ()
+ {
+ return L"NMTOKENS";
+ }
+
+ template<>
+ inline const wchar_t*
+ ncname<wchar_t> ()
+ {
+ return L"NCName";
+ }
+
+ template<>
+ inline const wchar_t*
+ id<wchar_t> ()
+ {
+ return L"ID";
+ }
+
+ template<>
+ inline const wchar_t*
+ idref<wchar_t> ()
+ {
+ return L"IDREF";
+ }
+
+ template<>
+ inline const wchar_t*
+ idrefs<wchar_t> ()
+ {
+ return L"IDREFS";
+ }
+
+ template<>
+ inline const wchar_t*
+ language<wchar_t> ()
+ {
+ return L"language";
+ }
+
+ template<>
+ inline const wchar_t*
+ qname<wchar_t> ()
+ {
+ return L"QName";
+ }
+
+ template<>
+ inline const wchar_t*
+ base64_binary<wchar_t> ()
+ {
+ return L"base64Binary";
+ }
+
+ template<>
+ inline const wchar_t*
+ hex_binary<wchar_t> ()
+ {
+ return L"hexBinary";
+ }
+
+ template<>
+ inline const wchar_t*
+ gday<wchar_t> ()
+ {
+ return L"gDay";
+ }
+
+ template<>
+ inline const wchar_t*
+ gmonth<wchar_t> ()
+ {
+ return L"gMonth";
+ }
+
+ template<>
+ inline const wchar_t*
+ gyear<wchar_t> ()
+ {
+ return L"gYear";
+ }
+
+ template<>
+ inline const wchar_t*
+ gmonth_day<wchar_t> ()
+ {
+ return L"gMonthDay";
+ }
+
+ template<>
+ inline const wchar_t*
+ gyear_month<wchar_t> ()
+ {
+ return L"gYearMonth";
+ }
+
+ template<>
+ inline const wchar_t*
+ date<wchar_t> ()
+ {
+ return L"date";
+ }
+
+ template<>
+ inline const wchar_t*
+ time<wchar_t> ()
+ {
+ return L"time";
+ }
+
+ template<>
+ inline const wchar_t*
+ date_time<wchar_t> ()
+ {
+ return L"dateTime";
+ }
+
+ template<>
+ inline const wchar_t*
+ duration<wchar_t> ()
+ {
+ return L"duration";
+ }
+
+
+ //
+ //
+ template<>
+ inline const wchar_t*
+ positive_inf<wchar_t> ()
+ {
+ return L"INF";
+ }
+
+ template<>
+ inline const wchar_t*
+ negative_inf<wchar_t> ()
+ {
+ return L"-INF";
+ }
+
+ template<>
+ inline const wchar_t*
+ nan<wchar_t> ()
+ {
+ return L"NaN";
+ }
+
+ //
+ //
+ template<>
+ inline const wchar_t*
+ true_<wchar_t> ()
+ {
+ return L"true";
+ }
+
+ template<>
+ inline const wchar_t*
+ false_<wchar_t> ()
+ {
+ return L"false";
+ }
+
+ template<>
+ inline const wchar_t*
+ one<wchar_t> ()
+ {
+ return L"1";
+ }
+
+ template<>
+ inline const wchar_t*
+ zero<wchar_t> ()
+ {
+ return L"0";
+ }
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PIMPL_IXX_WCHAR
+#endif // XSD_CXX_PARSER_USE_WCHAR
diff --git a/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.txx b/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.txx
new file mode 100644
index 0000000..9dd30a3
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/validating/xml-schema-pimpl.txx
@@ -0,0 +1,2746 @@
+// file : xsd/cxx/parser/validating/xml-schema-pimpl.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <limits>
+#include <locale>
+
+#include <xsd/cxx/zc-istream.hxx>
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ // Note that most of the types implemented here cannot have
+ // whitespaces in the value. 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.
+ //
+
+ // Character table.
+ //
+ namespace bits
+ {
+ const unsigned char ncname_mask = 0x1;
+ const unsigned char name_first_mask = 0x2;
+ const unsigned char name_mask = 0x4;
+
+ template <typename C>
+ struct char_table
+ {
+ static C table[0x80];
+ };
+
+ template <typename C>
+ C char_table<C>::table[0x80] =
+ {
+ 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xD8, 0xD0, 0x00, 0x00, 0xD0, 0x00, 0x00,
+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+ 0xD8, 0x48, 0x58, 0x48, 0x48, 0x48, 0x40, 0x58, 0x48, 0x48, 0x48, 0x48, 0x48, 0x4D, 0x4D, 0x58,
+ 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4D, 0x4E, 0x48, 0x50, 0x48, 0x58, 0x48,
+ 0x48, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F,
+ 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x48, 0x48, 0x40, 0x48, 0x4F,
+ 0x48, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F,
+ 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x4F, 0x48, 0x48, 0x48, 0x48, 0x48
+ };
+ }
+
+ // any_type
+ //
+
+ template <typename C>
+ void any_type_pimpl<C>::
+ post_any_type ()
+ {
+ }
+
+ // any_simple_type
+ //
+
+ template <typename C>
+ void any_simple_type_pimpl<C>::
+ post_any_simple_type ()
+ {
+ }
+
+ // boolean
+ //
+
+ template <typename C>
+ void boolean_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void boolean_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void boolean_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ if (str == bits::true_<C> () || str == bits::one<C> ())
+ value_ = true;
+ else if (str == bits::false_<C> () || str == bits::zero<C> ())
+ value_ = false;
+ else
+ throw invalid_value<C> (bits::boolean<C> (), str);
+ }
+
+ template <typename C>
+ bool boolean_pimpl<C>::
+ post_boolean ()
+ {
+ return value_;
+ }
+
+ // byte
+ //
+
+ template <typename C>
+ void byte_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void byte_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void byte_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ short t;
+ zc_istream<C> is (str);
+
+ if (is >> t && is.exhausted () && t >= -128 && t <= 127)
+ value_ = static_cast<signed char> (t);
+ else
+ throw invalid_value<C> (bits::byte<C> (), str);
+ }
+
+ template <typename C>
+ signed char byte_pimpl<C>::
+ post_byte ()
+ {
+ return value_;
+ }
+
+ // unsigned_byte
+ //
+
+ template <typename C>
+ void unsigned_byte_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void unsigned_byte_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void unsigned_byte_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ unsigned short t;
+ zc_istream<C> is (str);
+
+ if (is >> t && is.exhausted () && t <= 255)
+ value_ = static_cast<unsigned char> (t);
+ else
+ throw invalid_value<C> (bits::unsigned_byte<C> (), str);
+ }
+
+ template <typename C>
+ unsigned char unsigned_byte_pimpl<C>::
+ post_unsigned_byte ()
+ {
+ return value_;
+ }
+
+ // short
+ //
+
+ template <typename C>
+ void short_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void short_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void short_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ zc_istream<C> is (str);
+
+ if (!(is >> value_ && is.exhausted ()))
+ throw invalid_value<C> (bits::short_<C> (), str);
+ }
+
+ template <typename C>
+ short short_pimpl<C>::
+ post_short ()
+ {
+ return value_;
+ }
+
+
+ // unsigned_short
+ //
+
+ template <typename C>
+ void unsigned_short_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void unsigned_short_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void unsigned_short_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ zc_istream<C> is (str);
+
+ if (!(is >> value_ && is.exhausted ()))
+ throw invalid_value<C> (bits::unsigned_short<C> (), str);
+ }
+
+ template <typename C>
+ unsigned short unsigned_short_pimpl<C>::
+ post_unsigned_short ()
+ {
+ return value_;
+ }
+
+ // int
+ //
+
+ template <typename C>
+ void int_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void int_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void int_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ zc_istream<C> is (str);
+
+ if (!(is >> value_ && is.exhausted ()))
+ throw invalid_value<C> (bits::int_<C> (), str);
+ }
+
+ template <typename C>
+ int int_pimpl<C>::
+ post_int ()
+ {
+ return value_;
+ }
+
+
+ // unsigned_int
+ //
+
+ template <typename C>
+ void unsigned_int_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void unsigned_int_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void unsigned_int_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ zc_istream<C> is (str);
+
+ if (!(is >> value_ && is.exhausted ()))
+ throw invalid_value<C> (bits::unsigned_int<C> (), str);
+ }
+
+ template <typename C>
+ unsigned int unsigned_int_pimpl<C>::
+ post_unsigned_int ()
+ {
+ return value_;
+ }
+
+
+ // long
+ //
+ template <typename C>
+ void long_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void long_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void long_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ zc_istream<C> is (str);
+
+ if (!(is >> value_ && is.exhausted ()))
+ throw invalid_value<C> (bits::long_<C> (), str);
+ }
+
+ template <typename C>
+ long long long_pimpl<C>::
+ post_long ()
+ {
+ return value_;
+ }
+
+ // unsigned_long
+ //
+ template <typename C>
+ void unsigned_long_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void unsigned_long_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void unsigned_long_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ zc_istream<C> is (str);
+
+ if (!(is >> value_ && is.exhausted ()))
+ throw invalid_value<C> (bits::unsigned_long<C> (), str);
+ }
+
+ template <typename C>
+ unsigned long long unsigned_long_pimpl<C>::
+ post_unsigned_long ()
+ {
+ return value_;
+ }
+
+
+ // integer
+ //
+ template <typename C>
+ void integer_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void integer_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void integer_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ zc_istream<C> is (str);
+
+ if (!(is >> value_ && is.exhausted ()))
+ throw invalid_value<C> (bits::integer<C> (), str);
+ }
+
+ template <typename C>
+ long long integer_pimpl<C>::
+ post_integer ()
+ {
+ return value_;
+ }
+
+ // negative_integer
+ //
+ template <typename C>
+ void negative_integer_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void negative_integer_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void negative_integer_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ zc_istream<C> is (str);
+
+ if (!(is >> value_ && is.exhausted () && value_ < 0))
+ throw invalid_value<C> (bits::negative_integer<C> (), str);
+ }
+
+ template <typename C>
+ long long negative_integer_pimpl<C>::
+ post_negative_integer ()
+ {
+ return value_;
+ }
+
+
+ // non_positive_integer
+ //
+ template <typename C>
+ void non_positive_integer_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void non_positive_integer_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void non_positive_integer_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ zc_istream<C> is (str);
+
+ if (!(is >> value_ && is.exhausted () && value_ <= 0))
+ throw invalid_value<C> (bits::non_positive_integer<C> (), str);
+ }
+
+ template <typename C>
+ long long non_positive_integer_pimpl<C>::
+ post_non_positive_integer ()
+ {
+ return value_;
+ }
+
+ // positive_integer
+ //
+ template <typename C>
+ void positive_integer_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void positive_integer_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void positive_integer_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ zc_istream<C> is (str);
+
+ if (!(is >> value_ && is.exhausted () && value_ > 0))
+ throw invalid_value<C> (bits::positive_integer<C> (), str);
+ }
+
+ template <typename C>
+ unsigned long long positive_integer_pimpl<C>::
+ post_positive_integer ()
+ {
+ return value_;
+ }
+
+
+ // non_negative_integer
+ //
+ template <typename C>
+ void non_negative_integer_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void non_negative_integer_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void non_negative_integer_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ zc_istream<C> is (str);
+
+ if (!(is >> value_ && is.exhausted ()))
+ throw invalid_value<C> (bits::non_negative_integer<C> (), str);
+ }
+
+ template <typename C>
+ unsigned long long non_negative_integer_pimpl<C>::
+ post_non_negative_integer ()
+ {
+ return value_;
+ }
+
+
+ // float
+ //
+ template <typename C>
+ void float_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void float_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void float_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ if (str == bits::positive_inf<C> ())
+ value_ = std::numeric_limits<float>::infinity ();
+ else if (str == bits::negative_inf<C> ())
+ value_ = -std::numeric_limits<float>::infinity ();
+ else if (str == bits::nan<C> ())
+ value_ = std::numeric_limits<float>::quiet_NaN ();
+ else
+ {
+ zc_istream<C> is (str);
+ is.imbue (std::locale::classic ());
+
+ if (!(is >> value_ && is.exhausted ()))
+ throw invalid_value<C> (bits::float_<C> (), str);
+ }
+ }
+
+ template <typename C>
+ float float_pimpl<C>::
+ post_float ()
+ {
+ return value_;
+ }
+
+
+ // double
+ //
+ template <typename C>
+ void double_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void double_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void double_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ if (str == bits::positive_inf<C> ())
+ value_ = std::numeric_limits<double>::infinity ();
+ else if (str == bits::negative_inf<C> ())
+ value_ = -std::numeric_limits<double>::infinity ();
+ else if (str == bits::nan<C> ())
+ value_ = std::numeric_limits<double>::quiet_NaN ();
+ else
+ {
+ zc_istream<C> is (str);
+ is.imbue (std::locale::classic ());
+
+ if (!(is >> value_ && is.exhausted ()))
+ throw invalid_value<C> (bits::double_<C> (), str);
+ }
+ }
+
+ template <typename C>
+ double double_pimpl<C>::
+ post_double ()
+ {
+ return value_;
+ }
+
+ // decimal
+ //
+ template <typename C>
+ void decimal_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void decimal_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ void decimal_pimpl<C>::
+ _post ()
+ {
+ ro_string<C> str (str_);
+ trim (str);
+
+ zc_istream<C> is (str);
+ is.imbue (std::locale::classic ());
+
+ //@@ TODO: now we accept scientific notations and INF/NaN.
+ //
+ if (!(is >> value_ && is.exhausted ()))
+ throw invalid_value<C> (bits::decimal<C> (), str);
+ }
+
+ template <typename C>
+ double decimal_pimpl<C>::
+ post_decimal ()
+ {
+ return value_;
+ }
+
+ // string
+ //
+ template <typename C>
+ void string_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void string_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> string_pimpl<C>::
+ post_string ()
+ {
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // normalized_string
+ //
+ template <typename C>
+ void normalized_string_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void normalized_string_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> normalized_string_pimpl<C>::
+ post_normalized_string ()
+ {
+ typedef typename std::basic_string<C>::size_type size_type;
+
+ size_type size (str_.size ());
+
+ for (size_type i (0); i < size; ++i)
+ {
+ C& c = str_[i];
+
+ if (c == C (0x0A) || c == C (0x0D) || c == C (0x09))
+ c = C (0x20);
+ }
+
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // token
+ //
+ template <typename C>
+ void token_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void token_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> token_pimpl<C>::
+ post_token ()
+ {
+ typedef typename std::basic_string<C>::size_type size_type;
+
+ size_type size (str_.size ());
+ size_type j (0);
+
+ bool subs (false);
+
+ for (size_type i (0); i < size; ++i)
+ {
+ C c = str_[i];
+
+ if (c == C (0x20) || c == C (0x0A) ||
+ c == C (0x0D) || c == C (0x09))
+ {
+ subs = true;
+ }
+ else
+ {
+ if (subs)
+ {
+ subs = false;
+ str_[j++] = C (0x20);
+ }
+
+ str_[j++] = c;
+ }
+ }
+
+ str_.resize (j);
+
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // name
+ //
+ template <typename C>
+ void name_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void name_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void name_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+
+ // For now we are only checking the US-ASCII characters.
+ //
+
+ bool ok (size != 0);
+
+ if (ok)
+ {
+ unsigned int c (static_cast<unsigned int> (str_[0]));
+
+ ok = c >= 0x80 ||
+ (bits::char_table<unsigned char>::table[c] &
+ bits::name_first_mask);
+
+ if (ok)
+ {
+ for (size_type i (1); i < size; ++i)
+ {
+ c = static_cast<unsigned int> (str_[i]);
+
+ if (c < 0x80 &&
+ !(bits::char_table<unsigned char>::table[c] &
+ bits::name_mask))
+ {
+ ok = false;
+ break;
+ }
+ }
+ }
+ }
+
+ if (!ok)
+ throw invalid_value<C> (bits::name<C> (), tmp);
+
+ str_.resize (size);
+ }
+
+ template <typename C>
+ std::basic_string<C> name_pimpl<C>::
+ post_name ()
+ {
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // nmtoken
+ //
+ template <typename C>
+ void nmtoken_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void nmtoken_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void nmtoken_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+
+ // For now we are only checking the US-ASCII characters.
+ //
+
+ bool ok (size != 0);
+
+ if (ok)
+ {
+ for (size_type i (0); i < size; ++i)
+ {
+ unsigned int c (static_cast<unsigned int> (str_[i]));
+
+ if (c < 0x80 &&
+ !(bits::char_table<unsigned char>::table[c] &
+ bits::name_mask))
+ {
+ ok = false;
+ break;
+ }
+ }
+ }
+
+ if (!ok)
+ throw invalid_value<C> (bits::nmtoken<C> (), tmp);
+
+ str_.resize (size);
+ }
+
+ template <typename C>
+ std::basic_string<C> nmtoken_pimpl<C>::
+ post_nmtoken ()
+ {
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // nmtokens
+ //
+ template <typename C>
+ void nmtokens_pimpl<C>::
+ _pre ()
+ {
+ nmtokens_pskel<C>::_pre ();
+ seq_.clear ();
+ }
+
+ template <typename C>
+ void nmtokens_pimpl<C>::
+ _post ()
+ {
+ nmtokens_pskel<C>::_post ();
+
+ // Should have at least one element.
+ //
+ if (seq_.size () < 1)
+ {
+ ro_string<C> tmp;
+ throw invalid_value<C> (bits::nmtokens<C> (), tmp);
+ }
+ }
+
+ template <typename C>
+ string_sequence<C> nmtokens_pimpl<C>::
+ post_nmtokens ()
+ {
+ string_sequence<C> r;
+ r.swap (seq_);
+ return r;
+ }
+
+ template <typename C>
+ void nmtokens_pimpl<C>::
+ _xsd_parse_item (const ro_string<C>& s)
+ {
+ parser_.pre ();
+ parser_._pre ();
+ parser_._characters (s);
+ parser_._post ();
+ seq_.push_back (parser_.post_nmtoken ());
+ }
+
+ // ncname
+ //
+ namespace bits
+ {
+ template <typename C>
+ bool
+ valid_ncname (const C* s, typename ro_string<C>::size_type size)
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ // For now we are only checking the US-ASCII characters.
+ //
+ bool ok (size != 0);
+
+ if (ok)
+ {
+ unsigned int c (static_cast<unsigned int> (s[0]));
+
+ ok = c >= 0x80 ||
+ ((bits::char_table<unsigned char>::table[c] &
+ bits::name_first_mask) && c != C (':'));
+
+ if (ok)
+ {
+ for (size_type i (1); i < size; ++i)
+ {
+ c = static_cast<unsigned int> (s[i]);
+
+ if (c < 0x80 &&
+ !(bits::char_table<unsigned char>::table[c] &
+ bits::ncname_mask))
+ {
+ ok = false;
+ break;
+ }
+ }
+ }
+ }
+
+ return ok;
+ }
+ }
+
+ template <typename C>
+ void ncname_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void ncname_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void ncname_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+
+ if (!bits::valid_ncname (tmp.data (), size))
+ throw invalid_value<C> (bits::ncname<C> (), tmp);
+
+ str_.resize (size);
+ }
+
+ template <typename C>
+ std::basic_string<C> ncname_pimpl<C>::
+ post_ncname ()
+ {
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // id
+ //
+ template <typename C>
+ void id_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void id_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void id_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+
+ if (!bits::valid_ncname (tmp.data (), size))
+ throw invalid_value<C> (bits::id<C> (), tmp);
+
+ str_.resize (size);
+ }
+
+ template <typename C>
+ std::basic_string<C> id_pimpl<C>::
+ post_id ()
+ {
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // idref
+ //
+ template <typename C>
+ void idref_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void idref_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void idref_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+
+ if (!bits::valid_ncname (tmp.data (), size))
+ throw invalid_value<C> (bits::idref<C> (), tmp);
+
+ str_.resize (size);
+ }
+
+ template <typename C>
+ std::basic_string<C> idref_pimpl<C>::
+ post_idref ()
+ {
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // idrefs
+ //
+ template <typename C>
+ void idrefs_pimpl<C>::
+ _pre ()
+ {
+ idrefs_pskel<C>::_pre ();
+ seq_.clear ();
+ }
+
+ template <typename C>
+ void idrefs_pimpl<C>::
+ _post ()
+ {
+ idrefs_pskel<C>::_post ();
+
+ // Should have at least one element.
+ //
+ if (seq_.size () < 1)
+ {
+ ro_string<C> tmp;
+ throw invalid_value<C> (bits::idrefs<C> (), tmp);
+ }
+ }
+
+ template <typename C>
+ string_sequence<C> idrefs_pimpl<C>::
+ post_idrefs ()
+ {
+ string_sequence<C> r;
+ r.swap (seq_);
+ return r;
+ }
+
+ template <typename C>
+ void idrefs_pimpl<C>::
+ _xsd_parse_item (const ro_string<C>& s)
+ {
+ parser_.pre ();
+ parser_._pre ();
+ parser_._characters (s);
+ parser_._post ();
+ seq_.push_back (parser_.post_idref ());
+ }
+
+ // language
+ //
+ template <typename C>
+ void language_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void language_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void language_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+
+ // language := ALPHA{1,8} *(-(ALPHA | DIGIT){1,8})
+ //
+ bool ok (true);
+
+ for (size_type tag (0), i (0); ; ++tag)
+ {
+ size_type n (0);
+
+ for (; i < size && n < 8; ++n, ++i)
+ {
+ C c (tmp[i]);
+
+ if (!((c >= C ('a') && c <= C ('z')) ||
+ (c >= C ('A') && c <= C ('Z')) ||
+ (tag != 0 && c >= C ('0') && c <= C ('9'))))
+ break;
+ }
+
+ if (n == 0)
+ {
+ ok = false;
+ break;
+ }
+
+ if (i == size)
+ break;
+
+ if (tmp[i++] != C ('-'))
+ {
+ ok = false;
+ break;
+ }
+ }
+
+ if (!ok)
+ throw invalid_value<C> (bits::language<C> (), tmp);
+
+ str_.resize (size);
+ }
+
+ template <typename C>
+ std::basic_string<C> language_pimpl<C>::
+ post_language ()
+ {
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // uri
+ //
+ template <typename C>
+ void uri_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void uri_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ std::basic_string<C> uri_pimpl<C>::
+ post_uri ()
+ {
+ // According to Datatypes 3.2.17 and RFC2396 pretty much anything
+ // can be a URI and conforming processors do not need to figure
+ // out and verify particular URI schemes.
+ //
+ ro_string<C> tmp (str_);
+ str_.resize (trim_right (tmp));
+
+ std::basic_string<C> r;
+ r.swap (str_);
+ return r;
+ }
+
+ // qname
+ //
+ template <typename C>
+ void qname_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void qname_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void qname_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ size_type pos (tmp.find (C (':')));
+
+ const C* s (tmp.data ());
+
+ if (pos != ro_string<C>::npos)
+ {
+ if (!bits::valid_ncname (s, pos) ||
+ !bits::valid_ncname (s + pos + 1, size - pos - 1))
+ throw invalid_value<C> (bits::qname<C> (), tmp);
+
+ prefix_.assign (s, pos);
+ name_.assign (s + pos + 1, size - pos - 1);
+ }
+ else
+ {
+ if (!bits::valid_ncname (s, size))
+ throw invalid_value<C> (bits::qname<C> (), tmp);
+
+ prefix_.clear ();
+ str_.resize (size);
+ name_.swap (str_);
+ }
+ }
+
+ template <typename C>
+ qname<C> qname_pimpl<C>::
+ post_qname ()
+ {
+ return prefix_.empty ()
+ ? qname<C> (name_)
+ : qname<C> (prefix_, name_);
+ }
+
+ // base64_binary
+ //
+ template <typename C>
+ void base64_binary_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void base64_binary_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ namespace bits
+ {
+ template <typename C>
+ inline unsigned char
+ base64_decode (C c)
+ {
+ unsigned char r (0xFF);
+
+ if (c >= C('A') && c <= C ('Z'))
+ r = static_cast<unsigned char> (c - C ('A'));
+ else if (c >= C('a') && c <= C ('z'))
+ r = static_cast<unsigned char> (c - C ('a') + 26);
+ else if (c >= C('0') && c <= C ('9'))
+ r = static_cast<unsigned char> (c - C ('0') + 52);
+ else if (c == C ('+'))
+ r = 62;
+ else if (c == C ('/'))
+ r = 63;
+
+ return r;
+ }
+ }
+
+ template <typename C>
+ void base64_binary_pimpl<C>::
+ _post ()
+ {
+ typedef typename std::basic_string<C>::size_type size_type;
+
+ size_type size (str_.size ());
+ const C* src (str_.c_str ());
+
+ // Remove all whitespaces.
+ //
+ {
+ size_type j (0);
+
+ bool subs (false);
+
+ for (size_type i (0); i < size; ++i)
+ {
+ C c = str_[i];
+
+ if (c == C (0x20) || c == C (0x0A) ||
+ c == C (0x0D) || c == C (0x09))
+ {
+ subs = true;
+ }
+ else
+ {
+ if (subs)
+ subs = false;
+
+ str_[j++] = c;
+ }
+ }
+
+ size = j;
+ str_.resize (size);
+ }
+
+ // Our length should be a multiple of four.
+ //
+ if (size == 0 || size % 4 != 0)
+ throw invalid_value<C> (bits::base64_binary<C> (), str_);
+
+ size_type quad_count (size / 4);
+ size_type capacity (quad_count * 3 + 1);
+
+ buf_.reset (new buffer (capacity, capacity));
+ char* dst (buf_->data ());
+
+ size_type si (0), di (0); // Source and destination indexes.
+
+ // Process all quads except the last one.
+ //
+ unsigned char b1, b2, b3, b4;
+
+ for (size_type q (0); q < quad_count - 1; ++q)
+ {
+ b1 = bits::base64_decode (src[si++]);
+ b2 = bits::base64_decode (src[si++]);
+ b3 = bits::base64_decode (src[si++]);
+ b4 = bits::base64_decode (src[si++]);
+
+ if (b1 == 0xFF || b2 == 0xFF || b3 == 0xFF || b4 == 0xFF)
+ throw invalid_value<C> (bits::base64_binary<C> (), str_);
+
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ dst[di++] = (b2 << 4) | (b3 >> 2);
+ dst[di++] = (b3 << 6) | b4;
+ }
+
+ // Process the last quad. The first two octets are always there.
+ //
+ b1 = bits::base64_decode (src[si++]);
+ b2 = bits::base64_decode (src[si++]);
+
+ if (b1 == 0xFF || b2 == 0xFF)
+ throw invalid_value<C> (bits::base64_binary<C> (), str_);
+
+ C e3 (src[si++]);
+ C e4 (src[si++]);
+
+ if (e4 == C ('='))
+ {
+ if (e3 == C ('='))
+ {
+ // Two pads. Last 4 bits in b2 should be zero.
+ //
+ if ((b2 & 0x0F) != 0)
+ throw invalid_value<C> (bits::base64_binary<C> (), str_);
+
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ }
+ else
+ {
+ // One pad. Last 2 bits in b3 should be zero.
+ //
+ b3 = bits::base64_decode (e3);
+
+ if (b3 == 0xFF || (b3 & 0x03) != 0)
+ throw invalid_value<C> (bits::base64_binary<C> (), str_);
+
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ dst[di++] = (b2 << 4) | (b3 >> 2);
+ }
+ }
+ else
+ {
+ // No pads.
+ //
+ b3 = bits::base64_decode (e3);
+ b4 = bits::base64_decode (e4);
+
+ if (b3 == 0xFF || b4 == 0xFF)
+ throw invalid_value<C> (bits::base64_binary<C> (), str_);
+
+ dst[di++] = (b1 << 2) | (b2 >> 4);
+ dst[di++] = (b2 << 4) | (b3 >> 2);
+ dst[di++] = (b3 << 6) | b4;
+ }
+
+ // Set the real size.
+ //
+ buf_->size (di);
+ }
+
+ template <typename C>
+ std::auto_ptr<buffer> base64_binary_pimpl<C>::
+ post_base64_binary ()
+ {
+ return buf_;
+ }
+
+ // hex_binary
+ //
+ template <typename C>
+ void hex_binary_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void hex_binary_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ namespace bits
+ {
+ template <typename C>
+ inline unsigned char
+ hex_decode (C c)
+ {
+ unsigned char r (0xFF);
+
+ if (c >= C('0') && c <= C ('9'))
+ r = static_cast<unsigned char> (c - C ('0'));
+ else if (c >= C ('A') && c <= C ('F'))
+ r = static_cast<unsigned char> (10 + (c - C ('A')));
+ else if (c >= C ('a') && c <= C ('f'))
+ r = static_cast<unsigned char> (10 + (c - C ('a')));
+
+ return r;
+ }
+ }
+
+ template <typename C>
+ void hex_binary_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+
+ if (size % 2 != 0)
+ throw invalid_value<C> (bits::hex_binary<C> (), tmp);
+
+ buffer::size_t n (size / 2);
+ buf_.reset (new buffer (n));
+
+ if (n != 0)
+ {
+ const C* src (tmp.data ());
+ char* dst (buf_->data ());
+ buffer::size_t i (0);
+
+ for (; i < n; ++i)
+ {
+ unsigned char h (bits::hex_decode (src[2 * i]));
+ unsigned char l (bits::hex_decode (src[2 * i + 1]));
+
+ if (h == 0xFF || l == 0xFF)
+ break;
+
+ dst[i] = (h << 4) | l;
+ }
+
+ if (i != n)
+ throw invalid_value<C> (bits::hex_binary<C> (), tmp);
+ }
+ }
+
+ template <typename C>
+ std::auto_ptr<buffer> hex_binary_pimpl<C>::
+ post_hex_binary ()
+ {
+ return buf_;
+ }
+
+ // time_zone
+ //
+ namespace bits
+ {
+ // Datatypes 3.2.7.3. Return false if time zone is invalid.
+ //
+ template <typename C>
+ bool
+ parse_tz (const C* s,
+ typename std::basic_string<C>::size_type n,
+ short& h, short& m)
+ {
+ // time_zone := Z|(+|-)HH:MM
+ //
+ if (n == 0)
+ {
+ return false;
+ }
+ else if (s[0] == 'Z')
+ {
+ if (n != 1)
+ return false;
+
+ h = 0;
+ m = 0;
+ }
+ else
+ {
+ if (n != 6 || (s[0] != '-' && s[0] != '+') || s[3] != ':')
+ return false;
+
+ // Parse hours.
+ //
+ char d1 = s[1];
+ char d2 = s[2];
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ return false;
+
+ h = 10 * (d1 - '0') + (d2 - '0');
+
+ if (h > 14)
+ return false;
+
+ // Parse minutes.
+ //
+ d1 = s[4];
+ d2 = s[5];
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ return false;
+
+ m = 10 * (d1 - '0') + (d2 - '0');
+
+ if (m > 59 || (h == 14 && m != 0))
+ return false;
+
+ if (s[0] == '-')
+ {
+ h = -h;
+ m = -m;
+ }
+ }
+
+ return true;
+ }
+ }
+
+ // gday
+ //
+ template <typename C>
+ void gday_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void gday_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void gday_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ // gday := ---DD[Z|(+|-)HH:MM]
+ //
+ if (size < 5 ||
+ s[0] != C ('-') || s[1] != C ('-') || s[2] != C ('-'))
+ throw invalid_value<C> (bits::gday<C> (), tmp);
+
+ C d1 (s[3]), d2 (s[4]);
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ throw invalid_value<C> (bits::gday<C> (), tmp);
+
+ day_ = 10 * (d1 - '0') + (d2 - '0');
+
+ if (day_ < 1 || day_ > 31)
+ throw invalid_value<C> (bits::gday<C> (), tmp);
+
+ if (size > 5)
+ {
+ if (!bits::parse_tz (s + 5, size - 5, zh_, zm_))
+ throw invalid_value<C> (bits::gday<C> (), tmp);
+
+ z_ = true;
+ }
+ else
+ z_ = false;
+ }
+
+ template <typename C>
+ gday gday_pimpl<C>::
+ post_gday ()
+ {
+ return z_ ? gday (day_, zh_, zm_) : gday (day_);
+ }
+
+ // gmonth
+ //
+ template <typename C>
+ void gmonth_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void gmonth_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void gmonth_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ // gmonth := --MM[Z|(+|-)HH:MM]
+ //
+ if (size < 4 || s[0] != C ('-') || s[1] != C ('-'))
+ throw invalid_value<C> (bits::gmonth<C> (), tmp);
+
+ C d1 (s[2]), d2 (s[3]);
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ throw invalid_value<C> (bits::gmonth<C> (), tmp);
+
+ month_ = 10 * (d1 - '0') + (d2 - '0');
+
+ if (month_ < 1 || month_ > 12)
+ throw invalid_value<C> (bits::gmonth<C> (), tmp);
+
+ if (size > 4)
+ {
+ if (!bits::parse_tz (s + 4, size - 4, zh_, zm_))
+ throw invalid_value<C> (bits::gmonth<C> (), tmp);
+
+ z_ = true;
+ }
+ else
+ z_ = false;
+ }
+
+ template <typename C>
+ gmonth gmonth_pimpl<C>::
+ post_gmonth ()
+ {
+ return z_ ? gmonth (month_, zh_, zm_) : gmonth (month_);
+ }
+
+ // gyear
+ //
+ template <typename C>
+ void gyear_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void gyear_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void gyear_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ // gyear := [-]CCYY[N]*[Z|(+|-)HH:MM]
+ //
+
+ if (size < 4 || (s[0] == C ('-') && size < 5))
+ throw invalid_value<C> (bits::gyear<C> (), tmp);
+
+ // Find the end of the year token.
+ //
+ size_type pos (s[0] == C ('-') ? 5 : 4);
+ for (; pos < size; ++pos)
+ {
+ C c (s[pos]);
+
+ if (c == C ('Z') || c == C ('+') || c == C ('-'))
+ break;
+ }
+
+ ro_string<C> year_fragment (s, pos);
+ zc_istream<C> is (year_fragment);
+
+ if (!(is >> year_ && is.exhausted () && year_ != 0))
+ throw invalid_value<C> (bits::gyear<C> (), tmp);
+
+ if (pos < size)
+ {
+ if (!bits::parse_tz (s + pos, size - pos, zh_, zm_))
+ throw invalid_value<C> (bits::gyear<C> (), tmp);
+
+ z_ = true;
+ }
+ else
+ z_ = false;
+ }
+
+ template <typename C>
+ gyear gyear_pimpl<C>::
+ post_gyear ()
+ {
+ return z_ ? gyear (year_, zh_, zm_) : gyear (year_);
+ }
+
+ // gmonth_day
+ //
+ template <typename C>
+ void gmonth_day_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void gmonth_day_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void gmonth_day_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ // gmonth_day := --MM-DD[Z|(+|-)HH:MM]
+ //
+ if (size < 7 ||
+ s[0] != C ('-') || s[1] != C ('-') || s[4] != C ('-'))
+ throw invalid_value<C> (bits::gmonth_day<C> (), tmp);
+
+ // month
+ //
+ C d1 (s[2]), d2 (s[3]);
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ throw invalid_value<C> (bits::gmonth_day<C> (), tmp);
+
+ month_ = 10 * (d1 - '0') + (d2 - '0');
+
+ if (month_ < 1 || month_ > 12)
+ throw invalid_value<C> (bits::gmonth_day<C> (), tmp);
+
+ // day
+ //
+ d1 = s[5];
+ d2 = s[6];
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ throw invalid_value<C> (bits::gmonth_day<C> (), tmp);
+
+ day_ = 10 * (d1 - '0') + (d2 - '0');
+
+ if (day_ < 1 || day_ > 31)
+ throw invalid_value<C> (bits::gmonth_day<C> (), tmp);
+
+ // zone
+ //
+ if (size > 7)
+ {
+ if (!bits::parse_tz (s + 7, size - 7, zh_, zm_))
+ throw invalid_value<C> (bits::gmonth_day<C> (), tmp);
+
+ z_ = true;
+ }
+ else
+ z_ = false;
+ }
+
+ template <typename C>
+ gmonth_day gmonth_day_pimpl<C>::
+ post_gmonth_day ()
+ {
+ return z_
+ ? gmonth_day (month_, day_, zh_, zm_)
+ : gmonth_day (month_, day_);
+ }
+
+ // gyear_month
+ //
+ template <typename C>
+ void gyear_month_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void gyear_month_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void gyear_month_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ // gyear_month := [-]CCYY[N]*-MM[Z|(+|-)HH:MM]
+ //
+
+ if (size < 7 || (s[0] == C ('-') && size < 8))
+ throw invalid_value<C> (bits::gyear_month<C> (), tmp);
+
+ // Find the end of the year token.
+ //
+ size_type pos (tmp.find (C ('-'), s[0] == C ('-') ? 5 : 4));
+
+ if (pos == ro_string<C>::npos || (size - pos - 1) < 2)
+ throw invalid_value<C> (bits::gyear_month<C> (), tmp);
+
+ ro_string<C> year_fragment (s, pos);
+ zc_istream<C> yis (year_fragment);
+
+ if (!(yis >> year_ && yis.exhausted () && year_ != 0))
+ throw invalid_value<C> (bits::gyear_month<C> (), tmp);
+
+ // month
+ //
+ C d1 (s[pos + 1]), d2 (s[pos + 2]);
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ throw invalid_value<C> (bits::gyear_month<C> (), tmp);
+
+ month_ = 10 * (d1 - '0') + (d2 - '0');
+
+ if (month_ < 1 || month_ > 12)
+ throw invalid_value<C> (bits::gyear_month<C> (), tmp);
+
+ // zone
+ //
+ pos += 3;
+
+ if (pos < size)
+ {
+ if (!bits::parse_tz (s + pos, size - pos, zh_, zm_))
+ throw invalid_value<C> (bits::gyear_month<C> (), tmp);
+
+ z_ = true;
+ }
+ else
+ z_ = false;
+ }
+
+ template <typename C>
+ gyear_month gyear_month_pimpl<C>::
+ post_gyear_month ()
+ {
+ return z_
+ ? gyear_month (year_, month_, zh_, zm_)
+ : gyear_month (year_, month_);
+ }
+
+ // date
+ //
+ template <typename C>
+ void date_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void date_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void date_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ // date := [-]CCYY[N]*-MM-DD[Z|(+|-)HH:MM]
+ //
+
+ if (size < 10 || (s[0] == C ('-') && size < 11))
+ throw invalid_value<C> (bits::date<C> (), tmp);
+
+ // Find the end of the year token.
+ //
+ size_type pos (tmp.find (C ('-'), s[0] == C ('-') ? 5 : 4));
+
+ if (pos == ro_string<C>::npos
+ || (size - pos - 1) < 5
+ || s[pos + 3] != C ('-'))
+ throw invalid_value<C> (bits::date<C> (), tmp);
+
+ ro_string<C> year_fragment (s, pos);
+ zc_istream<C> yis (year_fragment);
+
+ if (!(yis >> year_ && yis.exhausted () && year_ != 0))
+ throw invalid_value<C> (bits::date<C> (), tmp);
+
+ // month
+ //
+ C d1 (s[pos + 1]), d2 (s[pos + 2]);
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ throw invalid_value<C> (bits::date<C> (), tmp);
+
+ month_ = 10 * (d1 - '0') + (d2 - '0');
+
+ if (month_ < 1 || month_ > 12)
+ throw invalid_value<C> (bits::date<C> (), tmp);
+
+ // day
+ //
+ d1 = s[pos + 4];
+ d2 = s[pos + 5];
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ throw invalid_value<C> (bits::date<C> (), tmp);
+
+ day_ = 10 * (d1 - '0') + (d2 - '0');
+
+ if (day_ < 1 || day_ > 31)
+ throw invalid_value<C> (bits::date<C> (), tmp);
+
+ // zone
+ //
+ pos += 6;
+
+ if (pos < size)
+ {
+ if (!bits::parse_tz (s + pos, size - pos, zh_, zm_))
+ throw invalid_value<C> (bits::date<C> (), tmp);
+
+ z_ = true;
+ }
+ else
+ z_ = false;
+ }
+
+ template <typename C>
+ date date_pimpl<C>::
+ post_date ()
+ {
+ return z_
+ ? date (year_, month_, day_, zh_, zm_)
+ : date (year_, month_, day_);
+ }
+
+ // time
+ //
+ template <typename C>
+ void time_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void time_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void time_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ // time := HH:MM:SS[.S+][Z|(+|-)HH:MM]
+ //
+
+ if (size < 8 || s[2] != C (':') || s[5] != C (':'))
+ throw invalid_value<C> (bits::time<C> (), tmp);
+
+ // hours
+ //
+ C d1 (s[0]), d2 (s[1]);
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ throw invalid_value<C> (bits::time<C> (), tmp);
+
+ hours_ = 10 * (d1 - '0') + (d2 - '0');
+
+ if (hours_ > 24)
+ throw invalid_value<C> (bits::time<C> (), tmp);
+
+ // minutes
+ //
+ d1 = s[3];
+ d2 = s[4];
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ throw invalid_value<C> (bits::time<C> (), tmp);
+
+ minutes_ = 10 * (d1 - '0') + (d2 - '0');
+
+ if (minutes_ > 59)
+ throw invalid_value<C> (bits::time<C> (), tmp);
+
+ // Find the end of the seconds fragment.
+ //
+ size_type pos (8);
+ for (; pos < size; ++pos)
+ {
+ C c (s[pos]);
+
+ if (c == C ('Z') || c == C ('+') || c == C ('-'))
+ break;
+ }
+
+ // At least one digit should follow the fraction point.
+ //
+ if ((pos - 6) == 3)
+ throw invalid_value<C> (bits::time<C> (), tmp);
+
+ ro_string<C> seconds_fragment (s + 6, pos - 6);
+ zc_istream<C> sis (seconds_fragment);
+
+ if (!(sis >> seconds_ && sis.exhausted () && seconds_ < 60.0))
+ throw invalid_value<C> (bits::time<C> (), tmp);
+
+ if (hours_ == 24 && (minutes_ != 0 || seconds_ != 0.0))
+ throw invalid_value<C> (bits::time<C> (), tmp);
+
+ // zone
+ //
+ if (pos < size)
+ {
+ if (!bits::parse_tz (s + pos, size - pos, zh_, zm_))
+ throw invalid_value<C> (bits::time<C> (), tmp);
+
+ z_ = true;
+ }
+ else
+ z_ = false;
+ }
+
+ template <typename C>
+ time time_pimpl<C>::
+ post_time ()
+ {
+ return z_
+ ? time (hours_, minutes_, seconds_, zh_, zm_)
+ : time (hours_, minutes_, seconds_);
+ }
+
+
+ // date_time
+ //
+ template <typename C>
+ void date_time_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void date_time_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ template <typename C>
+ void date_time_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+ const C* s (tmp.data ());
+
+ // date_time := [-]CCYY[N]*-MM-DDTHH:MM:SS[.S+][Z|(+|-)HH:MM]
+ //
+
+ if (size < 19 || (s[0] == C ('-') && size < 20))
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ // Find the end of the year token.
+ //
+ size_type pos (tmp.find (C ('-'), s[0] == C ('-') ? 5 : 4));
+
+ if (pos == ro_string<C>::npos || (size - pos - 1) < 14
+ || s[pos + 3] != C ('-') || s[pos + 6] != C ('T')
+ || s[pos + 9] != C (':') || s[pos + 12] != C (':'))
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ // year
+ //
+ ro_string<C> year_fragment (s, pos);
+ zc_istream<C> yis (year_fragment);
+
+ if (!(yis >> year_ && yis.exhausted () && year_ != 0))
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ // month
+ //
+ C d1 (s[pos + 1]), d2 (s[pos + 2]);
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ month_ = 10 * (d1 - '0') + (d2 - '0');
+
+ if (month_ < 1 || month_ > 12)
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ // day
+ //
+ d1 = s[pos + 4];
+ d2 = s[pos + 5];
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ day_ = 10 * (d1 - '0') + (d2 - '0');
+
+ if (day_ < 1 || day_ > 31)
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ pos += 7; // Point to the first H.
+
+ // hours
+ //
+ d1 = s[pos];
+ d2 = s[pos + 1];
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ hours_ = 10 * (d1 - '0') + (d2 - '0');
+
+ if (hours_ > 24)
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ // minutes
+ //
+ d1 = s[pos + 3];
+ d2 = s[pos + 4];
+
+ if (d1 < '0' || d1 > '9' || d2 < '0' || d2 > '9')
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ minutes_ = 10 * (d1 - '0') + (d2 - '0');
+
+ if (minutes_ > 59)
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ // Find the end of the seconds fragment.
+ //
+ pos += 6; // Point to the first S.
+
+ size_type sec_end (pos + 2);
+ for (; sec_end < size; ++sec_end)
+ {
+ C c (s[sec_end]);
+
+ if (c == C ('Z') || c == C ('+') || c == C ('-'))
+ break;
+ }
+
+ // At least one digit should should follow the fraction point.
+ //
+ if ((sec_end - pos) == 3)
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ ro_string<C> seconds_fragment (s + pos, sec_end - pos);
+ zc_istream<C> sis (seconds_fragment);
+
+ if (!(sis >> seconds_ && sis.exhausted () && seconds_ < 60.0))
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ if (hours_ == 24 && (minutes_ != 0 || seconds_ != 0.0))
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ // zone
+ //
+ if (sec_end < size)
+ {
+ if (!bits::parse_tz (s + sec_end, size - sec_end, zh_, zm_))
+ throw invalid_value<C> (bits::date_time<C> (), tmp);
+
+ z_ = true;
+ }
+ else
+ z_ = false;
+ }
+
+ template <typename C>
+ date_time date_time_pimpl<C>::
+ post_date_time ()
+ {
+ return z_
+ ? date_time (year_, month_, day_, hours_, minutes_, seconds_,
+ zh_, zm_)
+ : date_time (year_, month_, day_, hours_, minutes_, seconds_);
+ }
+
+ // duration
+ //
+ template <typename C>
+ void duration_pimpl<C>::
+ _pre ()
+ {
+ str_.clear ();
+ }
+
+ template <typename C>
+ void duration_pimpl<C>::
+ _characters (const ro_string<C>& s)
+ {
+ if (str_.size () == 0)
+ {
+ ro_string<C> tmp (s.data (), s.size ());
+
+ if (trim_left (tmp) != 0)
+ str_ += tmp;
+ }
+ else
+ str_ += s;
+ }
+
+ namespace bits
+ {
+ template <typename C>
+ inline typename ro_string<C>::size_type
+ duration_delim (const C* s,
+ typename ro_string<C>::size_type pos,
+ typename ro_string<C>::size_type size)
+ {
+ const C* p (s + pos);
+ for (; p < (s + size); ++p)
+ {
+ if (*p == C ('Y') || *p == C ('D') || *p == C ('M') ||
+ *p == C ('H') || *p == C ('M') || *p == C ('S') ||
+ *p == C ('T'))
+ break;
+ }
+
+ return p - s;
+ }
+ }
+
+ template <typename C>
+ void duration_pimpl<C>::
+ _post ()
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str_);
+ size_type size (trim_right (tmp));
+
+ negative_ = false;
+ years_ = 0;
+ months_ = 0;
+ days_ = 0;
+ hours_ = 0;
+ minutes_ = 0;
+ seconds_ = 0.0;
+
+ // duration := [-]P[nY][nM][nD][TnHnMn[.n+]S]
+ //
+ const C* s (tmp.data ());
+
+ if (size < 3 || (s[0] == C ('-') && size < 4))
+ throw invalid_value<C> (bits::duration<C> (), tmp);
+
+ size_type pos (0);
+
+ if (s[0] == C ('-'))
+ {
+ negative_ = true;
+ pos++;
+ }
+
+ if (s[pos++] != C ('P'))
+ throw invalid_value<C> (bits::duration<C> (), tmp);
+
+ size_type del (bits::duration_delim (s, pos, size));
+
+ // Duration should contain at least one component.
+ //
+ if (del == size)
+ throw invalid_value<C> (bits::duration<C> (), tmp);
+
+ if (s[del] == C ('Y'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+
+ if (!(is >> years_ && is.exhausted ()))
+ throw invalid_value<C> (bits::duration<C> (), tmp);
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, size);
+ }
+
+ if (del != size && s[del] == C ('M'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+
+ if (!(is >> months_ && is.exhausted ()))
+ throw invalid_value<C> (bits::duration<C> (), tmp);
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, size);
+ }
+
+ if (del != size && s[del] == C ('D'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+
+ if (!(is >> days_ && is.exhausted ()))
+ throw invalid_value<C> (bits::duration<C> (), tmp);
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, size);
+ }
+
+ if (del != size && s[del] == C ('T'))
+ {
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, size);
+
+ // At least one time component should be present.
+ //
+ if (del == size)
+ throw invalid_value<C> (bits::duration<C> (), tmp);
+
+ if (s[del] == C ('H'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+
+ if (!(is >> hours_ && is.exhausted ()))
+ throw invalid_value<C> (bits::duration<C> (), tmp);
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, size);
+ }
+
+ if (del != size && s[del] == C ('M'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+
+ if (!(is >> minutes_ && is.exhausted ()))
+ throw invalid_value<C> (bits::duration<C> (), tmp);
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, size);
+ }
+
+ if (del != size && s[del] == C ('S'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+
+ if (!(is >> seconds_ && is.exhausted () && seconds_ >= 0.0))
+ throw invalid_value<C> (bits::duration<C> (), tmp);
+
+ pos = del + 1;
+ }
+ }
+
+ // Something did not match or appeared in the wrong order.
+ //
+ if (pos != size)
+ throw invalid_value<C> (bits::duration<C> (), tmp);
+ }
+
+ template <typename C>
+ duration duration_pimpl<C>::
+ post_duration ()
+ {
+ return duration (
+ negative_, years_, months_, days_, hours_, minutes_, seconds_);
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.hxx b/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.hxx
new file mode 100644
index 0000000..0fca037
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.hxx
@@ -0,0 +1,647 @@
+// file : xsd/cxx/parser/validating/xml-schema-pskel.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_HXX
+#define XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_HXX
+
+#include <string>
+#include <memory> // auto_ptr
+
+#include <xsd/cxx/parser/xml-schema.hxx>
+#include <xsd/cxx/parser/validating/parser.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ // anyType and anySimpleType. All events are routed to the
+ // _any_* callbacks.
+ //
+ template <typename C>
+ struct any_type_pskel: complex_content<C>
+ {
+ virtual bool
+ _start_element_impl (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>*);
+
+ virtual bool
+ _end_element_impl (const ro_string<C>&,
+ const ro_string<C>&);
+
+ virtual bool
+ _attribute_impl_phase_two (const ro_string<C>&,
+ const ro_string<C>&,
+ const ro_string<C>&);
+
+ virtual bool
+ _characters_impl (const ro_string<C>&);
+
+ virtual void
+ post_any_type () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct any_simple_type_pskel: simple_content<C>
+ {
+ virtual bool
+ _characters_impl (const ro_string<C>&);
+
+ virtual void
+ post_any_simple_type () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // Boolean.
+ //
+ template <typename C>
+ struct boolean_pskel: simple_content<C>
+ {
+ virtual bool
+ post_boolean () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // 8-bit
+ //
+ template <typename C>
+ struct byte_pskel: simple_content<C>
+ {
+ virtual signed char
+ post_byte () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct unsigned_byte_pskel: simple_content<C>
+ {
+ virtual unsigned char
+ post_unsigned_byte () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // 16-bit
+ //
+ template <typename C>
+ struct short_pskel: simple_content<C>
+ {
+ virtual short
+ post_short () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct unsigned_short_pskel: simple_content<C>
+ {
+ virtual unsigned short
+ post_unsigned_short () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // 32-bit
+ //
+ template <typename C>
+ struct int_pskel: simple_content<C>
+ {
+ virtual int
+ post_int () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct unsigned_int_pskel: simple_content<C>
+ {
+ virtual unsigned int
+ post_unsigned_int () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // 64-bit
+ //
+ template <typename C>
+ struct long_pskel: simple_content<C>
+ {
+ virtual long long
+ post_long () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct unsigned_long_pskel: simple_content<C>
+ {
+ virtual unsigned long long
+ post_unsigned_long () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // Arbitrary-length integers.
+ //
+ template <typename C>
+ struct integer_pskel: simple_content<C>
+ {
+ virtual long long
+ post_integer () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct negative_integer_pskel: simple_content<C>
+ {
+ virtual long long
+ post_negative_integer () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct non_positive_integer_pskel: simple_content<C>
+ {
+ virtual long long
+ post_non_positive_integer () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct positive_integer_pskel: simple_content<C>
+ {
+ virtual unsigned long long
+ post_positive_integer () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct non_negative_integer_pskel: simple_content<C>
+ {
+ virtual unsigned long long
+ post_non_negative_integer () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // Floats.
+ //
+ template <typename C>
+ struct float_pskel: simple_content<C>
+ {
+ virtual float
+ post_float () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct double_pskel: simple_content<C>
+ {
+ virtual double
+ post_double () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct decimal_pskel: simple_content<C>
+ {
+ virtual double
+ post_decimal () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+
+ // Strings.
+ //
+ template <typename C>
+ struct string_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_string () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct normalized_string_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_normalized_string () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct token_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_token () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct name_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_name () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct nmtoken_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_nmtoken () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct nmtokens_pskel: list_base<C>
+ {
+ virtual string_sequence<C>
+ post_nmtokens () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct ncname_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_ncname () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct id_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_id () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct idref_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_idref () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct idrefs_pskel: list_base<C>
+ {
+ virtual string_sequence<C>
+ post_idrefs () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ // Language.
+ //
+ template <typename C>
+ struct language_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_language () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ // URI.
+ //
+ template <typename C>
+ struct uri_pskel: simple_content<C>
+ {
+ virtual std::basic_string<C>
+ post_uri () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ // QName.
+ //
+ template <typename C>
+ struct qname_pskel: simple_content<C>
+ {
+ virtual qname<C>
+ post_qname () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ // Base64 and hex binaries.
+ //
+ template <typename C>
+ struct base64_binary_pskel: simple_content<C>
+ {
+ virtual std::auto_ptr<buffer>
+ post_base64_binary () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct hex_binary_pskel: simple_content<C>
+ {
+ virtual std::auto_ptr<buffer>
+ post_hex_binary () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ // Time and date types.
+ //
+ template <typename C>
+ struct gday_pskel: simple_content<C>
+ {
+ virtual gday
+ post_gday () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct gmonth_pskel: simple_content<C>
+ {
+ virtual gmonth
+ post_gmonth () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct gyear_pskel: simple_content<C>
+ {
+ virtual gyear
+ post_gyear () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct gmonth_day_pskel: simple_content<C>
+ {
+ virtual gmonth_day
+ post_gmonth_day () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct gyear_month_pskel: simple_content<C>
+ {
+ virtual gyear_month
+ post_gyear_month () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct date_pskel: simple_content<C>
+ {
+ virtual date
+ post_date () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct time_pskel: simple_content<C>
+ {
+ virtual time
+ post_time () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct date_time_pskel: simple_content<C>
+ {
+ virtual date_time
+ post_date_time () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+
+ template <typename C>
+ struct duration_pskel: simple_content<C>
+ {
+ virtual duration
+ post_duration () = 0;
+
+ static const C*
+ _static_type ();
+
+ virtual const C*
+ _dynamic_type () const;
+ };
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/parser/validating/xml-schema-pskel.txx>
+
+#endif // XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_HXX
+
+#include <xsd/cxx/parser/validating/xml-schema-pskel.ixx>
diff --git a/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.ixx b/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.ixx
new file mode 100644
index 0000000..7a9f5e5
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.ixx
@@ -0,0 +1,1249 @@
+// file : xsd/cxx/parser/validating/xml-schema-pskel.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#if defined(XSD_CXX_PARSER_USE_CHAR) || !defined(XSD_CXX_PARSER_USE_WCHAR)
+
+#ifndef XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_IXX_CHAR
+#define XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_IXX_CHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ template<>
+ inline const char* any_type_pskel<char>::
+ _static_type ()
+ {
+ return "anyType http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* any_type_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* any_simple_type_pskel<char>::
+ _static_type ()
+ {
+ return "anySimpleType http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* any_simple_type_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* boolean_pskel<char>::
+ _static_type ()
+ {
+ return "boolean http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* boolean_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* byte_pskel<char>::
+ _static_type ()
+ {
+ return "byte http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* byte_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* unsigned_byte_pskel<char>::
+ _static_type ()
+ {
+ return "unsignedByte http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* unsigned_byte_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* short_pskel<char>::
+ _static_type ()
+ {
+ return "short http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* short_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* unsigned_short_pskel<char>::
+ _static_type ()
+ {
+ return "unsignedShort http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* unsigned_short_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* int_pskel<char>::
+ _static_type ()
+ {
+ return "int http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* int_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* unsigned_int_pskel<char>::
+ _static_type ()
+ {
+ return "unsignedInt http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* unsigned_int_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* long_pskel<char>::
+ _static_type ()
+ {
+ return "long http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* long_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* unsigned_long_pskel<char>::
+ _static_type ()
+ {
+ return "unsignedLong http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* unsigned_long_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* integer_pskel<char>::
+ _static_type ()
+ {
+ return "integer http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* integer_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* negative_integer_pskel<char>::
+ _static_type ()
+ {
+ return "negativeInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* negative_integer_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* non_positive_integer_pskel<char>::
+ _static_type ()
+ {
+ return "nonPositiveInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* non_positive_integer_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* positive_integer_pskel<char>::
+ _static_type ()
+ {
+ return "positiveInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* positive_integer_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* non_negative_integer_pskel<char>::
+ _static_type ()
+ {
+ return "nonNegativeInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* non_negative_integer_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* float_pskel<char>::
+ _static_type ()
+ {
+ return "float http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* float_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* double_pskel<char>::
+ _static_type ()
+ {
+ return "double http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* double_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* decimal_pskel<char>::
+ _static_type ()
+ {
+ return "decimal http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* decimal_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* string_pskel<char>::
+ _static_type ()
+ {
+ return "string http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* string_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* normalized_string_pskel<char>::
+ _static_type ()
+ {
+ return "normalizedString http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* normalized_string_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* token_pskel<char>::
+ _static_type ()
+ {
+ return "token http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* token_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* name_pskel<char>::
+ _static_type ()
+ {
+ return "Name http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* name_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* nmtoken_pskel<char>::
+ _static_type ()
+ {
+ return "NMTOKEN http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* nmtoken_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* nmtokens_pskel<char>::
+ _static_type ()
+ {
+ return "NMTOKENS http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* nmtokens_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* ncname_pskel<char>::
+ _static_type ()
+ {
+ return "NCName http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* ncname_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* id_pskel<char>::
+ _static_type ()
+ {
+ return "ID http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* id_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* idref_pskel<char>::
+ _static_type ()
+ {
+ return "IDREF http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* idref_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* idrefs_pskel<char>::
+ _static_type ()
+ {
+ return "IDREFS http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* idrefs_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* language_pskel<char>::
+ _static_type ()
+ {
+ return "language http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* language_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* uri_pskel<char>::
+ _static_type ()
+ {
+ return "anyURI http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* uri_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* qname_pskel<char>::
+ _static_type ()
+ {
+ return "QName http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* qname_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* base64_binary_pskel<char>::
+ _static_type ()
+ {
+ return "base64Binary http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* base64_binary_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* hex_binary_pskel<char>::
+ _static_type ()
+ {
+ return "hexBinary http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* hex_binary_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* gday_pskel<char>::
+ _static_type ()
+ {
+ return "gDay http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* gday_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* gmonth_pskel<char>::
+ _static_type ()
+ {
+ return "gMonth http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* gmonth_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* gyear_pskel<char>::
+ _static_type ()
+ {
+ return "gYear http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* gyear_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* gmonth_day_pskel<char>::
+ _static_type ()
+ {
+ return "gMonthDay http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* gmonth_day_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* gyear_month_pskel<char>::
+ _static_type ()
+ {
+ return "gYearMonth http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* gyear_month_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* date_pskel<char>::
+ _static_type ()
+ {
+ return "date http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* date_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* time_pskel<char>::
+ _static_type ()
+ {
+ return "time http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* time_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* date_time_pskel<char>::
+ _static_type ()
+ {
+ return "dateTime http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* date_time_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const char* duration_pskel<char>::
+ _static_type ()
+ {
+ return "duration http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const char* duration_pskel<char>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_IXX_CHAR
+#endif // XSD_CXX_PARSER_USE_CHAR
+
+
+#if defined(XSD_CXX_PARSER_USE_WCHAR) || !defined(XSD_CXX_PARSER_USE_CHAR)
+
+#ifndef XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_IXX_WCHAR
+#define XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_IXX_WCHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ template<>
+ inline const wchar_t* any_type_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"anyType http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* any_type_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* any_simple_type_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"anySimpleType http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* any_simple_type_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* boolean_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"boolean http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* boolean_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* byte_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"byte http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* byte_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* unsigned_byte_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"unsignedByte http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* unsigned_byte_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* short_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"short http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* short_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* unsigned_short_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"unsignedShort http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* unsigned_short_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* int_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"int http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* int_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* unsigned_int_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"unsignedInt http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* unsigned_int_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* long_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"long http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* long_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* unsigned_long_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"unsignedLong http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* unsigned_long_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* integer_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"integer http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* integer_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* negative_integer_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"negativeInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* negative_integer_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* non_positive_integer_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"nonPositiveInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* non_positive_integer_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* positive_integer_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"positiveInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* positive_integer_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* non_negative_integer_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"nonNegativeInteger http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* non_negative_integer_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* float_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"float http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* float_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* double_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"double http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* double_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* decimal_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"decimal http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* decimal_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* string_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"string http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* string_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* normalized_string_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"normalizedString http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* normalized_string_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* token_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"token http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* token_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* name_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"Name http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* name_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* nmtoken_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"NMTOKEN http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* nmtoken_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* nmtokens_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"NMTOKENS http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* nmtokens_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* ncname_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"NCName http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* ncname_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* id_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"ID http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* id_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* idref_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"IDREF http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* idref_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* idrefs_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"IDREFS http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* idrefs_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* language_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"language http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* language_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* uri_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"anyURI http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* uri_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* qname_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"QName http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* qname_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* base64_binary_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"base64Binary http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* base64_binary_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* hex_binary_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"hexBinary http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* hex_binary_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* gday_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"gDay http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* gday_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* gmonth_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"gMonth http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* gmonth_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* gyear_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"gYear http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* gyear_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* gmonth_day_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"gMonthDay http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* gmonth_day_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* gyear_month_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"gYearMonth http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* gyear_month_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* date_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"date http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* date_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* time_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"time http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* time_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* date_time_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"dateTime http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* date_time_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+
+ template<>
+ inline const wchar_t* duration_pskel<wchar_t>::
+ _static_type ()
+ {
+ return L"duration http://www.w3.org/2001/XMLSchema";
+ }
+
+ template<>
+ inline const wchar_t* duration_pskel<wchar_t>::
+ _dynamic_type () const
+ {
+ return _static_type ();
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_PARSER_VALIDATING_XML_SCHEMA_PSKEL_IXX_WCHAR
+#endif // XSD_CXX_PARSER_USE_WCHAR
diff --git a/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.txx b/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.txx
new file mode 100644
index 0000000..c5fe5ef
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/validating/xml-schema-pskel.txx
@@ -0,0 +1,69 @@
+// file : xsd/cxx/parser/validating/xml-schema-pskel.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace validating
+ {
+ // any_type
+ //
+
+ template <typename C>
+ bool any_type_pskel<C>::
+ _start_element_impl (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>* type)
+ {
+ _start_any_element (ns, name, type);
+ this->complex_content<C>::context_.top ().any_ = true;
+ return true;
+ }
+
+ template <typename C>
+ bool any_type_pskel<C>::
+ _end_element_impl (const ro_string<C>& ns, const ro_string<C>& name)
+ {
+ this->complex_content<C>::context_.top ().any_ = false;
+ _end_any_element (ns, name);
+ return true;
+ }
+
+
+ template <typename C>
+ bool any_type_pskel<C>::
+ _attribute_impl_phase_two (const ro_string<C>& ns,
+ const ro_string<C>& name,
+ const ro_string<C>& value)
+ {
+ _any_attribute (ns, name, value);
+ return true;
+ }
+
+ template <typename C>
+ bool any_type_pskel<C>::
+ _characters_impl (const ro_string<C>& s)
+ {
+ _any_characters (s);
+ return true;
+ }
+
+ // any_simple_type
+ //
+
+ template <typename C>
+ bool any_simple_type_pskel<C>::
+ _characters_impl (const ro_string<C>& s)
+ {
+ _any_characters (s);
+ return true;
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/xerces/elements.hxx b/libxsd/xsd/cxx/parser/xerces/elements.hxx
new file mode 100644
index 0000000..9d79e61
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/xerces/elements.hxx
@@ -0,0 +1,462 @@
+// file : xsd/cxx/parser/xerces/elements.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_XERCES_ELEMENTS_HXX
+#define XSD_CXX_PARSER_XERCES_ELEMENTS_HXX
+
+#include <memory> // std::auto_ptr
+#include <string>
+#include <iosfwd>
+#include <vector>
+
+#include <xercesc/sax/Locator.hpp>
+#include <xercesc/sax/InputSource.hpp>
+#include <xercesc/sax2/SAX2XMLReader.hpp>
+#include <xercesc/sax2/DefaultHandler.hpp>
+
+#include <xsd/cxx/xml/elements.hxx>
+#include <xsd/cxx/xml/error-handler.hxx>
+
+#include <xsd/cxx/parser/exceptions.hxx>
+#include <xsd/cxx/parser/elements.hxx>
+#include <xsd/cxx/parser/document.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace xerces
+ {
+ //
+ //
+ struct flags
+ {
+ // Use the following flags to modify the default behavior
+ // of the parsing functions.
+ //
+
+ // Do not try to validate instance documents.
+ //
+ static const unsigned long dont_validate = 0x00000001;
+
+ // Do not initialize the Xerces-C++ runtime.
+ //
+ static const unsigned long dont_initialize = 0x00000002;
+
+ // Disable handling of subsequent imports for the same namespace
+ // in Xerces-C++ 3-series.
+ //
+ static const unsigned long no_multiple_imports = 0x00000004;
+
+ public:
+ flags (unsigned long x = 0)
+ : x_ (x)
+ {
+ }
+
+ operator unsigned long () const
+ {
+ return x_;
+ }
+
+ private:
+ unsigned long x_;
+ };
+
+
+ // Parsing properties. Refer to xsd/cxx/xml/elements.hxx for
+ // XML-related properties.
+ //
+ template <typename C>
+ class properties: public xml::properties<C>
+ {
+ };
+
+ //
+ //
+ template <typename C>
+ struct document: cxx::parser::document<C> // VC 7.1 likes it qualified
+ {
+ public:
+ document (parser_base<C>& root,
+ const C* root_element_name,
+ bool polymorphic = false);
+
+ document (parser_base<C>& root,
+ const std::basic_string<C>& root_element_name,
+ bool polymorphic = false);
+
+ document (parser_base<C>& root,
+ const C* root_element_namespace,
+ const C* root_element_name,
+ bool polymorphic = false);
+
+ document (parser_base<C>& root,
+ const std::basic_string<C>& root_element_namespace,
+ const std::basic_string<C>& root_element_name,
+ bool polymorphic = false);
+
+ protected:
+ explicit
+ document (bool polymorphic = false);
+
+ public:
+ // Parse URI or a local file. We have to overload it for const C*
+ // bacause xercesc::InputSource has an implicit constructor that
+ // takes const char*.
+ //
+ void
+ parse (const std::basic_string<C>& uri,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+ void
+ parse (const C* uri,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse URI or a local file with a user-provided error_handler
+ // object.
+ //
+ void
+ parse (const std::basic_string<C>& uri,
+ xml::error_handler<C>&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+ void
+ parse (const C* uri,
+ xml::error_handler<C>&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse URI or a local file with a user-provided ErrorHandler
+ // object. Note that you must initialize the Xerces-C++ runtime
+ // before calling these functions.
+ //
+ void
+ parse (const std::basic_string<C>& uri,
+ xercesc::ErrorHandler&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+ void
+ parse (const C* uri,
+ xercesc::ErrorHandler&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse URI or a local file using a user-provided SAX2XMLReader
+ // object. Note that you must initialize the Xerces-C++ runtime
+ // before calling these functions.
+ //
+ void
+ parse (const std::basic_string<C>& uri,
+ xercesc::SAX2XMLReader&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+ void
+ parse (const C* uri,
+ xercesc::SAX2XMLReader&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ public:
+ // System id is a "system" identifier of the resources (e.g.,
+ // URI or a full file path). Public id is a "public" identifier
+ // of the resource (e.g., an application-specific name or a
+ // relative file path). System id is used to resolve relative
+ // paths. In diagnostics messages system id is used if public
+ // id is not available. Otherwise public id is used.
+ //
+
+ // Parse std::istream.
+ //
+ void
+ parse (std::istream&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse std::istream with a user-provided error_handler object.
+ //
+ void
+ parse (std::istream&,
+ xml::error_handler<C>&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse std::istream with a user-provided ErrorHandler object.
+ // Note that you must initialize the Xerces-C++ runtime before
+ // calling this function.
+ //
+ void
+ parse (std::istream&,
+ xercesc::ErrorHandler&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse std::istream using a user-provided SAX2XMLReader object.
+ // Note that you must initialize the Xerces-C++ runtime before
+ // calling this function.
+ //
+ void
+ parse (std::istream&,
+ xercesc::SAX2XMLReader&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ public:
+ // Parse std::istream with a system id.
+ //
+ void
+ parse (std::istream&,
+ const std::basic_string<C>& system_id,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse std::istream with a system id and a user-provided
+ // error_handler object.
+ //
+ void
+ parse (std::istream&,
+ const std::basic_string<C>& system_id,
+ xml::error_handler<C>&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse std::istream with a system id and a user-provided
+ // ErrorHandler object. Note that you must initialize the
+ // Xerces-C++ runtime before calling this function.
+ //
+ void
+ parse (std::istream&,
+ const std::basic_string<C>& system_id,
+ xercesc::ErrorHandler&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse std::istream with a system id using a user-provided
+ // SAX2XMLReader object. Note that you must initialize the
+ // Xerces-C++ runtime before calling this function.
+ //
+ void
+ parse (std::istream&,
+ const std::basic_string<C>& system_id,
+ xercesc::SAX2XMLReader&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+
+ public:
+ // Parse std::istream with system and public ids.
+ //
+ void
+ parse (std::istream&,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse std::istream with system and public ids and a user-provided
+ // error_handler object.
+ //
+ void
+ parse (std::istream&,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id,
+ xml::error_handler<C>&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse std::istream with system and public ids and a user-provided
+ // ErrorHandler object. Note that you must initialize the Xerces-C++
+ // runtime before calling this function.
+ //
+ void
+ parse (std::istream&,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id,
+ xercesc::ErrorHandler&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse std::istream with system and public ids using a user-
+ // provided SAX2XMLReader object. Note that you must initialize
+ // the Xerces-C++ runtime before calling this function.
+ //
+ void
+ parse (std::istream&,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id,
+ xercesc::SAX2XMLReader&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ public:
+ // Parse InputSource. Note that you must initialize the Xerces-C++
+ // runtime before calling this function.
+ //
+ void
+ parse (const xercesc::InputSource&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse InputSource with a user-provided error_handler object.
+ // Note that you must initialize the Xerces-C++ runtime before
+ // calling this function.
+ //
+ void
+ parse (const xercesc::InputSource&,
+ xml::error_handler<C>&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse InputSource with a user-provided ErrorHandler object.
+ // Note that you must initialize the Xerces-C++ runtime before
+ // calling this function.
+ //
+ void
+ parse (const xercesc::InputSource&,
+ xercesc::ErrorHandler&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+
+ // Parse InputSource using a user-provided SAX2XMLReader object.
+ // Note that you must initialize the Xerces-C++ runtime before
+ // calling this function.
+ //
+ void
+ parse (const xercesc::InputSource&,
+ xercesc::SAX2XMLReader&,
+ flags = 0,
+ const properties<C>& = properties<C> ());
+
+ private:
+ void
+ parse (const std::basic_string<C>& uri,
+ xercesc::ErrorHandler&,
+ xercesc::SAX2XMLReader&,
+ flags,
+ const properties<C>&);
+
+ void
+ parse (const xercesc::InputSource&,
+ xercesc::ErrorHandler&,
+ xercesc::SAX2XMLReader&,
+ flags,
+ const properties<C>&);
+
+ private:
+ std::auto_ptr<xercesc::SAX2XMLReader>
+ create_sax_ (flags, const properties<C>&);
+
+ private:
+ bool polymorphic_;
+ };
+
+ //
+ //
+ template <typename C>
+ struct event_router: xercesc::DefaultHandler
+ {
+ event_router (cxx::parser::document<C>&, bool polymorphic);
+
+ // I know, some of those consts are stupid. But that's what
+ // Xerces folks put into their interfaces and VC 7.1 thinks
+ // there are different signatures if one strips this fluff off.
+ //
+ virtual void
+ setDocumentLocator (const xercesc::Locator* const);
+
+ virtual void
+ startElement (const XMLCh* const uri,
+ const XMLCh* const lname,
+ const XMLCh* const qname,
+ const xercesc::Attributes& attributes);
+
+ virtual void
+ endElement (const XMLCh* const uri,
+ const XMLCh* const lname,
+ const XMLCh* const qname);
+
+#if _XERCES_VERSION >= 30000
+ virtual void
+ characters (const XMLCh* const s, const XMLSize_t length);
+#else
+ virtual void
+ characters (const XMLCh* const s, const unsigned int length);
+#endif
+
+ virtual void
+ startPrefixMapping (const XMLCh* const prefix,
+ const XMLCh* const uri);
+
+ virtual void
+ endPrefixMapping (const XMLCh* const prefix);
+
+ private:
+ void
+ set_location (schema_exception<C>&);
+
+ private:
+ const xercesc::Locator* loc_;
+ cxx::parser::document<C>& consumer_;
+ bool polymorphic_;
+
+ // Last element name cache.
+ //
+ bool last_valid_;
+ std::basic_string<C> last_ns_;
+ std::basic_string<C> last_name_;
+
+ // Namespace-prefix mapping. Only maintained in the polymorphic
+ // case.
+ //
+ struct ns_decl
+ {
+ ns_decl (const std::basic_string<C>& p,
+ const std::basic_string<C>& n)
+ : prefix (p), ns (n)
+ {
+ }
+
+ std::basic_string<C> prefix;
+ std::basic_string<C> ns;
+ };
+
+ typedef std::vector<ns_decl> ns_decls;
+
+ ns_decls ns_decls_;
+ };
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/parser/xerces/elements.txx>
+
+#endif // XSD_CXX_PARSER_XERCES_ELEMENTS_HXX
diff --git a/libxsd/xsd/cxx/parser/xerces/elements.txx b/libxsd/xsd/cxx/parser/xerces/elements.txx
new file mode 100644
index 0000000..e09ffc5
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/xerces/elements.txx
@@ -0,0 +1,964 @@
+// file : xsd/cxx/parser/xerces/elements.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <istream>
+#include <cstddef> // std::size_t
+#include <cassert>
+
+#include <xercesc/sax/SAXParseException.hpp>
+#include <xercesc/sax2/Attributes.hpp>
+#include <xercesc/sax2/XMLReaderFactory.hpp>
+#include <xercesc/validators/schema/SchemaSymbols.hpp>
+#include <xercesc/util/XMLUni.hpp>
+
+#include <xsd/cxx/xml/string.hxx>
+#include <xsd/cxx/xml/sax/std-input-source.hxx>
+#include <xsd/cxx/xml/sax/bits/error-handler-proxy.hxx>
+#include <xsd/cxx/xml/bits/literals.hxx> // xml::bits::{xml_prefix, etc}
+
+#include <xsd/cxx/parser/error-handler.hxx>
+#include <xsd/cxx/parser/schema-exceptions.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ namespace xerces
+ {
+
+ // document
+ //
+
+ template <typename C>
+ document<C>::
+ document (parser_base<C>& parser,
+ const C* name,
+ bool polymorphic)
+ : cxx::parser::document<C> (parser, std::basic_string<C> (), name),
+ polymorphic_ (polymorphic)
+ {
+ }
+
+ template <typename C>
+ document<C>::
+ document (parser_base<C>& parser,
+ const std::basic_string<C>& name,
+ bool polymorphic)
+ : cxx::parser::document<C> (parser, std::basic_string<C> (), name),
+ polymorphic_ (polymorphic)
+ {
+ }
+
+ template <typename C>
+ document<C>::
+ document (parser_base<C>& parser,
+ const C* ns,
+ const C* name,
+ bool polymorphic)
+ : cxx::parser::document<C> (parser, ns, name),
+ polymorphic_ (polymorphic)
+ {
+ }
+
+ template <typename C>
+ document<C>::
+ document (parser_base<C>& parser,
+ const std::basic_string<C>& ns,
+ const std::basic_string<C>& name,
+ bool polymorphic)
+ : cxx::parser::document<C> (parser, ns, name),
+ polymorphic_ (polymorphic)
+ {
+ }
+
+ template <typename C>
+ document<C>::
+ document (bool polymorphic)
+ : polymorphic_ (polymorphic)
+ {
+ }
+
+ // parse (uri)
+ //
+ template <typename C>
+ void document<C>::
+ parse (const std::basic_string<C>& uri,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::auto_initializer init ((f & flags::dont_initialize) == 0);
+
+ error_handler<C> eh;
+ xml::sax::bits::error_handler_proxy<C> eh_proxy (eh);
+ std::auto_ptr<xercesc::SAX2XMLReader> sax (create_sax_ (f, p));
+
+ parse (uri, eh_proxy, *sax, f, p);
+
+ eh.throw_if_failed ();
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (const C* uri,
+ flags f,
+ const properties<C>& p)
+ {
+ parse (std::basic_string<C> (uri), f, p);
+ }
+
+ // error_handler
+ //
+
+ template <typename C>
+ void document<C>::
+ parse (const std::basic_string<C>& uri,
+ xml::error_handler<C>& eh,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::auto_initializer init ((f & flags::dont_initialize) == 0);
+
+ xml::sax::bits::error_handler_proxy<C> eh_proxy (eh);
+ std::auto_ptr<xercesc::SAX2XMLReader> sax (create_sax_ (f, p));
+
+ parse (uri, eh_proxy, *sax, f, p);
+
+ if (eh_proxy.failed ())
+ throw parsing<C> ();
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (const C* uri,
+ xml::error_handler<C>& eh,
+ flags f,
+ const properties<C>& p)
+ {
+ parse (std::basic_string<C> (uri), eh, f, p);
+ }
+
+ // ErrorHandler
+ //
+
+ template <typename C>
+ void document<C>::
+ parse (const std::basic_string<C>& uri,
+ xercesc::ErrorHandler& eh,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::sax::bits::error_handler_proxy<C> eh_proxy (eh);
+ std::auto_ptr<xercesc::SAX2XMLReader> sax (create_sax_ (f, p));
+
+ parse (uri, eh_proxy, *sax, f, p);
+
+ if (eh_proxy.failed ())
+ throw parsing<C> ();
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (const C* uri,
+ xercesc::ErrorHandler& eh,
+ flags f,
+ const properties<C>& p)
+ {
+ parse (std::basic_string<C> (uri), eh, f, p);
+ }
+
+ // SAX2XMLReader
+ //
+
+ template <typename C>
+ void document<C>::
+ parse (const std::basic_string<C>& uri,
+ xercesc::SAX2XMLReader& sax,
+ flags f,
+ const properties<C>& p)
+ {
+ // If there is no error handler, then fall back on the default
+ // implementation.
+ //
+ xercesc::ErrorHandler* eh (sax.getErrorHandler ());
+
+ if (eh)
+ {
+ xml::sax::bits::error_handler_proxy<C> eh_proxy (*eh);
+
+ parse (uri, eh_proxy, sax, f, p);
+
+ if (eh_proxy.failed ())
+ throw parsing<C> ();
+ }
+ else
+ {
+ error_handler<C> fallback_eh;
+ xml::sax::bits::error_handler_proxy<C> eh_proxy (fallback_eh);
+
+ parse (uri, eh_proxy, sax, f, p);
+
+ fallback_eh.throw_if_failed ();
+ }
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (const C* uri,
+ xercesc::SAX2XMLReader& sax,
+ flags f,
+ const properties<C>& p)
+ {
+ parse (std::basic_string<C> (uri), sax, f, p);
+ }
+
+ // parse (istream)
+ //
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::auto_initializer init ((f & flags::dont_initialize) == 0);
+
+ xml::sax::std_input_source isrc (is);
+
+ parse (isrc, f, p);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ xml::error_handler<C>& eh,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::auto_initializer init ((f & flags::dont_initialize) == 0);
+ xml::sax::std_input_source isrc (is);
+ parse (isrc, eh, f, p);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ xercesc::ErrorHandler& eh,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::sax::std_input_source isrc (is);
+ parse (isrc, eh, f, p);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ xercesc::SAX2XMLReader& sax,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::sax::std_input_source isrc (is);
+ parse (isrc, sax, f, p);
+ }
+
+
+ // parse (istream, system_id)
+ //
+
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ const std::basic_string<C>& system_id,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::auto_initializer init ((f & flags::dont_initialize) == 0);
+ xml::sax::std_input_source isrc (is, system_id);
+ parse (isrc, f, p);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ const std::basic_string<C>& system_id,
+ xml::error_handler<C>& eh,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::auto_initializer init ((f & flags::dont_initialize) == 0);
+ xml::sax::std_input_source isrc (is, system_id);
+ parse (isrc, eh, f, p);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ const std::basic_string<C>& system_id,
+ xercesc::ErrorHandler& eh,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::sax::std_input_source isrc (is, system_id);
+ parse (isrc, eh, f, p);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ const std::basic_string<C>& system_id,
+ xercesc::SAX2XMLReader& sax,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::sax::std_input_source isrc (is, system_id);
+ parse (isrc, sax, f, p);
+ }
+
+
+ // parse (istream, system_id, public_id)
+ //
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::auto_initializer init ((f & flags::dont_initialize) == 0);
+ xml::sax::std_input_source isrc (is, system_id, public_id);
+ parse (isrc, f, p);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id,
+ xml::error_handler<C>& eh,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::auto_initializer init ((f & flags::dont_initialize) == 0);
+ xml::sax::std_input_source isrc (is, system_id, public_id);
+ parse (isrc, eh, f, p);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id,
+ xercesc::ErrorHandler& eh,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::sax::std_input_source isrc (is, system_id, public_id);
+ parse (isrc, eh, f, p);
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (std::istream& is,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id,
+ xercesc::SAX2XMLReader& sax,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::sax::std_input_source isrc (is, system_id, public_id);
+ parse (isrc, sax, f, p);
+ }
+
+
+ // parse (InputSource)
+ //
+
+
+ template <typename C>
+ void document<C>::
+ parse (const xercesc::InputSource& is,
+ flags f,
+ const properties<C>& p)
+ {
+ error_handler<C> eh;
+ xml::sax::bits::error_handler_proxy<C> eh_proxy (eh);
+ std::auto_ptr<xercesc::SAX2XMLReader> sax (create_sax_ (f, p));
+
+ parse (is, eh_proxy, *sax, f, p);
+
+ eh.throw_if_failed ();
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (const xercesc::InputSource& is,
+ xml::error_handler<C>& eh,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::sax::bits::error_handler_proxy<C> eh_proxy (eh);
+ std::auto_ptr<xercesc::SAX2XMLReader> sax (create_sax_ (f, p));
+
+ parse (is, eh_proxy, *sax, f, p);
+
+ if (eh_proxy.failed ())
+ throw parsing<C> ();
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (const xercesc::InputSource& is,
+ xercesc::ErrorHandler& eh,
+ flags f,
+ const properties<C>& p)
+ {
+ xml::sax::bits::error_handler_proxy<C> eh_proxy (eh);
+ std::auto_ptr<xercesc::SAX2XMLReader> sax (create_sax_ (f, p));
+
+ parse (is, eh_proxy, *sax, f, p);
+
+ if (eh_proxy.failed ())
+ throw parsing<C> ();
+ }
+
+
+ template <typename C>
+ void document<C>::
+ parse (const xercesc::InputSource& is,
+ xercesc::SAX2XMLReader& sax,
+ flags f,
+ const properties<C>& p)
+ {
+ // If there is no error handler, then fall back on the default
+ // implementation.
+ //
+ xercesc::ErrorHandler* eh (sax.getErrorHandler ());
+
+ if (eh)
+ {
+ xml::sax::bits::error_handler_proxy<C> eh_proxy (*eh);
+
+ parse (is, eh_proxy, sax, f, p);
+
+ if (eh_proxy.failed ())
+ throw parsing<C> ();
+ }
+ else
+ {
+ error_handler<C> fallback_eh;
+ xml::sax::bits::error_handler_proxy<C> eh_proxy (fallback_eh);
+
+ parse (is, eh_proxy, sax, f, p);
+
+ fallback_eh.throw_if_failed ();
+ }
+ }
+
+ namespace Bits
+ {
+ struct ErrorHandlingController
+ {
+ ErrorHandlingController (xercesc::SAX2XMLReader& sax,
+ xercesc::ErrorHandler& eh)
+ : sax_ (sax), eh_ (sax_.getErrorHandler ())
+ {
+ sax_.setErrorHandler (&eh);
+ }
+
+ ~ErrorHandlingController ()
+ {
+ sax_.setErrorHandler (eh_);
+ }
+
+ private:
+ xercesc::SAX2XMLReader& sax_;
+ xercesc::ErrorHandler* eh_;
+ };
+
+ struct ContentHandlingController
+ {
+ ContentHandlingController (xercesc::SAX2XMLReader& sax,
+ xercesc::ContentHandler& ch)
+ : sax_ (sax), ch_ (sax_.getContentHandler ())
+ {
+ sax_.setContentHandler (&ch);
+ }
+
+ ~ContentHandlingController ()
+ {
+ sax_.setContentHandler (ch_);
+ }
+
+ private:
+ xercesc::SAX2XMLReader& sax_;
+ xercesc::ContentHandler* ch_;
+ };
+ };
+
+ template <typename C>
+ void document<C>::
+ parse (const std::basic_string<C>& uri,
+ xercesc::ErrorHandler& eh,
+ xercesc::SAX2XMLReader& sax,
+ flags,
+ const properties<C>&)
+ {
+ event_router<C> router (*this, polymorphic_);
+
+ Bits::ErrorHandlingController ehc (sax, eh);
+ Bits::ContentHandlingController chc (sax, router);
+
+ try
+ {
+ sax.parse (xml::string (uri).c_str ());
+ }
+ catch (const schema_exception<C>& e)
+ {
+ xml::string id (e.id ());
+
+ xercesc::SAXParseException se (
+ xml::string (e.message ()).c_str (),
+ id.c_str (),
+ id.c_str (),
+#if _XERCES_VERSION >= 30000
+ static_cast<XMLFileLoc> (e.line ()),
+ static_cast<XMLFileLoc> (e.column ())
+#else
+ static_cast<XMLSSize_t> (e.line ()),
+ static_cast<XMLSSize_t> (e.column ())
+#endif
+ );
+
+ eh.fatalError (se);
+ }
+ }
+
+ template <typename C>
+ void document<C>::
+ parse (const xercesc::InputSource& is,
+ xercesc::ErrorHandler& eh,
+ xercesc::SAX2XMLReader& sax,
+ flags,
+ const properties<C>&)
+ {
+ event_router<C> router (*this, polymorphic_);
+
+ Bits::ErrorHandlingController controller (sax, eh);
+ Bits::ContentHandlingController chc (sax, router);
+
+ try
+ {
+ sax.parse (is);
+ }
+ catch (const schema_exception<C>& e)
+ {
+ xml::string id (e.id ());
+
+ xercesc::SAXParseException se (
+ xml::string (e.message ()).c_str (),
+ id.c_str (),
+ id.c_str (),
+#if _XERCES_VERSION >= 30000
+ static_cast<XMLFileLoc> (e.line ()),
+ static_cast<XMLFileLoc> (e.column ())
+#else
+ static_cast<XMLSSize_t> (e.line ()),
+ static_cast<XMLSSize_t> (e.column ())
+#endif
+ );
+
+ eh.fatalError (se);
+ }
+ }
+
+
+ template <typename C>
+ std::auto_ptr<xercesc::SAX2XMLReader> document<C>::
+ create_sax_ (flags f, const properties<C>& p)
+ {
+ // HP aCC cannot handle using namespace xercesc;
+ //
+ using xercesc::SAX2XMLReader;
+ using xercesc::XMLReaderFactory;
+ using xercesc::XMLUni;
+
+ std::auto_ptr<SAX2XMLReader> sax (
+ XMLReaderFactory::createXMLReader ());
+
+ sax->setFeature (XMLUni::fgSAX2CoreNameSpaces, true);
+ sax->setFeature (XMLUni::fgSAX2CoreNameSpacePrefixes, true);
+ sax->setFeature (XMLUni::fgXercesValidationErrorAsFatal, true);
+
+ if (f & flags::dont_validate)
+ {
+ sax->setFeature (XMLUni::fgSAX2CoreValidation, false);
+ sax->setFeature (XMLUni::fgXercesSchema, false);
+ sax->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+ else
+ {
+ sax->setFeature (XMLUni::fgSAX2CoreValidation, true);
+ sax->setFeature (XMLUni::fgXercesSchema, true);
+
+#if _XERCES_VERSION >= 30000
+ if (!(f & flags::no_multiple_imports))
+ sax->setFeature (XMLUni::fgXercesHandleMultipleImports, true);
+#endif
+ // This feature checks the schema grammar for additional
+ // errors. We most likely do not need it when validating
+ // instances (assuming the schema is valid).
+ //
+ sax->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+
+ // Transfer properies if any.
+ //
+
+ if (!p.schema_location ().empty ())
+ {
+ xml::string sl (p.schema_location ());
+ const void* v (sl.c_str ());
+
+ sax->setProperty (
+ XMLUni::fgXercesSchemaExternalSchemaLocation,
+ const_cast<void*> (v));
+ }
+
+ if (!p.no_namespace_schema_location ().empty ())
+ {
+ xml::string sl (p.no_namespace_schema_location ());
+ const void* v (sl.c_str ());
+
+ sax->setProperty (
+ XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
+ const_cast<void*> (v));
+ }
+
+ return sax;
+ }
+
+ // event_router
+ //
+ template <typename C>
+ event_router<C>::
+ event_router (cxx::parser::document<C>& consumer, bool polymorphic)
+ : loc_ (0), consumer_ (consumer), polymorphic_ (polymorphic)
+ {
+ }
+
+ template <typename C>
+ void event_router<C>::
+ setDocumentLocator (const xercesc::Locator* const loc)
+ {
+ loc_ = loc;
+ }
+
+ template <typename C>
+ void event_router<C>::
+ startElement(const XMLCh* const uri,
+ const XMLCh* const lname,
+ const XMLCh* const /*qname*/,
+ const xercesc::Attributes& attributes)
+ {
+ typedef std::basic_string<C> string;
+
+ {
+ last_valid_ = true;
+ last_ns_ = xml::transcode<C> (uri);
+ last_name_ = xml::transcode<C> (lname);
+
+ // Without this explicit construction IBM XL C++ complains
+ // about ro_string's copy ctor being private even though the
+ // temporary has been eliminated. Note that we cannot
+ // eliminate ns, name and value since ro_string does not make
+ // a copy.
+ //
+ ro_string<C> ro_ns (last_ns_);
+ ro_string<C> ro_name (last_name_);
+
+ if (!polymorphic_)
+ {
+ try
+ {
+ consumer_.start_element (ro_ns, ro_name, 0);
+ }
+ catch (schema_exception<C>& e)
+ {
+ set_location (e);
+ throw;
+ }
+ }
+ else
+ {
+ // Search for the xsi:type attribute.
+ //
+ int i (attributes.getIndex (
+ xercesc::SchemaSymbols::fgURI_XSI,
+ xercesc::SchemaSymbols::fgXSI_TYPE));
+
+ if (i == -1)
+ {
+ try
+ {
+ consumer_.start_element (ro_ns, ro_name, 0);
+ }
+ catch (schema_exception<C>& e)
+ {
+ set_location (e);
+ throw;
+ }
+ }
+ else
+ {
+ try
+ {
+ // @@ Probably need proper QName validation.
+ //
+ // Get the qualified type name and try to resolve it.
+ //
+ string qn (xml::transcode<C> (attributes.getValue (i)));
+
+ ro_string<C> tp, tn;
+ typename string::size_type pos (qn.find (C (':')));
+
+ if (pos != string::npos)
+ {
+ tp.assign (qn.c_str (), pos);
+ tn.assign (qn.c_str () + pos + 1);
+
+ if (tp.empty ())
+ throw dynamic_type<C> (qn);
+ }
+ else
+ tn.assign (qn);
+
+ if (tn.empty ())
+ throw dynamic_type<C> (qn);
+
+ // Search our namespace declaration stack. Sun CC 5.7
+ // blows if we use const_reverse_iterator.
+ //
+ ro_string<C> tns;
+ for (typename ns_decls::reverse_iterator
+ it (ns_decls_.rbegin ()), e (ns_decls_.rend ());
+ it != e; ++it)
+ {
+ if (it->prefix == tp)
+ {
+ tns.assign (it->ns);
+ break;
+ }
+ }
+
+ if (!tp.empty () && tns.empty ())
+ {
+ // The 'xml' prefix requires special handling.
+ //
+ if (tp == xml::bits::xml_prefix<C> ())
+ tns.assign (xml::bits::xml_namespace<C> ());
+ else
+ throw dynamic_type<C> (qn);
+ }
+
+ // Construct the compound type id.
+ //
+ string id (tn.data (), tn.size ());
+
+ if (!tns.empty ())
+ {
+ id += C (' ');
+ id.append (tns.data (), tns.size ());
+ }
+
+ ro_string<C> ro_id (id);
+ consumer_.start_element (ro_ns, ro_name, &ro_id);
+ }
+ catch (schema_exception<C>& e)
+ {
+ set_location (e);
+ throw;
+ }
+ }
+ }
+ }
+
+#if _XERCES_VERSION >= 30000
+ for (XMLSize_t i (0), end (attributes.getLength()); i < end; ++i)
+#else
+ for (unsigned int i (0), end (attributes.getLength()); i < end; ++i)
+#endif
+ {
+ string ns (xml::transcode<C> (attributes.getURI (i)));
+ string name (xml::transcode<C> (attributes.getLocalName (i)));
+ string value (xml::transcode<C> (attributes.getValue (i)));
+
+ // Without this explicit construction IBM XL C++ complains
+ // about ro_string's copy ctor being private even though the
+ // temporary has been eliminated. Note that we cannot
+ // eliminate ns, name and value since ro_string does not make
+ // a copy.
+ //
+ ro_string<C> ro_ns (ns);
+ ro_string<C> ro_name (name);
+ ro_string<C> ro_value (value);
+
+ try
+ {
+ consumer_.attribute (ro_ns, ro_name, ro_value);
+ }
+ catch (schema_exception<C>& e)
+ {
+ set_location (e);
+ throw;
+ }
+ }
+ }
+
+ template <typename C>
+ void event_router<C>::
+ endElement(const XMLCh* const uri,
+ const XMLCh* const lname,
+ const XMLCh* const /*qname*/)
+ {
+ typedef std::basic_string<C> string;
+
+ try
+ {
+ // Without this explicit construction IBM XL C++ complains
+ // about ro_string's copy ctor being private even though the
+ // temporary has been eliminated. Note that we cannot
+ // eliminate ns, name and value since ro_string does not make
+ // a copy.
+ //
+ if (last_valid_)
+ {
+ last_valid_ = false;
+ ro_string<C> ro_ns (last_ns_);
+ ro_string<C> ro_name (last_name_);
+
+ consumer_.end_element (ro_ns, ro_name);
+ }
+ else
+ {
+ string ns (xml::transcode<C> (uri));
+ string name (xml::transcode<C> (lname));
+
+ ro_string<C> ro_ns (ns);
+ ro_string<C> ro_name (name);
+
+ consumer_.end_element (ro_ns, ro_name);
+ }
+ }
+ catch (schema_exception<C>& e)
+ {
+ set_location (e);
+ throw;
+ }
+ }
+
+ template <typename C>
+ void event_router<C>::
+#if _XERCES_VERSION >= 30000
+ characters (const XMLCh* const s, const XMLSize_t n)
+#else
+ characters (const XMLCh* const s, const unsigned int n)
+#endif
+ {
+ typedef std::basic_string<C> string;
+
+ if (n != 0)
+ {
+ string str (xml::transcode<C> (s, n));
+
+ // Without this explicit construction IBM XL C++ complains
+ // about ro_string's copy ctor being private even though the
+ // temporary has been eliminated. Note that we cannot
+ // eliminate str since ro_string does not make a copy.
+ //
+ ro_string<C> ro_str (str);
+
+ try
+ {
+ consumer_.characters (ro_str);
+ }
+ catch (schema_exception<C>& e)
+ {
+ set_location (e);
+ throw;
+ }
+ }
+ }
+
+ template <typename C>
+ void event_router<C>::
+ startPrefixMapping (const XMLCh* const prefix,
+ const XMLCh* const uri)
+ {
+ if (polymorphic_)
+ {
+ typedef std::basic_string<C> string;
+
+ string p (xml::transcode<C> (prefix));
+ string ns (xml::transcode<C> (uri));
+
+ ns_decls_.push_back (ns_decl (p, ns));
+ }
+ }
+
+ template <typename C>
+ void event_router<C>::
+ endPrefixMapping (const XMLCh* const prefix)
+ {
+ if (polymorphic_)
+ {
+ typedef std::basic_string<C> string;
+
+ string p (xml::transcode<C> (prefix));
+
+ // Here we assume the prefixes are removed in the reverse
+ // order of them being added. This appears to how every
+ // sensible implementation works.
+ //
+ assert (ns_decls_.back ().prefix == p);
+
+ ns_decls_.pop_back ();
+ }
+ }
+
+ template <typename C>
+ void event_router<C>::
+ set_location (schema_exception<C>& e)
+ {
+ if (loc_ != 0)
+ {
+ const XMLCh* id (loc_->getPublicId ());
+
+ if (id == 0)
+ id = loc_->getSystemId ();
+
+ if (id != 0)
+ e.id (xml::transcode<C> (id));
+
+#if _XERCES_VERSION >= 30000
+ e.line (static_cast<unsigned long> (loc_->getLineNumber ()));
+ e.column (static_cast<unsigned long> (loc_->getColumnNumber ()));
+#else
+ XMLSSize_t l (loc_->getLineNumber ());
+ XMLSSize_t c (loc_->getColumnNumber ());
+
+ e.line (l == -1 ? 0 : static_cast<unsigned long> (l));
+ e.column (c == -1 ? 0: static_cast<unsigned long> (c));
+#endif
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/xml-schema.hxx b/libxsd/xsd/cxx/parser/xml-schema.hxx
new file mode 100644
index 0000000..b6f9a1b
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/xml-schema.hxx
@@ -0,0 +1,572 @@
+// file : xsd/cxx/parser/xml-schema.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_PARSER_XML_SCHEMA_HXX
+#define XSD_CXX_PARSER_XML_SCHEMA_HXX
+
+#include <string>
+#include <vector>
+#include <cstddef> // std::size_t
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // String sequence. Used for the NMTOKENS and IDREFS types.
+ //
+ template <typename C>
+ class string_sequence: public std::vector<std::basic_string<C> >
+ {
+ public:
+ typedef std::basic_string<C> value_type;
+ typedef std::vector<value_type> base;
+ typedef typename base::size_type size_type;
+
+ string_sequence ();
+
+ explicit
+ string_sequence (size_type n, const value_type& x = value_type ());
+
+ template <typename I>
+ string_sequence (const I& begin, const I& end);
+ };
+
+ template <typename C>
+ bool
+ operator== (const string_sequence<C>&, const string_sequence<C>&);
+
+ template <typename C>
+ bool
+ operator!= (const string_sequence<C>&, const string_sequence<C>&);
+
+
+ // QName
+ //
+ template <typename C>
+ class qname
+ {
+ public:
+ explicit
+ qname (const std::basic_string<C>& name);
+
+ qname (const std::basic_string<C>& prefix,
+ const std::basic_string<C>& name);
+
+ void
+ swap (qname&);
+
+ const std::basic_string<C>&
+ prefix () const;
+
+ std::basic_string<C>&
+ prefix ();
+
+ void
+ prefix (const std::basic_string<C>&);
+
+ const std::basic_string<C>&
+ name () const;
+
+ std::basic_string<C>&
+ name ();
+
+ void
+ name (const std::basic_string<C>&);
+
+ private:
+ std::basic_string<C> prefix_;
+ std::basic_string<C> name_;
+ };
+
+ template <typename C>
+ bool
+ operator== (const qname<C>&, const qname<C>&);
+
+ template <typename C>
+ bool
+ operator!= (const qname<C>&, const qname<C>&);
+
+
+ // Binary buffer. Used for the base64Binary and hexBinary types.
+ //
+ class buffer
+ {
+ public:
+ typedef std::size_t size_t;
+
+ class bounds {}; // Out of bounds exception.
+
+ public:
+ ~buffer ();
+
+ explicit
+ buffer (size_t size = 0);
+ buffer (size_t size, size_t capacity);
+ buffer (const void* data, size_t size);
+ buffer (const void* data, size_t size, size_t capacity);
+
+ // If the assume_ownership argument is true, the buffer will
+ // assume the ownership of the data and will release the memory
+ // by calling operator delete ().
+ //
+ buffer (void* data,
+ size_t size,
+ size_t capacity,
+ bool assume_ownership);
+
+ buffer (const buffer&);
+
+ public:
+ buffer&
+ operator= (const buffer&);
+
+ public:
+ size_t
+ capacity () const;
+
+ // Returns true if the underlying buffer has moved.
+ //
+ bool
+ capacity (size_t);
+
+ public:
+ size_t
+ size () const;
+
+ // Returns true if the underlying buffer has moved.
+ //
+ bool
+ size (size_t);
+
+ public:
+ const char*
+ data () const;
+
+ char*
+ data ();
+
+ const char*
+ begin () const;
+
+ char*
+ begin ();
+
+ const char*
+ end () const;
+
+ char*
+ end ();
+
+ public:
+ void
+ swap (buffer&);
+
+ private:
+ bool
+ capacity (size_t capacity, bool copy);
+
+ private:
+ char* data_;
+ size_t size_;
+ size_t capacity_;
+ };
+
+ bool
+ operator== (const buffer&, const buffer&);
+
+ bool
+ operator!= (const buffer&, const buffer&);
+
+
+ // Time and date types.
+ //
+
+ class time_zone
+ {
+ public:
+ time_zone ();
+ time_zone (short hours, short minutes);
+
+ // Returns true if time zone is specified.
+ //
+ bool
+ zone_present () const;
+
+ // Resets the time zone to the 'not specified' state.
+ //
+ void
+ zone_reset ();
+
+ short
+ zone_hours () const;
+
+ void
+ zone_hours (short);
+
+ short
+ zone_minutes () const;
+
+ void
+ zone_minutes (short);
+
+ private:
+ bool present_;
+ short hours_;
+ short minutes_;
+ };
+
+ bool
+ operator== (const time_zone&, const time_zone&);
+
+ bool
+ operator!= (const time_zone&, const time_zone&);
+
+
+ class gday: public time_zone
+ {
+ public:
+ explicit
+ gday (unsigned short day);
+ gday (unsigned short day, short zone_hours, short zone_minutes);
+
+ unsigned short
+ day () const;
+
+ void
+ day (unsigned short);
+
+ private:
+ unsigned short day_;
+ };
+
+ bool
+ operator== (const gday&, const gday&);
+
+ bool
+ operator!= (const gday&, const gday&);
+
+
+ class gmonth: public time_zone
+ {
+ public:
+ explicit
+ gmonth (unsigned short month);
+ gmonth (unsigned short month, short zone_hours, short zone_minutes);
+
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+
+ private:
+ unsigned short month_;
+ };
+
+ bool
+ operator== (const gmonth&, const gmonth&);
+
+ bool
+ operator!= (const gmonth&, const gmonth&);
+
+
+ class gyear: public time_zone
+ {
+ public:
+ explicit
+ gyear (int year);
+ gyear (int year, short zone_hours, short zone_minutes);
+
+ int
+ year () const;
+
+ void
+ year (int);
+
+ private:
+ int year_;
+ };
+
+ bool
+ operator== (const gyear&, const gyear&);
+
+ bool
+ operator!= (const gyear&, const gyear&);
+
+
+ class gmonth_day: public time_zone
+ {
+ public:
+ gmonth_day (unsigned short month, unsigned short day);
+ gmonth_day (unsigned short month, unsigned short day,
+ short zone_hours, short zone_minutes);
+
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+
+ unsigned short
+ day () const;
+
+ void
+ day (unsigned short);
+
+ private:
+ unsigned short month_;
+ unsigned short day_;
+ };
+
+ bool
+ operator== (const gmonth_day&, const gmonth_day&);
+
+ bool
+ operator!= (const gmonth_day&, const gmonth_day&);
+
+
+ class gyear_month: public time_zone
+ {
+ public:
+ gyear_month (int year, unsigned short month);
+ gyear_month (int year, unsigned short month,
+ short zone_hours, short zone_minutes);
+
+ int
+ year () const;
+
+ void
+ year (int);
+
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+
+ private:
+ int year_;
+ unsigned short month_;
+ };
+
+ bool
+ operator== (const gyear_month&, const gyear_month&);
+
+ bool
+ operator!= (const gyear_month&, const gyear_month&);
+
+
+ class date: public time_zone
+ {
+ public:
+ date (int year, unsigned short month, unsigned short day);
+ date (int year, unsigned short month, unsigned short day,
+ short zone_hours, short zone_minutes);
+
+ int
+ year () const;
+
+ void
+ year (int);
+
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+
+ unsigned short
+ day () const;
+
+ void
+ day (unsigned short);
+
+ private:
+ int year_;
+ unsigned short month_;
+ unsigned short day_;
+ };
+
+ bool
+ operator== (const date&, const date&);
+
+ bool
+ operator!= (const date&, const date&);
+
+
+ class time: public time_zone
+ {
+ public:
+ time (unsigned short hours, unsigned short minutes, double seconds);
+ time (unsigned short hours, unsigned short minutes, double seconds,
+ short zone_hours, short zone_minutes);
+
+ unsigned short
+ hours () const;
+
+ void
+ hours (unsigned short);
+
+ unsigned short
+ minutes () const;
+
+ void
+ minutes (unsigned short);
+
+ double
+ seconds () const;
+
+ void
+ seconds (double);
+
+ private:
+ unsigned short hours_;
+ unsigned short minutes_;
+ double seconds_;
+ };
+
+ bool
+ operator== (const time&, const time&);
+
+ bool
+ operator!= (const time&, const time&);
+
+
+ class date_time: public time_zone
+ {
+ public:
+ date_time (int year, unsigned short month, unsigned short day,
+ unsigned short hours, unsigned short minutes, double seconds);
+
+ date_time (int year, unsigned short month, unsigned short day,
+ unsigned short hours, unsigned short minutes, double seconds,
+ short zone_hours, short zone_minutes);
+
+ int
+ year () const;
+
+ void
+ year (int);
+
+ unsigned short
+ month () const;
+
+ void
+ month (unsigned short);
+
+ unsigned short
+ day () const;
+
+ void
+ day (unsigned short);
+
+ unsigned short
+ hours () const;
+
+ void
+ hours (unsigned short);
+
+ unsigned short
+ minutes () const;
+
+ void
+ minutes (unsigned short);
+
+ double
+ seconds () const;
+
+ void
+ seconds (double);
+
+ private:
+ int year_;
+ unsigned short month_;
+ unsigned short day_;
+ unsigned short hours_;
+ unsigned short minutes_;
+ double seconds_;
+ };
+
+ bool
+ operator== (const date_time&, const date_time&);
+
+ bool
+ operator!= (const date_time&, const date_time&);
+
+
+ class duration
+ {
+ public:
+ duration (bool negative,
+ unsigned int years, unsigned int months, unsigned int days,
+ unsigned int hours, unsigned int minutes, double seconds);
+
+ bool
+ negative () const;
+
+ void
+ negative (bool);
+
+ unsigned int
+ years () const;
+
+ void
+ years (unsigned int);
+
+ unsigned int
+ months () const;
+
+ void
+ months (unsigned int);
+
+ unsigned int
+ days () const;
+
+ void
+ days (unsigned int);
+
+ unsigned int
+ hours () const;
+
+ void
+ hours (unsigned int);
+
+ unsigned int
+ minutes () const;
+
+ void
+ minutes (unsigned int);
+
+ double
+ seconds () const;
+
+ void
+ seconds (double);
+
+ private:
+ bool negative_;
+ unsigned int years_;
+ unsigned int months_;
+ unsigned int days_;
+ unsigned int hours_;
+ unsigned int minutes_;
+ double seconds_;
+ };
+
+ bool
+ operator== (const duration&, const duration&);
+
+ bool
+ operator!= (const duration&, const duration&);
+ }
+ }
+}
+
+#include <xsd/cxx/parser/xml-schema.ixx>
+#include <xsd/cxx/parser/xml-schema.txx>
+
+#endif // XSD_CXX_PARSER_XML_SCHEMA_HXX
diff --git a/libxsd/xsd/cxx/parser/xml-schema.ixx b/libxsd/xsd/cxx/parser/xml-schema.ixx
new file mode 100644
index 0000000..5a0922b
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/xml-schema.ixx
@@ -0,0 +1,1022 @@
+// file : xsd/cxx/parser/xml-schema.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <new> // operator new/delete
+#include <cstring> // std::memcpy, std::memcmp
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // string_sequence
+ //
+ template <typename C>
+ string_sequence<C>::
+ string_sequence ()
+ {
+ }
+
+ template <typename C>
+ string_sequence<C>::
+ string_sequence (size_type n, const value_type& x)
+ : base (n, x)
+ {
+ }
+
+ template <typename C>
+ template <typename I>
+ string_sequence<C>::
+ string_sequence (const I& begin, const I& end)
+ : base (begin, end)
+ {
+ }
+
+ template <typename C>
+ inline bool
+ operator!= (const string_sequence<C>& a, const string_sequence<C>& b)
+ {
+ return !(a == b);
+ }
+
+ // qname
+ //
+ template <typename C>
+ inline qname<C>::
+ qname (const std::basic_string<C>& name)
+ : name_ (name)
+ {
+ }
+
+ template <typename C>
+ inline qname<C>::
+ qname (const std::basic_string<C>& prefix,
+ const std::basic_string<C>& name)
+ : prefix_ (prefix), name_ (name)
+ {
+ }
+
+ template <typename C>
+ void qname<C>::
+ swap (qname<C>& x)
+ {
+ prefix_.swap (x.prefix_);
+ name_.swap (x.name_);
+ }
+
+ template <typename C>
+ inline const std::basic_string<C>& qname<C>::
+ prefix () const
+ {
+ return prefix_;
+ }
+
+ template <typename C>
+ inline std::basic_string<C>& qname<C>::
+ prefix ()
+ {
+ return prefix_;
+ }
+
+ template <typename C>
+ inline void qname<C>::
+ prefix (const std::basic_string<C>& prefix)
+ {
+ prefix_ = prefix;
+ }
+
+ template <typename C>
+ inline const std::basic_string<C>& qname<C>::
+ name () const
+ {
+ return name_;
+ }
+
+ template <typename C>
+ inline std::basic_string<C>& qname<C>::
+ name ()
+ {
+ return name_;
+ }
+
+ template <typename C>
+ inline void qname<C>::
+ name (const std::basic_string<C>& name)
+ {
+ name_ = name;
+ }
+
+ template <typename C>
+ inline bool
+ operator== (const qname<C>& a, const qname<C>& b)
+ {
+ return a.prefix () == b.prefix () && a.name () == b.name ();
+ }
+
+ template <typename C>
+ inline bool
+ operator!= (const qname<C>& a, const qname<C>& b)
+ {
+ return !(a == b);
+ }
+
+ // buffer
+ //
+ inline buffer::
+ ~buffer ()
+ {
+ if (data_)
+ operator delete (data_);
+ }
+
+ inline buffer::
+ buffer (size_t size)
+ : data_ (0), size_ (0), capacity_ (0)
+ {
+ capacity (size);
+ size_ = size;
+ }
+
+ inline buffer::
+ buffer (size_t size, size_t cap)
+ : data_ (0), size_ (0), capacity_ (0)
+ {
+ if (size > cap)
+ throw bounds ();
+
+ capacity (cap);
+ size_ = size;
+ }
+
+ inline buffer::
+ buffer (const void* data, size_t size)
+ : data_ (0), size_ (0), capacity_ (0)
+ {
+ capacity (size);
+ size_ = size;
+
+ if (size_)
+ std::memcpy (data_, data, size_);
+ }
+
+ inline buffer::
+ buffer (const void* data, size_t size, size_t cap)
+ : data_ (0), size_ (0), capacity_ (0)
+ {
+ if (size > cap)
+ throw bounds ();
+
+ capacity (cap);
+ size_ = size;
+
+ if (size_)
+ std::memcpy (data_, data, size_);
+ }
+
+ inline buffer::
+ buffer (void* data, size_t size, size_t cap, bool own)
+ : data_ (0), size_ (0), capacity_ (0)
+ {
+ if (size > cap)
+ throw bounds ();
+
+ if (own)
+ {
+ data_ = reinterpret_cast<char*> (data);
+ size_ = size;
+ capacity_ = cap;
+ }
+ else
+ {
+ capacity (cap);
+ size_ = size;
+
+ if (size_)
+ std::memcpy (data_, data, size_);
+ }
+ }
+
+ inline buffer::
+ buffer (const buffer& other)
+ : data_ (0), size_ (0), capacity_ (0)
+ {
+ capacity (other.capacity_);
+ size_ = other.size_;
+
+ if (size_)
+ std::memcpy (data_, other.data_, size_);
+ }
+
+ inline buffer& buffer::
+ operator= (const buffer& other)
+ {
+ if (this != &other)
+ {
+ capacity (other.capacity_, false);
+ size_ = other.size_;
+
+ if (size_)
+ std::memcpy (data_, other.data_, size_);
+ }
+
+ return *this;
+ }
+
+ inline size_t buffer::
+ capacity () const
+ {
+ return capacity_;
+ }
+
+ inline bool buffer::
+ capacity (size_t cap)
+ {
+ return capacity (cap, true);
+ }
+
+ inline size_t buffer::
+ size () const
+ {
+ return size_;
+ }
+
+ inline bool buffer::
+ size (size_t size)
+ {
+ bool r (false);
+
+ if (size > capacity_)
+ r = capacity (size);
+
+ size_ = size;
+
+ return r;
+ }
+
+ inline const char* buffer::
+ data () const
+ {
+ return data_;
+ }
+
+ inline char* buffer::
+ data ()
+ {
+ return data_;
+ }
+
+ inline const char* buffer::
+ begin () const
+ {
+ return data_;
+ }
+
+ inline char* buffer::
+ begin ()
+ {
+ return data_;
+ }
+
+ inline const char* buffer::
+ end () const
+ {
+ return data_ + size_;
+ }
+
+ inline char* buffer::
+ end ()
+ {
+ return data_ + size_;
+ }
+
+ inline void buffer::
+ swap (buffer& other)
+ {
+ char* tmp_data (data_);
+ size_t tmp_size (size_);
+ size_t tmp_capacity (capacity_);
+
+ data_ = other.data_;
+ size_ = other.size_;
+ capacity_ = other.capacity_;
+
+ other.data_ = tmp_data;
+ other.size_ = tmp_size;
+ other.capacity_ = tmp_capacity;
+ }
+
+ inline bool buffer::
+ capacity (size_t capacity, bool copy)
+ {
+ if (size_ > capacity)
+ throw bounds ();
+
+ if (capacity <= capacity_)
+ {
+ return false; // Do nothing if shrinking is requested.
+ }
+ else
+ {
+ char* data (reinterpret_cast<char*> (operator new (capacity)));
+
+ if (copy && size_ > 0)
+ std::memcpy (data, data_, size_);
+
+ if (data_)
+ operator delete (data_);
+
+ data_ = data;
+ capacity_ = capacity;
+
+ return true;
+ }
+ }
+
+ inline bool
+ operator== (const buffer& a, const buffer& b)
+ {
+ return a.size () == b.size () &&
+ std::memcmp (a.data (), b.data (), a.size ()) == 0;
+ }
+
+ inline bool
+ operator!= (const buffer& a, const buffer& b)
+ {
+ return !(a == b);
+ }
+
+ // time_zone
+ //
+ inline time_zone::
+ time_zone ()
+ : present_ (false)
+ {
+ }
+
+ inline time_zone::
+ time_zone (short h, short m)
+ : present_ (true), hours_ (h), minutes_ (m)
+ {
+ }
+
+ inline bool time_zone::
+ zone_present () const
+ {
+ return present_;
+ }
+
+ inline void time_zone::
+ zone_reset ()
+ {
+ present_ = false;
+ }
+
+ inline short time_zone::
+ zone_hours () const
+ {
+ return hours_;
+ }
+
+ inline void time_zone::
+ zone_hours (short h)
+ {
+ hours_ = h;
+ present_ = true;
+ }
+
+ inline short time_zone::
+ zone_minutes () const
+ {
+ return minutes_;
+ }
+
+ inline void time_zone::
+ zone_minutes (short m)
+ {
+ minutes_ = m;
+ present_ = true;
+ }
+
+ inline bool
+ operator== (const time_zone& x, const time_zone& y)
+ {
+ return x.zone_present ()
+ ? y.zone_present () &&
+ x.zone_hours () == y.zone_hours () &&
+ x.zone_minutes () == y.zone_minutes ()
+ : !y.zone_present ();
+ }
+
+ inline bool
+ operator!= (const time_zone& x, const time_zone& y)
+ {
+ return !(x == y);
+ }
+
+ // gday
+ //
+ inline gday::
+ gday (unsigned short day)
+ : day_ (day)
+ {
+ }
+
+ inline gday::
+ gday (unsigned short day, short zh, short zm)
+ : time_zone (zh, zm), day_ (day)
+ {
+ }
+
+ inline unsigned short gday::
+ day () const
+ {
+ return day_;
+ }
+
+ inline void gday::
+ day (unsigned short day)
+ {
+ day_ = day;
+ }
+
+ inline bool
+ operator== (const gday& a, const gday& b)
+ {
+ const time_zone& az = a;
+ const time_zone& bz = b;
+
+ return a.day () == b.day () && az == bz;
+ }
+
+ inline bool
+ operator!= (const gday& a, const gday& b)
+ {
+ return !(a == b);
+ }
+
+ // gmonth
+ //
+ inline gmonth::
+ gmonth (unsigned short month)
+ : month_ (month)
+ {
+ }
+
+ inline gmonth::
+ gmonth (unsigned short month, short zh, short zm)
+ : time_zone (zh, zm), month_ (month)
+ {
+ }
+
+ inline unsigned short gmonth::
+ month () const
+ {
+ return month_;
+ }
+
+ inline void gmonth::
+ month (unsigned short month)
+ {
+ month_ = month;
+ }
+
+ inline bool
+ operator== (const gmonth& a, const gmonth& b)
+ {
+ const time_zone& az = a;
+ const time_zone& bz = b;
+
+ return a.month () == b.month () && az == bz;
+ }
+
+ inline bool
+ operator!= (const gmonth& a, const gmonth& b)
+ {
+ return !(a == b);
+ }
+
+ // gyear
+ //
+ inline gyear::
+ gyear (int year)
+ : year_ (year)
+ {
+ }
+
+ inline gyear::
+ gyear (int year, short zh, short zm)
+ : time_zone (zh, zm), year_ (year)
+ {
+ }
+
+ inline int gyear::
+ year () const
+ {
+ return year_;
+ }
+
+ inline void gyear::
+ year (int year)
+ {
+ year_ = year;
+ }
+
+ inline bool
+ operator== (const gyear& a, const gyear& b)
+ {
+ const time_zone& az = a;
+ const time_zone& bz = b;
+
+ return a.year () == b.year () && az == bz;
+ }
+
+ inline bool
+ operator!= (const gyear& a, const gyear& b)
+ {
+ return !(a == b);
+ }
+
+ // gmonth_day
+ //
+ inline gmonth_day::
+ gmonth_day (unsigned short month, unsigned short day)
+ : month_ (month), day_ (day)
+ {
+ }
+
+ inline gmonth_day::
+ gmonth_day (unsigned short month,
+ unsigned short day,
+ short zh, short zm)
+ : time_zone (zh, zm), month_ (month), day_ (day)
+ {
+ }
+
+ inline unsigned short gmonth_day::
+ month () const
+ {
+ return month_;
+ }
+
+ inline void gmonth_day::
+ month (unsigned short month)
+ {
+ month_ = month;
+ }
+
+ inline unsigned short gmonth_day::
+ day () const
+ {
+ return day_;
+ }
+
+ inline void gmonth_day::
+ day (unsigned short day)
+ {
+ day_ = day;
+ }
+
+ inline bool
+ operator== (const gmonth_day& a, const gmonth_day& b)
+ {
+ const time_zone& az = a;
+ const time_zone& bz = b;
+
+ return a.month () == b.month () &&
+ a.day () == b.day () &&
+ az == bz;
+ }
+
+ inline bool
+ operator!= (const gmonth_day& a, const gmonth_day& b)
+ {
+ return !(a == b);
+ }
+
+ // gyear_month
+ //
+ inline gyear_month::
+ gyear_month (int year, unsigned short month)
+ : year_ (year), month_ (month)
+ {
+ }
+
+ inline gyear_month::
+ gyear_month (int year, unsigned short month,
+ short zh, short zm)
+ : time_zone (zh, zm), year_ (year), month_ (month)
+ {
+ }
+
+ inline int gyear_month::
+ year () const
+ {
+ return year_;
+ }
+
+ inline void gyear_month::
+ year (int year)
+ {
+ year_ = year;
+ }
+
+ inline unsigned short gyear_month::
+ month () const
+ {
+ return month_;
+ }
+
+ inline void gyear_month::
+ month (unsigned short month)
+ {
+ month_ = month;
+ }
+
+ inline bool
+ operator== (const gyear_month& a, const gyear_month& b)
+ {
+ const time_zone& az = a;
+ const time_zone& bz = b;
+
+ return a.year () == b.year () &&
+ a.month () == b.month () &&
+ az == bz;
+ }
+
+ inline bool
+ operator!= (const gyear_month& a, const gyear_month& b)
+ {
+ return !(a == b);
+ }
+
+ // date
+ //
+ inline date::
+ date (int year, unsigned short month, unsigned short day)
+ : year_ (year), month_ (month), day_ (day)
+ {
+ }
+
+ inline date::
+ date (int year, unsigned short month, unsigned short day,
+ short zh, short zm)
+ : time_zone (zh, zm), year_ (year), month_ (month), day_ (day)
+ {
+ }
+
+ inline int date::
+ year () const
+ {
+ return year_;
+ }
+
+ inline void date::
+ year (int year)
+ {
+ year_ = year;
+ }
+
+ inline unsigned short date::
+ month () const
+ {
+ return month_;
+ }
+
+ inline void date::
+ month (unsigned short month)
+ {
+ month_ = month;
+ }
+
+ inline unsigned short date::
+ day () const
+ {
+ return day_;
+ }
+
+ inline void date::
+ day (unsigned short day)
+ {
+ day_ = day;
+ }
+
+ inline bool
+ operator== (const date& a, const date& b)
+ {
+ const time_zone& az = a;
+ const time_zone& bz = b;
+
+ return a.year () == b.year () &&
+ a.month () == b.month () &&
+ a.day () == b.day () &&
+ az == bz;
+ }
+
+ inline bool
+ operator!= (const date& a, const date& b)
+ {
+ return !(a == b);
+ }
+
+ // time
+ //
+ inline time::
+ time (unsigned short hours, unsigned short minutes, double seconds)
+ : hours_ (hours), minutes_ (minutes), seconds_ (seconds)
+ {
+ }
+
+ inline time::
+ time (unsigned short hours, unsigned short minutes, double seconds,
+ short zh, short zm)
+ : time_zone (zh, zm),
+ hours_ (hours), minutes_ (minutes), seconds_ (seconds)
+ {
+ }
+
+ inline unsigned short time::
+ hours () const
+ {
+ return hours_;
+ }
+
+ inline void time::
+ hours (unsigned short hours)
+ {
+ hours_ = hours;
+ }
+
+ inline unsigned short time::
+ minutes () const
+ {
+ return minutes_;
+ }
+
+ inline void time::
+ minutes (unsigned short minutes)
+ {
+ minutes_ = minutes;
+ }
+
+ inline double time::
+ seconds () const
+ {
+ return seconds_;
+ }
+
+ inline void time::
+ seconds (double seconds)
+ {
+ seconds_ = seconds;
+ }
+
+ inline bool
+ operator== (const time& a, const time& b)
+ {
+ const time_zone& az = a;
+ const time_zone& bz = b;
+
+ return a.hours () == b.hours () &&
+ a.minutes () == b.minutes () &&
+ a.seconds () == b.seconds () &&
+ az == bz;
+ }
+
+ inline bool
+ operator!= (const time& a, const time& b)
+ {
+ return !(a == b);
+ }
+
+ // date_time
+ //
+ inline date_time::
+ date_time (int year, unsigned short month, unsigned short day,
+ unsigned short hours, unsigned short minutes, double seconds)
+ : year_ (year), month_ (month), day_ (day),
+ hours_ (hours), minutes_ (minutes), seconds_ (seconds)
+ {
+ }
+
+ inline date_time::
+ date_time (int year, unsigned short month, unsigned short day,
+ unsigned short hours, unsigned short minutes, double seconds,
+ short zh, short zm)
+ : time_zone (zh, zm),
+ year_ (year), month_ (month), day_ (day),
+ hours_ (hours), minutes_ (minutes), seconds_ (seconds)
+ {
+ }
+
+ inline int date_time::
+ year () const
+ {
+ return year_;
+ }
+
+ inline void date_time::
+ year (int year)
+ {
+ year_ = year;
+ }
+
+ inline unsigned short date_time::
+ month () const
+ {
+ return month_;
+ }
+
+ inline void date_time::
+ month (unsigned short month)
+ {
+ month_ = month;
+ }
+
+ inline unsigned short date_time::
+ day () const
+ {
+ return day_;
+ }
+
+ inline void date_time::
+ day (unsigned short day)
+ {
+ day_ = day;
+ }
+
+ inline unsigned short date_time::
+ hours () const
+ {
+ return hours_;
+ }
+
+ inline void date_time::
+ hours (unsigned short hours)
+ {
+ hours_ = hours;
+ }
+
+ inline unsigned short date_time::
+ minutes () const
+ {
+ return minutes_;
+ }
+
+ inline void date_time::
+ minutes (unsigned short minutes)
+ {
+ minutes_ = minutes;
+ }
+
+ inline double date_time::
+ seconds () const
+ {
+ return seconds_;
+ }
+
+ inline void date_time::
+ seconds (double seconds)
+ {
+ seconds_ = seconds;
+ }
+
+ inline bool
+ operator== (const date_time& a, const date_time& b)
+ {
+ const time_zone& az = a;
+ const time_zone& bz = b;
+
+ return a.year () == b.year () &&
+ a.month () == b.month () &&
+ a.day () == b.day () &&
+ a.hours () == b.hours () &&
+ a.minutes () == b.minutes () &&
+ a.seconds () == b.seconds () &&
+ az == bz;
+ }
+
+ inline bool
+ operator!= (const date_time& a, const date_time& b)
+ {
+ return !(a == b);
+ }
+
+ // duration
+ //
+ inline duration::
+ duration (bool negative,
+ unsigned int years, unsigned int months, unsigned int days,
+ unsigned int hours, unsigned int minutes, double seconds)
+ : negative_ (negative),
+ years_ (years), months_ (months), days_ (days),
+ hours_ (hours), minutes_ (minutes), seconds_ (seconds)
+ {
+ }
+
+ inline bool duration::
+ negative () const
+ {
+ return negative_;
+ }
+
+ inline void duration::
+ negative (bool negative)
+ {
+ negative_ = negative;
+ }
+
+ inline unsigned int duration::
+ years () const
+ {
+ return years_;
+ }
+
+ inline void duration::
+ years (unsigned int years)
+ {
+ years_ = years;
+ }
+
+ inline unsigned int duration::
+ months () const
+ {
+ return months_;
+ }
+
+ inline void duration::
+ months (unsigned int months)
+ {
+ months_ = months;
+ }
+
+ inline unsigned int duration::
+ days () const
+ {
+ return days_;
+ }
+
+ inline void duration::
+ days (unsigned int days)
+ {
+ days_ = days;
+ }
+
+ inline unsigned int duration::
+ hours () const
+ {
+ return hours_;
+ }
+
+ inline void duration::
+ hours (unsigned int hours)
+ {
+ hours_ = hours;
+ }
+
+ inline unsigned int duration::
+ minutes () const
+ {
+ return minutes_;
+ }
+
+ inline void duration::
+ minutes (unsigned int minutes)
+ {
+ minutes_ = minutes;
+ }
+
+ inline double duration::
+ seconds () const
+ {
+ return seconds_;
+ }
+
+ inline void duration::
+ seconds (double seconds)
+ {
+ seconds_ = seconds;
+ }
+
+ inline bool
+ operator== (const duration& a, const duration& b)
+ {
+ return a.negative () == b.negative () &&
+ a.years () == b.years () &&
+ a.months () == b.months () &&
+ a.days () == b.days () &&
+ a.hours () == b.hours () &&
+ a.minutes () == b.minutes () &&
+ a.seconds () == b.seconds ();
+ }
+
+ inline bool
+ operator!= (const duration& a, const duration& b)
+ {
+ return !(a == b);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/parser/xml-schema.txx b/libxsd/xsd/cxx/parser/xml-schema.txx
new file mode 100644
index 0000000..c0e2de9
--- /dev/null
+++ b/libxsd/xsd/cxx/parser/xml-schema.txx
@@ -0,0 +1,34 @@
+// file : xsd/cxx/parser/xml-schema.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace parser
+ {
+ // string_sequence
+ //
+ template <typename C>
+ bool
+ operator== (const string_sequence<C>& a, const string_sequence<C>& b)
+ {
+ if (a.size () != b.size ())
+ return false;
+
+ for (typename string_sequence<C>::const_iterator
+ ai (a.begin ()), bi (b.begin ()), ae (a.end ());
+ ai != ae; ++ai, ++bi)
+ {
+ if (*ai != *bi)
+ return false;
+ }
+
+ return true;
+ }
+ }
+ }
+}
+
diff --git a/libxsd/xsd/cxx/post.hxx b/libxsd/xsd/cxx/post.hxx
new file mode 100644
index 0000000..839d473
--- /dev/null
+++ b/libxsd/xsd/cxx/post.hxx
@@ -0,0 +1,13 @@
+// file : xsd/cxx/post.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+
+#ifdef _MSC_VER
+# if (_MSC_VER >= 1400)
+# include <xsd/cxx/compilers/vc-8/post.hxx>
+# elif (_MSC_VER >= 1300)
+# include <xsd/cxx/compilers/vc-7/post.hxx>
+# endif
+#endif
diff --git a/libxsd/xsd/cxx/pre.hxx b/libxsd/xsd/cxx/pre.hxx
new file mode 100644
index 0000000..4d5bce7
--- /dev/null
+++ b/libxsd/xsd/cxx/pre.hxx
@@ -0,0 +1,15 @@
+// file : xsd/cxx/pre.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+
+#ifdef _MSC_VER
+# if (_MSC_VER >= 1400)
+# include <xsd/cxx/compilers/vc-8/pre.hxx>
+# elif (_MSC_VER >= 1300)
+# include <xsd/cxx/compilers/vc-7/pre.hxx>
+# else
+# error Microsoft Visual C++ 6 is not supported.
+# endif
+#endif
diff --git a/libxsd/xsd/cxx/ro-string.hxx b/libxsd/xsd/cxx/ro-string.hxx
new file mode 100644
index 0000000..33a70e6
--- /dev/null
+++ b/libxsd/xsd/cxx/ro-string.hxx
@@ -0,0 +1,430 @@
+// file : xsd/cxx/ro-string.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_RO_STRING_HXX
+#define XSD_CXX_RO_STRING_HXX
+
+#include <string>
+#include <cstddef> // std::size_t
+#include <ostream>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ // Read-only string class template.
+ //
+ template <typename C>
+ class ro_string
+ {
+ public:
+ typedef std::char_traits<C> traits_type;
+ typedef std::size_t size_type;
+
+ static const size_type npos = ~(size_type (0));
+
+ public:
+ ro_string ()
+ : data_ (0), size_ (0)
+ {
+ }
+
+ ro_string (const C* s)
+ : data_ (s), size_ (traits_type::length (s))
+ {
+ }
+
+ ro_string (const C* s, size_type size)
+ : data_ (s), size_ (size)
+ {
+ }
+
+ ro_string (const std::basic_string<C>& s)
+ : data_ (s.data ()), size_ (s.size ())
+ {
+ }
+
+ operator std::basic_string<C> () const
+ {
+ return std::basic_string<C> (data (), size ());
+ }
+
+ private:
+ ro_string (const ro_string&);
+
+ ro_string&
+ operator= (const ro_string&);
+
+ public:
+ // The returned string is not necessarily terminated with '\0'.
+ // If size() returns 0, the returned pointer may be 0.
+ //
+ const C*
+ data () const
+ {
+ return data_;
+ }
+
+ size_type
+ size () const
+ {
+ return size_;
+ }
+
+ size_type
+ length () const
+ {
+ return size ();
+ }
+
+ public:
+ bool
+ empty () const
+ {
+ return size () == 0;
+ }
+
+ const C&
+ operator[] (size_type pos) const
+ {
+ return data ()[pos];
+ }
+
+ public:
+ void
+ assign (const C* s)
+ {
+ data_ = s;
+ size_ = traits_type::length (s);
+ }
+
+ void
+ assign (const C* s, size_type size)
+ {
+ data_ = s;
+ size_ = size;
+ }
+
+ void
+ assign (const std::basic_string<C>& s)
+ {
+ data_ = s.c_str ();
+ size_ = s.size ();
+ }
+
+ public:
+ int
+ compare (const ro_string& str) const
+ {
+ return compare (str.data (), str.size ());
+ }
+
+ int
+ compare (const std::basic_string<C>& str) const
+ {
+ return compare (str.c_str (), str.size ());
+ }
+
+ int
+ compare (const C* str) const
+ {
+ return compare (str, traits_type::length (str));
+ }
+
+ int
+ compare (const C* str, size_type n) const
+ {
+ size_type s1 (size ());
+ size_type s (s1 < n ? s1 : n);
+
+ int r (s != 0 ? traits_type::compare (data (), str, s) : 0);
+
+ if (!r && s1 != n)
+ r = s1 < n ? -1 : 1;
+
+ return r;
+ }
+
+ public:
+ size_type
+ find (C c, size_type pos = 0) const;
+
+ private:
+ const C* data_;
+ size_type size_;
+ };
+
+ // operator==
+ //
+ template <typename C>
+ inline bool
+ operator== (const ro_string<C>& a, const ro_string<C>& b)
+ {
+ return a.compare (b) == 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator== (const ro_string<C>& a, const std::basic_string<C>& b)
+ {
+ return a.compare (b) == 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator== (const std::basic_string<C>& a, const ro_string<C>& b)
+ {
+ return b.compare (a) == 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator== (const ro_string<C>& a, const C* b)
+ {
+ return a.compare (b) == 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator== (const C* a, const ro_string<C>& b)
+ {
+ return b.compare (a) == 0;
+ }
+
+ // operator!=
+ //
+ template <typename C>
+ inline bool
+ operator!= (const ro_string<C>& a, const ro_string<C>& b)
+ {
+ return a.compare (b) != 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator!= (const ro_string<C>& a, const std::basic_string<C>& b)
+ {
+ return a.compare (b) != 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator!= (const std::basic_string<C>& a, const ro_string<C>& b)
+ {
+ return b.compare (a) != 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator!= (const ro_string<C>& a, const C* b)
+ {
+ return a.compare (b) != 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator!= (const C* a, const ro_string<C>& b)
+ {
+ return b.compare (a) != 0;
+ }
+
+ // operator<
+ //
+ template <typename C>
+ inline bool
+ operator< (const ro_string<C>& l, const ro_string<C>& r)
+ {
+ return l.compare (r) < 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator< (const ro_string<C>& l, const std::basic_string<C>& r)
+ {
+ return l.compare (r) < 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator< (const std::basic_string<C>& l, const ro_string<C>& r)
+ {
+ return r.compare (l) > 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator< (const ro_string<C>& l, const C* r)
+ {
+ return l.compare (r) < 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator< (const C* l, const ro_string<C>& r)
+ {
+ return r.compare (l) > 0;
+ }
+
+
+ // operator>
+ //
+ template <typename C>
+ inline bool
+ operator> (const ro_string<C>& l, const ro_string<C>& r)
+ {
+ return l.compare (r) > 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator> (const ro_string<C>& l, const std::basic_string<C>& r)
+ {
+ return l.compare (r) > 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator> (const std::basic_string<C>& l, const ro_string<C>& r)
+ {
+ return r.compare (l) < 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator> (const ro_string<C>& l, const C* r)
+ {
+ return l.compare (r) > 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator> (const C* l, const ro_string<C>& r)
+ {
+ return r.compare (l) < 0;
+ }
+
+ // operator<=
+ //
+ template <typename C>
+ inline bool
+ operator<= (const ro_string<C>& l, const ro_string<C>& r)
+ {
+ return l.compare (r) <= 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator<= (const ro_string<C>& l, const std::basic_string<C>& r)
+ {
+ return l.compare (r) <= 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator<= (const std::basic_string<C>& l, const ro_string<C>& r)
+ {
+ return r.compare (l) >= 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator<= (const ro_string<C>& l, const C* r)
+ {
+ return l.compare (r) <= 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator<= (const C* l, const ro_string<C>& r)
+ {
+ return r.compare (l) >= 0;
+ }
+
+
+ // operator>=
+ //
+ template <typename C>
+ inline bool
+ operator>= (const ro_string<C>& l, const ro_string<C>& r)
+ {
+ return l.compare (r) >= 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator>= (const ro_string<C>& l, const std::basic_string<C>& r)
+ {
+ return l.compare (r) >= 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator>= (const std::basic_string<C>& l, const ro_string<C>& r)
+ {
+ return r.compare (l) <= 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator>= (const ro_string<C>& l, const C* r)
+ {
+ return l.compare (r) >= 0;
+ }
+
+ template <typename C>
+ inline bool
+ operator>= (const C* l, const ro_string<C>& r)
+ {
+ return r.compare (l) <= 0;
+ }
+
+ // operator<<
+ //
+ template<typename C>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const ro_string<C>& str)
+ {
+ if (str.size () != 0)
+ os.write (str.data (), static_cast<std::streamsize> (str.size ()));
+
+ return os;
+ }
+
+ // operator+=
+ //
+ template<typename C>
+ std::basic_string<C>&
+ operator+= (std::basic_string<C>& l, const ro_string<C>& r)
+ {
+ l.append (r.data (), r.size ());
+ return l;
+ }
+
+ // Trim leading and trailing XML whitespaces. Return the new
+ // string size.
+ //
+ template <typename C>
+ typename ro_string<C>::size_type
+ trim_left (ro_string<C>&);
+
+ template <typename C>
+ typename ro_string<C>::size_type
+ trim_right (ro_string<C>&);
+
+ template <typename C>
+ typename ro_string<C>::size_type
+ trim (ro_string<C>&);
+
+ // Trim leading and trailing XML whitespaces.
+ //
+ template<typename C>
+ std::basic_string<C>
+ trim (const std::basic_string<C>&);
+ }
+}
+
+#include <xsd/cxx/ro-string.txx>
+
+#endif // XSD_CXX_RO_STRING_HXX
diff --git a/libxsd/xsd/cxx/ro-string.txx b/libxsd/xsd/cxx/ro-string.txx
new file mode 100644
index 0000000..6f4be14
--- /dev/null
+++ b/libxsd/xsd/cxx/ro-string.txx
@@ -0,0 +1,133 @@
+// file : xsd/cxx/ro-string.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ template <typename C>
+ typename ro_string<C>::size_type ro_string<C>::
+ find (C c, size_type pos) const
+ {
+ size_type r (npos);
+
+ if (pos < size_)
+ {
+ if (const C* p = traits_type::find(data_ + pos, size_ - pos, c))
+ r = p - data_;
+ }
+
+ return r;
+ }
+
+ template<typename C>
+ typename ro_string<C>::size_type
+ trim_left (ro_string<C>& s)
+ {
+ typename ro_string<C>::size_type size (s.size ());
+
+ if (size != 0)
+ {
+ const C* f (s.data ());
+ const C* l (f + size);
+ const C* of (f);
+
+ while (f < l &&
+ (*f == C (0x20) || *f == C (0x0A) ||
+ *f == C (0x0D) || *f == C (0x09)))
+ ++f;
+
+ if (f != of)
+ {
+ size = f <= l ? l - f : 0;
+ s.assign ((f <= l ? f : 0), size);
+ }
+ }
+
+ return size;
+ }
+
+ template<typename C>
+ typename ro_string<C>::size_type
+ trim_right (ro_string<C>& s)
+ {
+ typename ro_string<C>::size_type size (s.size ());
+
+ if (size != 0)
+ {
+ const C* f (s.data ());
+ const C* l (f + size - 1);
+ const C* ol (l);
+
+ while (l > f &&
+ (*l == C (0x20) || *l == C (0x0A) ||
+ *l == C (0x0D) || *l == C (0x09)))
+ --l;
+
+ if (l != ol)
+ {
+ size = f <= l ? l - f + 1 : 0;
+ s.assign ((f <= l ? f : 0), size);
+ }
+ }
+
+ return size;
+ }
+
+ template<typename C>
+ typename ro_string<C>::size_type
+ trim (ro_string<C>& s)
+ {
+ typename ro_string<C>::size_type size (s.size ());
+
+ if (size != 0)
+ {
+ const C* f (s.data ());
+ const C* l (f + size);
+
+ const C* of (f);
+
+ while (f < l &&
+ (*f == C (0x20) || *f == C (0x0A) ||
+ *f == C (0x0D) || *f == C (0x09)))
+ ++f;
+
+ --l;
+
+ const C* ol (l);
+
+ while (l > f &&
+ (*l == C (0x20) || *l == C (0x0A) ||
+ *l == C (0x0D) || *l == C (0x09)))
+ --l;
+
+ if (f != of || l != ol)
+ {
+ size = f <= l ? l - f + 1 : 0;
+ s.assign ((f <= l ? f : 0), size);
+ }
+ }
+
+ return size;
+ }
+
+ template<typename C>
+ std::basic_string<C>
+ trim (const std::basic_string<C>& s)
+ {
+ ro_string<C> tmp (s);
+ typename ro_string<C>::size_type size (tmp.size ());
+ trim (tmp);
+
+ // If we didn't change the string then return the original to help
+ // avoid copying for smart (ref counted) string implementations.
+ //
+ if (size == tmp.size ())
+ return s;
+ else
+ return tmp;
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/ace-cdr-stream-common.hxx b/libxsd/xsd/cxx/tree/ace-cdr-stream-common.hxx
new file mode 100644
index 0000000..55f4547
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/ace-cdr-stream-common.hxx
@@ -0,0 +1,26 @@
+// file : xsd/cxx/tree/ace-cdr-stream-common.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_ACE_CDR_STREAM_COMMON_HXX
+#define XSD_CXX_TREE_ACE_CDR_STREAM_COMMON_HXX
+
+#include <xsd/cxx/exceptions.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // Base exception for ACE CDR insertion/extraction exceptions.
+ //
+ struct ace_cdr_stream_operation: xsd::cxx::exception
+ {
+ };
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_ACE_CDR_STREAM_COMMON_HXX
diff --git a/libxsd/xsd/cxx/tree/ace-cdr-stream-extraction.hxx b/libxsd/xsd/cxx/tree/ace-cdr-stream-extraction.hxx
new file mode 100644
index 0000000..8151507
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/ace-cdr-stream-extraction.hxx
@@ -0,0 +1,334 @@
+// file : xsd/cxx/tree/ace-cdr-stream-extraction.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_ACE_CDR_STREAM_EXTRACTION_HXX
+#define XSD_CXX_TREE_ACE_CDR_STREAM_EXTRACTION_HXX
+
+#include <cstddef> // std::size_t
+#include <string>
+
+#include <ace/ACE.h> // ACE::strdelete
+#include <ace/CDR_Stream.h>
+
+#include <xsd/cxx/auto-array.hxx>
+
+#include <xsd/cxx/tree/buffer.hxx>
+#include <xsd/cxx/tree/istream.hxx>
+#include <xsd/cxx/tree/ace-cdr-stream-common.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ struct ace_cdr_stream_extraction: ace_cdr_stream_operation
+ {
+ virtual const char*
+ what () const throw ()
+ {
+ return "ACE CDR stream extraction operation failed";
+ }
+ };
+
+
+ // as_size
+ //
+
+#ifdef XSD_CXX_TREE_USE_64_BIT_SIZE
+ template <typename T>
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s,
+ istream<ACE_InputCDR>::as_size<T>& x)
+ {
+ ACE_CDR::ULongLong r;
+
+ if (!s.impl ().read_ulonglong (r) ||
+ r > ~(T (0)))
+ throw ace_cdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (r);
+
+ return s;
+ }
+#else
+ template <typename T>
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s,
+ istream<ACE_InputCDR>::as_size<T>& x)
+ {
+ ACE_CDR::ULong r;
+
+ if (!s.impl ().read_ulong (r))
+ throw ace_cdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (r);
+
+ return s;
+ }
+#endif
+
+
+ // 8-bit
+ //
+ template <typename T>
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s,
+ istream<ACE_InputCDR>::as_int8<T>& x)
+ {
+ ACE_CDR::Octet r;
+
+ if (!s.impl ().read_octet (r))
+ throw ace_cdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (r);
+
+ return s;
+ }
+
+ template <typename T>
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s,
+ istream<ACE_InputCDR>::as_uint8<T>& x)
+ {
+ ACE_CDR::Octet r;
+
+ if (!s.impl ().read_octet (r))
+ throw ace_cdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (r);
+
+ return s;
+ }
+
+
+ // 16-bit
+ //
+ template <typename T>
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s,
+ istream<ACE_InputCDR>::as_int16<T>& x)
+ {
+ ACE_CDR::Short r;
+
+ if (!s.impl ().read_short (r))
+ throw ace_cdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (r);
+
+ return s;
+ }
+
+ template <typename T>
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s,
+ istream<ACE_InputCDR>::as_uint16<T>& x)
+ {
+ ACE_CDR::UShort r;
+
+ if (!s.impl ().read_ushort (r))
+ throw ace_cdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (r);
+
+ return s;
+ }
+
+
+ // 32-bit
+ //
+ template <typename T>
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s,
+ istream<ACE_InputCDR>::as_int32<T>& x)
+ {
+ ACE_CDR::Long r;
+
+ if (!s.impl ().read_long (r))
+ throw ace_cdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (r);
+
+ return s;
+ }
+
+ template <typename T>
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s,
+ istream<ACE_InputCDR>::as_uint32<T>& x)
+ {
+ ACE_CDR::ULong r;
+
+ if (!s.impl ().read_ulong (r))
+ throw ace_cdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (r);
+
+ return s;
+ }
+
+
+ // 64-bit
+ //
+ template <typename T>
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s,
+ istream<ACE_InputCDR>::as_int64<T>& x)
+ {
+ ACE_CDR::LongLong r;
+
+ if (!s.impl ().read_longlong (r))
+ throw ace_cdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (r);
+
+ return s;
+ }
+
+ template <typename T>
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s,
+ istream<ACE_InputCDR>::as_uint64<T>& x)
+ {
+ ACE_CDR::ULongLong r;
+
+ if (!s.impl ().read_ulonglong (r))
+ throw ace_cdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (r);
+
+ return s;
+ }
+
+
+ // Boolean
+ //
+ template <typename T>
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s,
+ istream<ACE_InputCDR>::as_bool<T>& x)
+ {
+ ACE_CDR::Boolean r;
+
+ if (!s.impl ().read_boolean (r))
+ throw ace_cdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (r);
+
+ return s;
+ }
+
+
+ // Floating-point
+ //
+ template <typename T>
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s,
+ istream<ACE_InputCDR>::as_float32<T>& x)
+ {
+ ACE_CDR::Float r;
+
+ if (!s.impl ().read_float (r))
+ throw ace_cdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (r);
+
+ return s;
+ }
+
+ template <typename T>
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s,
+ istream<ACE_InputCDR>::as_float64<T>& x)
+ {
+ ACE_CDR::Double r;
+
+ if (!s.impl ().read_double (r))
+ throw ace_cdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (r);
+
+ return s;
+ }
+
+ // Extraction of std::basic_string.
+ //
+
+ namespace bits
+ {
+ template<typename C>
+ struct ace_str_deallocator
+ {
+ void
+ deallocate (C* s)
+ {
+ ACE::strdelete (s);
+ }
+ };
+ }
+
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s, std::basic_string<char>& x)
+ {
+ typedef bits::ace_str_deallocator<char> deallocator;
+
+ deallocator d;
+ char* r;
+
+ if (!s.impl ().read_string (r))
+ throw ace_cdr_stream_extraction ();
+
+ auto_array<char, deallocator> ar (r, d);
+
+ x = r;
+
+ return s;
+ }
+
+#ifdef ACE_HAS_WCHAR
+ inline istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s, std::basic_string<wchar_t>& x)
+ {
+ typedef bits::ace_str_deallocator<wchar_t> deallocator;
+
+ deallocator d;
+ wchar_t* r;
+
+ if (!s.impl ().read_wstring (r))
+ throw ace_cdr_stream_extraction ();
+
+ auto_array<wchar_t, deallocator> ar (r, d);
+
+ x = r;
+
+ return s;
+ }
+#endif
+
+
+ // Extraction of a binary buffer.
+ //
+ template <typename C>
+ istream<ACE_InputCDR>&
+ operator>> (istream<ACE_InputCDR>& s, buffer<C>& x)
+ {
+ ACE_CDR::ULong size;
+
+ if (!s.impl ().read_ulong (size))
+ throw ace_cdr_stream_extraction ();
+
+ x.size (size);
+
+ if (!s.impl ().read_octet_array (
+ reinterpret_cast<ACE_CDR::Octet*> (x.data ()), size))
+ throw ace_cdr_stream_extraction ();
+
+ return s;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_ACE_CDR_STREAM_EXTRACTION_HXX
diff --git a/libxsd/xsd/cxx/tree/ace-cdr-stream-insertion.hxx b/libxsd/xsd/cxx/tree/ace-cdr-stream-insertion.hxx
new file mode 100644
index 0000000..d9c4187
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/ace-cdr-stream-insertion.hxx
@@ -0,0 +1,249 @@
+// file : xsd/cxx/tree/ace-cdr-stream-insertion.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_ACE_CDR_STREAM_INSERTION_HXX
+#define XSD_CXX_TREE_ACE_CDR_STREAM_INSERTION_HXX
+
+#include <cstddef> // std::size_t
+#include <string>
+
+#include <ace/CDR_Stream.h>
+
+#include <xsd/cxx/tree/buffer.hxx>
+#include <xsd/cxx/tree/ostream.hxx>
+#include <xsd/cxx/tree/ace-cdr-stream-common.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ struct ace_cdr_stream_insertion: ace_cdr_stream_operation
+ {
+ virtual const char*
+ what () const throw ()
+ {
+ return "ACE CDR stream insertion operation failed";
+ }
+ };
+
+
+ // as_size
+ //
+
+#ifdef XSD_CXX_TREE_USE_64_BIT_SIZE
+ template <typename T>
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ ostream<ACE_OutputCDR>::as_size<T> x)
+ {
+ if (!s.impl ().write_ulonglong (
+ static_cast<ACE_CDR::ULongLong> (x.x_)))
+ throw ace_cdr_stream_insertion ();
+ return s;
+ }
+#else
+ template <typename T>
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ ostream<ACE_OutputCDR>::as_size<T> x)
+ {
+ if (x.x_ > ~(ACE_CDR::ULong (0)) ||
+ !s.impl ().write_ulong (static_cast<ACE_CDR::ULong> (x.x_)))
+ throw ace_cdr_stream_insertion ();
+
+ return s;
+ }
+#endif
+
+
+ // 8-bit
+ //
+ template <typename T>
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ ostream<ACE_OutputCDR>::as_int8<T> x)
+ {
+ ACE_CDR::Octet r (static_cast<ACE_CDR::Octet> (x.x_));
+
+ if (!s.impl ().write_octet (r))
+ throw ace_cdr_stream_insertion ();
+
+ return s;
+ }
+
+ template <typename T>
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ ostream<ACE_OutputCDR>::as_uint8<T> x)
+ {
+ ACE_CDR::Octet r (static_cast<ACE_CDR::Octet> (x.x_));
+
+ if (!s.impl ().write_octet (r))
+ throw ace_cdr_stream_insertion ();
+
+ return s;
+ }
+
+
+ // 16-bit
+ //
+ template <typename T>
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ ostream<ACE_OutputCDR>::as_int16<T> x)
+ {
+ if (!s.impl ().write_short (static_cast<ACE_CDR::Short> (x.x_)))
+ throw ace_cdr_stream_insertion ();
+ return s;
+ }
+
+ template <typename T>
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ ostream<ACE_OutputCDR>::as_uint16<T> x)
+ {
+ if (!s.impl ().write_ushort (static_cast<ACE_CDR::UShort> (x.x_)))
+ throw ace_cdr_stream_insertion ();
+ return s;
+ }
+
+
+ // 32-bit
+ //
+ template <typename T>
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ ostream<ACE_OutputCDR>::as_int32<T> x)
+ {
+ if (!s.impl ().write_long (static_cast<ACE_CDR::Long> (x.x_)))
+ throw ace_cdr_stream_insertion ();
+ return s;
+ }
+
+ template <typename T>
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ ostream<ACE_OutputCDR>::as_uint32<T> x)
+ {
+ if (!s.impl ().write_ulong (static_cast<ACE_CDR::ULong> (x.x_)))
+ throw ace_cdr_stream_insertion ();
+ return s;
+ }
+
+
+ // 64-bit
+ //
+ template <typename T>
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ ostream<ACE_OutputCDR>::as_int64<T> x)
+ {
+ if (!s.impl ().write_longlong (static_cast<ACE_CDR::LongLong> (x.x_)))
+ throw ace_cdr_stream_insertion ();
+ return s;
+ }
+
+ template <typename T>
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ ostream<ACE_OutputCDR>::as_uint64<T> x)
+ {
+ if (!s.impl ().write_ulonglong (
+ static_cast<ACE_CDR::ULongLong> (x.x_)))
+ throw ace_cdr_stream_insertion ();
+ return s;
+ }
+
+
+ // Boolean
+ //
+ template <typename T>
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ ostream<ACE_OutputCDR>::as_bool<T> x)
+ {
+ if (!s.impl ().write_boolean (static_cast<ACE_CDR::Boolean> (x.x_)))
+ throw ace_cdr_stream_insertion ();
+ return s;
+ }
+
+
+ // Floating-point
+ //
+ template <typename T>
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ ostream<ACE_OutputCDR>::as_float32<T> x)
+ {
+ if (!s.impl ().write_float (static_cast<ACE_CDR::Float> (x.x_)))
+ throw ace_cdr_stream_insertion ();
+ return s;
+ }
+
+ template <typename T>
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ ostream<ACE_OutputCDR>::as_float64<T> x)
+ {
+ if (!s.impl ().write_double (static_cast<ACE_CDR::Double> (x.x_)))
+ throw ace_cdr_stream_insertion ();
+ return s;
+ }
+
+ // Insertion of std::basic_string.
+ //
+
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s, const std::basic_string<char>& x)
+ {
+ // ACE CDR strings are hard-wired with a 32 bit length.
+ //
+ if (x.length () > ~(ACE_CDR::ULong (0)) ||
+ !s.impl ().write_string (
+ static_cast<ACE_CDR::ULong> (x.length ()), x.c_str ()))
+ throw ace_cdr_stream_insertion ();
+ return s;
+ }
+
+#ifdef ACE_HAS_WCHAR
+ inline ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s,
+ const std::basic_string<wchar_t>& x)
+ {
+ // ACE CDR strings are hard-wired with a 32 bit length.
+ //
+ if (x.length () > ~(ACE_CDR::ULong (0)) ||
+ !s.impl ().write_wstring (
+ static_cast<ACE_CDR::ULong> (x.length ()), x.c_str ()))
+ throw ace_cdr_stream_insertion ();
+ return s;
+ }
+#endif
+
+ // Insertion of a binary buffer.
+ //
+ template <typename C>
+ ostream<ACE_OutputCDR>&
+ operator<< (ostream<ACE_OutputCDR>& s, const buffer<C>& x)
+ {
+ std::size_t size (x.size ());
+
+ // It is not possible to write an array with a 64-bit size.
+ //
+ if (size > ~(ACE_CDR::ULong (0)) ||
+ !s.impl ().write_ulong (static_cast<ACE_CDR::ULong> (size)) ||
+ !s.impl ().write_octet_array (
+ reinterpret_cast<const ACE_CDR::Octet*> (x.data ()), size))
+ throw ace_cdr_stream_insertion ();
+
+ return s;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_ACE_CDR_STREAM_INSERTION_HXX
diff --git a/libxsd/xsd/cxx/tree/bits/literals.hxx b/libxsd/xsd/cxx/tree/bits/literals.hxx
new file mode 100644
index 0000000..186e0dc
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/bits/literals.hxx
@@ -0,0 +1,183 @@
+// file : xsd/cxx/tree/bits/literals.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_BITS_LITERALS_HXX
+#define XSD_CXX_TREE_BITS_LITERALS_HXX
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ namespace bits
+ {
+ // Boolean literals
+ //
+ template<typename C>
+ const C*
+ true_ ();
+
+ template<typename C>
+ const C*
+ one ();
+
+ // Float literals: INF -INF NaN.
+ //
+ template<typename C>
+ const C*
+ positive_inf ();
+
+ template<typename C>
+ const C*
+ negative_inf ();
+
+ template<typename C>
+ const C*
+ nan ();
+
+ // Optional "not present" literal.
+ //
+ template<typename C>
+ const C*
+ not_present ();
+
+ // XML Schema namespace
+ //
+ template <typename C>
+ const C*
+ xml_schema ();
+
+ // Built-in XML Schema type names.
+ //
+ template <typename C>
+ const C*
+ any_type ();
+
+ template <typename C>
+ const C*
+ any_simple_type ();
+
+ template <typename C>
+ const C*
+ string ();
+
+ template <typename C>
+ const C*
+ normalized_string ();
+
+ template <typename C>
+ const C*
+ token ();
+
+ template <typename C>
+ const C*
+ name ();
+
+ template <typename C>
+ const C*
+ nmtoken ();
+
+ template <typename C>
+ const C*
+ nmtokens ();
+
+ template <typename C>
+ const C*
+ ncname ();
+
+ template <typename C>
+ const C*
+ language ();
+
+ template <typename C>
+ const C*
+ id ();
+
+ template <typename C>
+ const C*
+ idref ();
+
+ template <typename C>
+ const C*
+ idrefs ();
+
+ template <typename C>
+ const C*
+ any_uri ();
+
+ template <typename C>
+ const C*
+ qname ();
+
+ template <typename C>
+ const C*
+ base64_binary ();
+
+ template <typename C>
+ const C*
+ hex_binary ();
+
+ template <typename C>
+ const C*
+ date ();
+
+ template <typename C>
+ const C*
+ date_time ();
+
+ template <typename C>
+ const C*
+ duration ();
+
+ template <typename C>
+ const C*
+ gday ();
+
+ template <typename C>
+ const C*
+ gmonth ();
+
+ template <typename C>
+ const C*
+ gmonth_day ();
+
+ template <typename C>
+ const C*
+ gyear ();
+
+ template <typename C>
+ const C*
+ gyear_month ();
+
+ template <typename C>
+ const C*
+ time ();
+
+ template <typename C>
+ const C*
+ entity ();
+
+ template <typename C>
+ const C*
+ entities ();
+
+ // gday ("---") and gmonth ("--") prefixes.
+ //
+ template <typename C>
+ const C*
+ gday_prefix ();
+
+ template <typename C>
+ const C*
+ gmonth_prefix ();
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_BITS_LITERALS_HXX
+
+#include <xsd/cxx/tree/bits/literals.ixx>
diff --git a/libxsd/xsd/cxx/tree/bits/literals.ixx b/libxsd/xsd/cxx/tree/bits/literals.ixx
new file mode 100644
index 0000000..d2620e6
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/bits/literals.ixx
@@ -0,0 +1,606 @@
+// file : xsd/cxx/tree/bits/literals.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_BITS_LITERALS_IXX
+#define XSD_CXX_TREE_BITS_LITERALS_IXX
+
+// The char versions of the following literals are required even
+// if we are using wchar_t as the character type.
+//
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ namespace bits
+ {
+ //
+ //
+ template<>
+ inline const char*
+ positive_inf<char> ()
+ {
+ return "INF";
+ }
+
+ template<>
+ inline const char*
+ negative_inf<char> ()
+ {
+ return "-INF";
+ }
+
+ template<>
+ inline const char*
+ nan<char> ()
+ {
+ return "NaN";
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_BITS_LITERALS_IXX
+
+
+#if defined(XSD_CXX_TREE_USE_CHAR) || !defined(XSD_CXX_TREE_USE_WCHAR)
+
+#ifndef XSD_CXX_TREE_BITS_LITERALS_IXX_CHAR
+#define XSD_CXX_TREE_BITS_LITERALS_IXX_CHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ namespace bits
+ {
+ //
+ //
+ template<>
+ inline const char*
+ true_<char> ()
+ {
+ return "true";
+ }
+
+ template<>
+ inline const char*
+ one<char> ()
+ {
+ return "1";
+ }
+
+ //
+ //
+ template<>
+ inline const char*
+ not_present<char> ()
+ {
+ return "<not present>";
+ }
+
+ //
+ //
+ template <>
+ inline const char*
+ xml_schema<char> ()
+ {
+ return "http://www.w3.org/2001/XMLSchema";
+ }
+
+ //
+ //
+ template <>
+ inline const char*
+ any_type<char> ()
+ {
+ return "anyType";
+ }
+
+ template <>
+ inline const char*
+ any_simple_type<char> ()
+ {
+ return "anySimpleType";
+ }
+
+ template <>
+ inline const char*
+ string<char> ()
+ {
+ return "string";
+ }
+
+ template <>
+ inline const char*
+ normalized_string<char> ()
+ {
+ return "normalizedString";
+ }
+
+ template <>
+ inline const char*
+ token<char> ()
+ {
+ return "token";
+ }
+
+ template <>
+ inline const char*
+ name<char> ()
+ {
+ return "Name";
+ }
+
+ template <>
+ inline const char*
+ nmtoken<char> ()
+ {
+ return "NMTOKEN";
+ }
+
+ template <>
+ inline const char*
+ nmtokens<char> ()
+ {
+ return "NMTOKENS";
+ }
+
+ template <>
+ inline const char*
+ ncname<char> ()
+ {
+ return "NCName";
+ }
+
+ template <>
+ inline const char*
+ language<char> ()
+ {
+ return "language";
+ }
+
+
+ template <>
+ inline const char*
+ id<char> ()
+ {
+ return "ID";
+ }
+
+ template <>
+ inline const char*
+ idref<char> ()
+ {
+ return "IDREF";
+ }
+
+ template <>
+ inline const char*
+ idrefs<char> ()
+ {
+ return "IDREFS";
+ }
+
+ template <>
+ inline const char*
+ any_uri<char> ()
+ {
+ return "anyURI";
+ }
+
+ template <>
+ inline const char*
+ qname<char> ()
+ {
+ return "QName";
+ }
+
+ template <>
+ inline const char*
+ base64_binary<char> ()
+ {
+ return "base64Binary";
+ }
+
+ template <>
+ inline const char*
+ hex_binary<char> ()
+ {
+ return "hexBinary";
+ }
+
+ template <>
+ inline const char*
+ date<char> ()
+ {
+ return "date";
+ }
+
+ template <>
+ inline const char*
+ date_time<char> ()
+ {
+ return "dateTime";
+ }
+
+ template <>
+ inline const char*
+ duration<char> ()
+ {
+ return "duration";
+ }
+
+ template <>
+ inline const char*
+ gday<char> ()
+ {
+ return "gDay";
+ }
+
+ template <>
+ inline const char*
+ gmonth<char> ()
+ {
+ return "gMonth";
+ }
+
+ template <>
+ inline const char*
+ gmonth_day<char> ()
+ {
+ return "gMonthDay";
+ }
+
+ template <>
+ inline const char*
+ gyear<char> ()
+ {
+ return "gYear";
+ }
+
+ template <>
+ inline const char*
+ gyear_month<char> ()
+ {
+ return "gYearMonth";
+ }
+
+ template <>
+ inline const char*
+ time<char> ()
+ {
+ return "time";
+ }
+
+ template <>
+ inline const char*
+ entity<char> ()
+ {
+ return "ENTITY";
+ }
+
+ template <>
+ inline const char*
+ entities<char> ()
+ {
+ return "ENTITIES";
+ }
+
+ template <>
+ inline const char*
+ gday_prefix<char> ()
+ {
+ return "---";
+ }
+
+ template <>
+ inline const char*
+ gmonth_prefix<char> ()
+ {
+ return "--";
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_BITS_LITERALS_IXX_CHAR
+#endif // XSD_CXX_TREE_USE_CHAR
+
+
+#if defined(XSD_CXX_TREE_USE_WCHAR) || !defined(XSD_CXX_TREE_USE_CHAR)
+
+#ifndef XSD_CXX_TREE_BITS_LITERALS_IXX_WCHAR
+#define XSD_CXX_TREE_BITS_LITERALS_IXX_WCHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ namespace bits
+ {
+ //
+ //
+ template<>
+ inline const wchar_t*
+ true_<wchar_t> ()
+ {
+ return L"true";
+ }
+
+ template<>
+ inline const wchar_t*
+ one<wchar_t> ()
+ {
+ return L"1";
+ }
+
+ //
+ //
+ template<>
+ inline const wchar_t*
+ positive_inf<wchar_t> ()
+ {
+ return L"INF";
+ }
+
+ template<>
+ inline const wchar_t*
+ negative_inf<wchar_t> ()
+ {
+ return L"-INF";
+ }
+
+ template<>
+ inline const wchar_t*
+ nan<wchar_t> ()
+ {
+ return L"NaN";
+ }
+
+ //
+ //
+ template<>
+ inline const wchar_t*
+ not_present<wchar_t> ()
+ {
+ return L"<not present>";
+ }
+
+ //
+ //
+ template <>
+ inline const wchar_t*
+ xml_schema<wchar_t> ()
+ {
+ return L"http://www.w3.org/2001/XMLSchema";
+ }
+
+ //
+ //
+ template <>
+ inline const wchar_t*
+ any_type<wchar_t> ()
+ {
+ return L"anyType";
+ }
+
+ template <>
+ inline const wchar_t*
+ any_simple_type<wchar_t> ()
+ {
+ return L"anySimpleType";
+ }
+
+ template <>
+ inline const wchar_t*
+ string<wchar_t> ()
+ {
+ return L"string";
+ }
+
+ template <>
+ inline const wchar_t*
+ normalized_string<wchar_t> ()
+ {
+ return L"normalizedString";
+ }
+
+ template <>
+ inline const wchar_t*
+ token<wchar_t> ()
+ {
+ return L"token";
+ }
+
+ template <>
+ inline const wchar_t*
+ name<wchar_t> ()
+ {
+ return L"Name";
+ }
+
+ template <>
+ inline const wchar_t*
+ nmtoken<wchar_t> ()
+ {
+ return L"NMTOKEN";
+ }
+
+ template <>
+ inline const wchar_t*
+ nmtokens<wchar_t> ()
+ {
+ return L"NMTOKENS";
+ }
+
+ template <>
+ inline const wchar_t*
+ ncname<wchar_t> ()
+ {
+ return L"NCName";
+ }
+
+ template <>
+ inline const wchar_t*
+ language<wchar_t> ()
+ {
+ return L"language";
+ }
+
+
+ template <>
+ inline const wchar_t*
+ id<wchar_t> ()
+ {
+ return L"ID";
+ }
+
+ template <>
+ inline const wchar_t*
+ idref<wchar_t> ()
+ {
+ return L"IDREF";
+ }
+
+ template <>
+ inline const wchar_t*
+ idrefs<wchar_t> ()
+ {
+ return L"IDREFS";
+ }
+
+ template <>
+ inline const wchar_t*
+ any_uri<wchar_t> ()
+ {
+ return L"anyURI";
+ }
+
+ template <>
+ inline const wchar_t*
+ qname<wchar_t> ()
+ {
+ return L"QName";
+ }
+
+ template <>
+ inline const wchar_t*
+ base64_binary<wchar_t> ()
+ {
+ return L"base64Binary";
+ }
+
+ template <>
+ inline const wchar_t*
+ hex_binary<wchar_t> ()
+ {
+ return L"hexBinary";
+ }
+
+ template <>
+ inline const wchar_t*
+ date<wchar_t> ()
+ {
+ return L"date";
+ }
+
+ template <>
+ inline const wchar_t*
+ date_time<wchar_t> ()
+ {
+ return L"dateTime";
+ }
+
+ template <>
+ inline const wchar_t*
+ duration<wchar_t> ()
+ {
+ return L"duration";
+ }
+
+ template <>
+ inline const wchar_t*
+ gday<wchar_t> ()
+ {
+ return L"gDay";
+ }
+
+ template <>
+ inline const wchar_t*
+ gmonth<wchar_t> ()
+ {
+ return L"gMonth";
+ }
+
+ template <>
+ inline const wchar_t*
+ gmonth_day<wchar_t> ()
+ {
+ return L"gMonthDay";
+ }
+
+ template <>
+ inline const wchar_t*
+ gyear<wchar_t> ()
+ {
+ return L"gYear";
+ }
+
+ template <>
+ inline const wchar_t*
+ gyear_month<wchar_t> ()
+ {
+ return L"gYearMonth";
+ }
+
+ template <>
+ inline const wchar_t*
+ time<wchar_t> ()
+ {
+ return L"time";
+ }
+
+ template <>
+ inline const wchar_t*
+ entity<wchar_t> ()
+ {
+ return L"ENTITY";
+ }
+
+ template <>
+ inline const wchar_t*
+ entities<wchar_t> ()
+ {
+ return L"ENTITIES";
+ }
+
+ template <>
+ inline const wchar_t*
+ gday_prefix<wchar_t> ()
+ {
+ return L"---";
+ }
+
+ template <>
+ inline const wchar_t*
+ gmonth_prefix<wchar_t> ()
+ {
+ return L"--";
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_BITS_LITERALS_IXX_WCHAR
+#endif // XSD_CXX_TREE_USE_WCHAR
diff --git a/libxsd/xsd/cxx/tree/buffer.hxx b/libxsd/xsd/cxx/tree/buffer.hxx
new file mode 100644
index 0000000..f611fe6
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/buffer.hxx
@@ -0,0 +1,336 @@
+// file : xsd/cxx/tree/buffer.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+/**
+ * @file
+ *
+ * @brief Contains a simple binary buffer abstraction that is used to
+ * implement the base64Binary and hexBinary XML Schema built-in types.
+ *
+ * This is an internal header and is included by the generated code. You
+ * normally should not include it directly.
+ *
+ */
+
+#ifndef XSD_CXX_TREE_BUFFER_HXX
+#define XSD_CXX_TREE_BUFFER_HXX
+
+#include <new> // operator new/delete
+#include <cstddef> // std::size_t
+#include <cstring> // std::memcpy, std::memcmp
+
+#include <xsd/cxx/tree/exceptions.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ /**
+ * @brief C++/Tree mapping runtime namespace.
+ *
+ * This is an internal namespace and normally should not be referenced
+ * directly. Instead you should use the aliases for types in this
+ * namespaces that are created in the generated code.
+ *
+ */
+ namespace tree
+ {
+ //@cond
+
+ class buffer_base
+ {
+ protected:
+ virtual
+ ~buffer_base ()
+ {
+ if (data_)
+ operator delete (data_);
+ }
+
+ buffer_base ()
+ : data_ (0), size_ (0), capacity_ (0)
+ {
+ }
+
+ protected:
+ char* data_;
+ size_t size_;
+ size_t capacity_;
+ };
+
+ //@endcond
+
+ /**
+ * @brief Simple binary %buffer abstraction
+ *
+ * The %buffer class manages a continuous binary %buffer. The base
+ * concepts are data (actual memory region), size (the portion of
+ * the %buffer that contains useful information), and capacity (the
+ * actual size of the underlying memory region). The bounds
+ * %exception is thrown from the constructors and modifier functions
+ * if the (size <= capacity) constraint is violated.
+ *
+ * Note that the template parameter is only used to instantiate
+ * %exception types. The underlying %buffer type is always @c char.
+ *
+ * @nosubgrouping
+ */
+ template<typename C>
+ class buffer: protected buffer_base
+ {
+ public:
+ /**
+ * @brief Size type
+ */
+ typedef std::size_t size_t;
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Allocate a %buffer of the specified size.
+ *
+ * The resulting %buffer has the same size and capacity.
+ *
+ * @param size A %buffer size in bytes.
+ */
+ explicit
+ buffer (size_t size = 0);
+
+ /**
+ * @brief Allocate a %buffer of the specified size and capacity.
+ *
+ * @param size A %buffer size in bytes.
+ * @param capacity A %buffer capacity in bytes.
+ * @throw bounds If @a size exceeds @a capacity
+ */
+ buffer (size_t size, size_t capacity);
+
+ /**
+ * @brief Allocate a %buffer of the specified size and copy
+ * the data.
+ *
+ * The resulting %buffer has the same size and capacity with
+ * @a size bytes copied from @a data.
+ *
+ * @param data A %buffer to copy the data from.
+ * @param size A %buffer size in bytes.
+ */
+ buffer (const void* data, size_t size);
+
+ /**
+ * @brief Allocate a %buffer of the specified size and capacity
+ * and copy the data.
+ *
+ * @a size bytes are copied from @a data to the resulting
+ * %buffer.
+ *
+ * @param data A %buffer to copy the data from.
+ * @param size A %buffer size in bytes.
+ * @param capacity A %buffer capacity in bytes.
+ * @throw bounds If @a size exceeds @a capacity
+ */
+ buffer (const void* data, size_t size, size_t capacity);
+
+ /**
+ * @brief Assume ownership of the specified %buffer.
+ *
+ * If the @a assume_ownership argument is true, the %buffer will
+ * assume ownership of @a data and will release the memory
+ * by calling @c operator @c delete().
+ *
+ * @param data A %buffer to assume ownership of.
+ * @param size A %buffer size in bytes.
+ * @param capacity A %buffer capacity in bytes.
+ * @param assume_ownership A boolean value indication whether to
+ * assume ownership.
+ * @throw bounds If @a size exceeds @a capacity
+ */
+ buffer (void* data,
+ size_t size,
+ size_t capacity,
+ bool assume_ownership);
+
+ /**
+ * @brief Copy constructor.
+ *
+ * The copy constructor performs a deep copy of the underlying
+ * memory %buffer.
+ *
+ * @param x An instance to make a copy of.
+ */
+ buffer (const buffer& x);
+
+ //@}
+
+ public:
+ /**
+ * @brief Copy assignment operator.
+ *
+ * The copy assignment operator changes the buffer's capacity
+ * to @c x.capacity() and copies @c x.size() bytes from @a x.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ buffer&
+ operator= (const buffer& x);
+
+ public:
+ /**
+ * @brief Get buffer's capacity.
+ *
+ * @return A number of bytes that the %buffer can hold without
+ * reallocation.
+ */
+ size_t
+ capacity () const
+ {
+ return capacity_;
+ }
+
+ /**
+ * @brief Set buffer's capacity.
+ *
+ * @param c The new capacity in bytes.
+ * @return True if the underlying %buffer has moved, false otherwise.
+ */
+ bool
+ capacity (size_t c)
+ {
+ return this->capacity (c, true);
+ }
+
+ public:
+ /**
+ * @brief Get buffer's size.
+ *
+ * @return A number of bytes that the %buffer holds.
+ */
+ size_t
+ size () const {return size_;}
+
+ /**
+ * @brief Set buffer's size.
+ *
+ * @param s The new size in bytes.
+ * @return True if the underlying %buffer has moved, false otherwise.
+ */
+ bool
+ size (size_t s)
+ {
+ bool r (false);
+
+ if (s > capacity_)
+ r = capacity (s);
+
+ size_ = s;
+
+ return r;
+ }
+
+ public:
+ /**
+ * @brief Get the underlying memory region.
+ *
+ * @return A constant pointer to the underlying memory region.
+ */
+ const char*
+ data () const {return data_;}
+
+ /**
+ * @brief Get the underlying memory region.
+ *
+ * @return A pointer to the underlying memory region.
+ */
+ char*
+ data () {return data_;}
+
+ /**
+ * @brief Get the beginning of the underlying memory region.
+ *
+ * @return A constant pointer to the first byte of the underlying
+ * memory region.
+ */
+ const char*
+ begin () const {return data_;}
+
+ /**
+ * @brief Get the beginning of the underlying memory region.
+ *
+ * @return A pointer to the first byte of the underlying memory
+ * region.
+ */
+ char*
+ begin () {return data_;}
+
+ /**
+ * @brief Get the end of the underlying memory region.
+ *
+ * @return A constant pointer to the one past last byte of the
+ * underlying memory region (that is @c %begin() @c + @c %size() ).
+ */
+ const char*
+ end () const {return data_ + size_;}
+
+ /**
+ * @brief Get the end of the underlying memory region.
+ *
+ * @return A pointer to the one past last byte of the underlying
+ * memory region (that is @c %begin() @c + @c %size() ).
+ */
+ char*
+ end () {return data_ + size_;}
+
+ public:
+ /**
+ * @brief Swap data with another %buffer.
+ *
+ * @param x A %buffer to swap with.
+ */
+ void
+ swap (buffer& x);
+
+ private:
+ bool
+ capacity (size_t capacity, bool copy);
+ };
+
+ /**
+ * @brief %buffer comparison operator.
+ *
+ * @return True if the buffers have the same sizes and the same
+ * data.
+ */
+ template <typename C>
+ inline bool
+ operator== (const buffer<C>& a, const buffer<C>& b)
+ {
+ return a.size () == b.size () &&
+ std::memcmp (a.data (), b.data (), a.size ()) == 0;
+ }
+
+ /**
+ * @brief %buffer comparison operator.
+ *
+ * @return True if the buffers have different sizes or different
+ * data.
+ */
+ template <typename C>
+ inline bool
+ operator!= (const buffer<C>& a, const buffer<C>& b)
+ {
+ return !(a == b);
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/tree/buffer.txx>
+
+#endif // XSD_CXX_TREE_BUFFER_HXX
diff --git a/libxsd/xsd/cxx/tree/buffer.txx b/libxsd/xsd/cxx/tree/buffer.txx
new file mode 100644
index 0000000..6212e20
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/buffer.txx
@@ -0,0 +1,153 @@
+// file : xsd/cxx/tree/buffer.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ buffer<C>::
+ buffer (size_t size)
+ {
+ capacity (size);
+ size_ = size;
+ }
+
+ template <typename C>
+ buffer<C>::
+ buffer (size_t size, size_t capacity)
+ {
+ if (size > capacity)
+ throw bounds<C> ();
+
+ this->capacity (capacity);
+ size_ = size;
+ }
+
+ template <typename C>
+ buffer<C>::
+ buffer (const void* data, size_t size)
+ {
+ capacity (size);
+ size_ = size;
+
+ if (size_)
+ std::memcpy (data_, data, size_);
+ }
+
+ template <typename C>
+ buffer<C>::
+ buffer (const void* data, size_t size, size_t capacity)
+ {
+ if (size > capacity)
+ throw bounds<C> ();
+
+ this->capacity (capacity);
+ size_ = size;
+
+ if (size_)
+ std::memcpy (data_, data, size_);
+ }
+
+ template <typename C>
+ buffer<C>::
+ buffer (void* data, size_t size, size_t capacity, bool own)
+ {
+ if (size > capacity)
+ throw bounds<C> ();
+
+ if (own)
+ {
+ data_ = reinterpret_cast<char*> (data);
+ size_ = size;
+ capacity_ = capacity;
+ }
+ else
+ {
+ this->capacity (capacity);
+ size_ = size;
+
+ if (size_)
+ std::memcpy (data_, data, size_);
+ }
+ }
+
+ template <typename C>
+ buffer<C>::
+ buffer (const buffer& other)
+ : buffer_base ()
+ {
+ capacity (other.capacity_);
+ size_ = other.size_;
+
+ if (size_)
+ std::memcpy (data_, other.data_, size_);
+ }
+
+ template <typename C>
+ buffer<C>& buffer<C>::
+ operator= (const buffer& other)
+ {
+ if (this != &other)
+ {
+ capacity (other.capacity_, false);
+ size_ = other.size_;
+
+ if (size_)
+ std::memcpy (data_, other.data_, size_);
+ }
+
+ return *this;
+ }
+
+ template <typename C>
+ void buffer<C>::
+ swap (buffer& other)
+ {
+ char* tmp_data (data_);
+ size_t tmp_size (size_);
+ size_t tmp_capacity (capacity_);
+
+ data_ = other.data_;
+ size_ = other.size_;
+ capacity_ = other.capacity_;
+
+ other.data_ = tmp_data;
+ other.size_ = tmp_size;
+ other.capacity_ = tmp_capacity;
+ }
+
+ template <typename C>
+ bool buffer<C>::
+ capacity (size_t capacity, bool copy)
+ {
+ if (size_ > capacity)
+ throw bounds<C> ();
+
+ if (capacity <= capacity_)
+ {
+ return false; // Do nothing if shrinking is requested.
+ }
+ else
+ {
+ char* data (reinterpret_cast<char*> (operator new (capacity)));
+
+ if (copy && size_ > 0)
+ std::memcpy (data, data_, size_);
+
+ if (data_)
+ operator delete (data_);
+
+ data_ = data;
+ capacity_ = capacity;
+
+ return true;
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/comparison-map.hxx b/libxsd/xsd/cxx/tree/comparison-map.hxx
new file mode 100644
index 0000000..f8461a0
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/comparison-map.hxx
@@ -0,0 +1,109 @@
+// file : xsd/cxx/tree/comparison-map.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_COMPARISON_MAP_HXX
+#define XSD_CXX_TREE_COMPARISON_MAP_HXX
+
+#include <map>
+#include <cstddef> // std::size_t
+#include <typeinfo>
+
+#include <xsd/cxx/tree/elements.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct comparison_map
+ {
+ typedef std::type_info type_id;
+ typedef bool (*comparator) (const type&, const type&);
+
+ comparison_map ();
+
+ void
+ register_type (const type_id&, comparator, bool override = true);
+
+ bool
+ compare (const type&, const type&);
+
+ public:
+ comparator
+ find (const type_id&) const;
+
+ private:
+ struct type_id_comparator
+ {
+ bool
+ operator() (const type_id* x, const type_id* y) const
+ {
+ // XL C++ on AIX has buggy type_info::before() in that
+ // it returns true for two different type_info objects
+ // that happened to be for the same type.
+ //
+#if defined(__xlC__) && defined(_AIX)
+ return *x != *y && x->before (*y);
+#else
+ return x->before (*y);
+#endif
+ }
+ };
+
+ typedef
+ std::map<const type_id*, comparator, type_id_comparator>
+ type_map;
+
+ type_map type_map_;
+ };
+
+ //
+ //
+ template<unsigned long id, typename C>
+ struct comparison_plate
+ {
+ static comparison_map<C>* map;
+ static std::size_t count;
+
+ comparison_plate ();
+ ~comparison_plate ();
+ };
+
+ template<unsigned long id, typename C>
+ comparison_map<C>* comparison_plate<id, C>::map = 0;
+
+ template<unsigned long id, typename C>
+ std::size_t comparison_plate<id, C>::count = 0;
+
+
+ //
+ //
+ template<unsigned long id, typename C>
+ inline comparison_map<C>&
+ comparison_map_instance ()
+ {
+ return *comparison_plate<id, C>::map;
+ }
+
+ //
+ //
+ template<typename T>
+ bool
+ comparator_impl (const type&, const type&);
+
+ template<unsigned long id, typename C, typename T>
+ struct comparison_initializer
+ {
+ comparison_initializer ();
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/tree/comparison-map.txx>
+
+#endif // XSD_CXX_TREE_COMPARISON_MAP_HXX
diff --git a/libxsd/xsd/cxx/tree/comparison-map.txx b/libxsd/xsd/cxx/tree/comparison-map.txx
new file mode 100644
index 0000000..38f215f
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/comparison-map.txx
@@ -0,0 +1,287 @@
+// file : xsd/cxx/tree/comparison-map.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd/cxx/tree/types.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // comparison_map
+ //
+ template <typename C>
+ comparison_map<C>::
+ comparison_map ()
+ {
+ // anyType and anySimpleType.
+ //
+
+ //register_type (
+ // typeid (type),
+ // &comparator_impl<type>,
+ // false);
+
+ typedef simple_type<type> simple_type;
+
+ //register_type (
+ // typeid (simple_type),
+ // &comparator_impl<simple_type>,
+ // false);
+
+
+ // Strings
+ //
+ typedef string<C, simple_type> string;
+ register_type (
+ typeid (string),
+ &comparator_impl<string>,
+ false);
+
+ typedef normalized_string<C, string> normalized_string;
+ register_type (
+ typeid (normalized_string),
+ &comparator_impl<normalized_string>,
+ false);
+
+ typedef token<C, normalized_string> token;
+ register_type (
+ typeid (token),
+ &comparator_impl<token>,
+ false);
+
+ typedef name<C, token> name;
+ register_type (
+ typeid (name),
+ &comparator_impl<name>,
+ false);
+
+ typedef nmtoken<C, token> nmtoken;
+ register_type (
+ typeid (nmtoken),
+ &comparator_impl<nmtoken>,
+ false);
+
+ typedef nmtokens<C, simple_type, nmtoken> nmtokens;
+ register_type (
+ typeid (nmtokens),
+ &comparator_impl<nmtokens>,
+ false);
+
+ typedef ncname<C, name> ncname;
+ register_type (
+ typeid (ncname),
+ &comparator_impl<ncname>,
+ false);
+
+ typedef language<C, token> language;
+ register_type (
+ typeid (language),
+ &comparator_impl<language>,
+ false);
+
+
+ // ID/IDREF.
+ //
+ typedef id<C, ncname> id;
+ register_type (
+ typeid (id),
+ &comparator_impl<id>,
+ false);
+
+ typedef idref<type, C, ncname> idref;
+ register_type (
+ typeid (idref),
+ &comparator_impl<idref>,
+ false);
+
+ typedef idrefs<C, simple_type, idref> idrefs;
+ register_type (
+ typeid (idrefs),
+ &comparator_impl<idrefs>,
+ false);
+
+
+ // URI.
+ //
+ typedef uri<C, simple_type> uri;
+ register_type (
+ typeid (uri),
+ &comparator_impl<uri>,
+ false);
+
+
+ // Qualified name.
+ //
+ typedef qname<C, simple_type, uri, ncname> qname;
+ register_type (
+ typeid (qname),
+ &comparator_impl<qname>,
+ false);
+
+
+ // Binary.
+ //
+ typedef base64_binary<C, simple_type> base64_binary;
+ register_type (
+ typeid (base64_binary),
+ &comparator_impl<base64_binary>,
+ false);
+
+ typedef hex_binary<C, simple_type> hex_binary;
+ register_type (
+ typeid (hex_binary),
+ &comparator_impl<hex_binary>,
+ false);
+
+
+ // Date/time.
+ //
+ typedef gday<C, simple_type> gday;
+ register_type (
+ typeid (gday),
+ &comparator_impl<gday>,
+ false);
+
+ typedef gmonth<C, simple_type> gmonth;
+ register_type (
+ typeid (gmonth),
+ &comparator_impl<gmonth>,
+ false);
+
+ typedef gyear<C, simple_type> gyear;
+ register_type (
+ typeid (gyear),
+ &comparator_impl<gyear>,
+ false);
+
+ typedef gmonth_day<C, simple_type> gmonth_day;
+ register_type (
+ typeid (gmonth_day),
+ &comparator_impl<gmonth_day>,
+ false);
+
+ typedef gyear_month<C, simple_type> gyear_month;
+ register_type (
+ typeid (gyear_month),
+ &comparator_impl<gyear_month>,
+ false);
+
+ typedef date<C, simple_type> date;
+ register_type (
+ typeid (date),
+ &comparator_impl<date>,
+ false);
+
+ typedef time<C, simple_type> time;
+ register_type (
+ typeid (time),
+ &comparator_impl<time>,
+ false);
+
+ typedef date_time<C, simple_type> date_time;
+ register_type (
+ typeid (date_time),
+ &comparator_impl<date_time>,
+ false);
+
+ typedef duration<C, simple_type> duration;
+ register_type (
+ typeid (duration),
+ &comparator_impl<duration>,
+ false);
+
+
+ // Entity.
+ //
+ typedef entity<C, ncname> entity;
+ register_type (
+ typeid (entity),
+ &comparator_impl<entity>,
+ false);
+
+ typedef entities<C, simple_type, entity> entities;
+ register_type (
+ typeid (entities),
+ &comparator_impl<entities>,
+ false);
+ }
+
+ template <typename C>
+ void comparison_map<C>::
+ register_type (const type_id& tid, comparator c, bool override)
+ {
+ if (override || type_map_.find (&tid) == type_map_.end ())
+ type_map_[&tid] = c;
+ }
+
+ template <typename C>
+ bool comparison_map<C>::
+ compare (const type& x, const type& y)
+ {
+ const type_id& xi (typeid (x));
+
+ if (xi != typeid (y))
+ return false;
+
+ if (comparator c = find (xi))
+ return c (x, y);
+ else
+ throw no_type_info<C> (std::basic_string<C> (),
+ std::basic_string<C> ()); // @@ TODO
+ }
+
+ template <typename C>
+ typename comparison_map<C>::comparator
+ comparison_map<C>::
+ find (const type_id& tid) const
+ {
+ typename type_map::const_iterator i (type_map_.find (&tid));
+ return i == type_map_.end () ? 0 : i->second;
+ }
+
+
+ // comparison_plate
+ //
+ template<unsigned long id, typename C>
+ comparison_plate<id, C>::
+ comparison_plate ()
+ {
+ if (count == 0)
+ map = new comparison_map<C>;
+
+ ++count;
+ }
+
+ template<unsigned long id, typename C>
+ comparison_plate<id, C>::
+ ~comparison_plate ()
+ {
+ if (--count == 0)
+ delete map;
+ }
+
+ //
+ //
+ template<typename T>
+ bool
+ comparator_impl (const type& x, const type& y)
+ {
+ return static_cast<const T&> (x) == static_cast<const T&> (y);
+ }
+
+ // comparison_initializer
+ //
+ template<unsigned long id, typename C, typename T>
+ comparison_initializer<id, C, T>::
+ comparison_initializer ()
+ {
+ comparison_map_instance<id, C> ().register_type (
+ typeid (T), &comparator_impl<T>);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/containers-wildcard.hxx b/libxsd/xsd/cxx/tree/containers-wildcard.hxx
new file mode 100644
index 0000000..53c0d22
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/containers-wildcard.hxx
@@ -0,0 +1,1335 @@
+// file : xsd/cxx/tree/containers-wildcard.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_CONTAINERS_WILDCARD_HXX
+#define XSD_CXX_TREE_CONTAINERS_WILDCARD_HXX
+
+#include <set>
+#include <string>
+
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMElement.hpp>
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xercesc/util/XMLString.hpp>
+
+#include <xsd/cxx/xml/string.hxx>
+
+#include <xsd/cxx/tree/containers.hxx> // iterator_adapter
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // one (for internal use only)
+ //
+ class element_one
+ {
+ public:
+ ~element_one ()
+ {
+ if (x_)
+ x_->release ();
+ }
+
+ explicit
+ element_one (xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ }
+
+ element_one (const xercesc::DOMElement& x, xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ set (x);
+ }
+
+ element_one (const element_one& x, xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ if (x.present ())
+ set (x.get ());
+ }
+
+ element_one&
+ operator= (const element_one& x)
+ {
+ if (this == &x)
+ return *this;
+
+ if (x.present ())
+ set (x.get ());
+ else if (x_)
+ {
+ x_->release ();
+ x_ = 0;
+ }
+
+ return *this;
+ }
+
+ public:
+ const xercesc::DOMElement&
+ get () const
+ {
+ return *x_;
+ }
+
+ xercesc::DOMElement&
+ get ()
+ {
+ return *x_;
+ }
+
+ void
+ set (const xercesc::DOMElement& x)
+ {
+ using xercesc::DOMElement;
+
+ DOMElement* r (
+ static_cast<DOMElement*> (
+ doc_.importNode (const_cast<DOMElement*> (&x), true)));
+
+ if (x_)
+ x_->release ();
+
+ x_ = r;
+ }
+
+ void
+ set (xercesc::DOMElement* x)
+ {
+ assert (x->getOwnerDocument () == &doc_);
+
+ if (x_)
+ x_->release ();
+
+ x_ = x;
+ }
+
+ bool
+ present () const
+ {
+ return x_ != 0;
+ }
+
+ protected:
+ xercesc::DOMElement* x_;
+ xercesc::DOMDocument& doc_;
+ };
+
+
+ //
+ //
+ class element_optional
+ {
+ public:
+ ~element_optional ()
+ {
+ if (x_)
+ x_->release ();
+ }
+
+ explicit
+ element_optional (xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ }
+
+ element_optional (const xercesc::DOMElement& x,
+ xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ set (x);
+ }
+
+ element_optional (xercesc::DOMElement* x, xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ set (x);
+ }
+
+ element_optional (const element_optional& x,
+ xercesc::DOMDocument& doc)
+ : x_ (0), doc_ (doc)
+ {
+ if (x)
+ set (*x);
+ }
+
+ element_optional&
+ operator= (const xercesc::DOMElement& x)
+ {
+ if (x_ == &x)
+ return *this;
+
+ set (x);
+
+ return *this;
+ }
+
+ element_optional&
+ operator= (const element_optional& x)
+ {
+ if (this == &x)
+ return *this;
+
+ if (x)
+ set (*x);
+ else
+ reset ();
+
+ return *this;
+ }
+
+ // Pointer-like interface.
+ //
+ public:
+ const xercesc::DOMElement*
+ operator-> () const
+ {
+ return x_;
+ }
+
+ xercesc::DOMElement*
+ operator-> ()
+ {
+ return x_;
+ }
+
+ const xercesc::DOMElement&
+ operator* () const
+ {
+ return *x_;
+ }
+
+ xercesc::DOMElement&
+ operator* ()
+ {
+ return *x_;
+ }
+
+ typedef void (element_optional::*bool_convertible) ();
+
+ operator bool_convertible () const
+ {
+ return x_ != 0 ? &element_optional::true_ : 0;
+ }
+
+ // Get/set interface.
+ //
+ public:
+ bool
+ present () const
+ {
+ return x_ != 0;
+ }
+
+ const xercesc::DOMElement&
+ get () const
+ {
+ return *x_;
+ }
+
+ xercesc::DOMElement&
+ get ()
+ {
+ return *x_;
+ }
+
+ void
+ set (const xercesc::DOMElement& x)
+ {
+ using xercesc::DOMElement;
+
+ DOMElement* r (
+ static_cast<DOMElement*> (
+ doc_.importNode (const_cast<DOMElement*> (&x), true)));
+
+ if (x_)
+ x_->release ();
+
+ x_ = r;
+ }
+
+ void
+ set (xercesc::DOMElement* x)
+ {
+ assert (x->getOwnerDocument () == &doc_);
+
+ if (x_)
+ x_->release ();
+
+ x_ = x;
+ }
+
+ void
+ reset ()
+ {
+ if (x_)
+ x_->release ();
+
+ x_ = 0;
+ }
+
+ private:
+ void
+ true_ ()
+ {
+ }
+
+ private:
+ xercesc::DOMElement* x_;
+ xercesc::DOMDocument& doc_;
+ };
+
+ // Comparison operators.
+ //
+
+ inline bool
+ operator== (const element_optional& a, const element_optional& b)
+ {
+ return !a || !b
+ ? a.present () == b.present ()
+ : a->isEqualNode (&b.get ());
+ }
+
+ inline bool
+ operator!= (const element_optional& a, const element_optional& b)
+ {
+ return !(a == b);
+ }
+
+
+ //
+ //
+ class element_sequence
+ {
+ protected:
+ // This is a dangerously destructive automatic pointer. We are going
+ // to use it in a controlled environment to save us a lot of coding.
+ //
+ struct ptr
+ {
+ ~ptr ()
+ {
+ if (x_)
+ x_->release ();
+ }
+
+ explicit
+ ptr (xercesc::DOMElement* x = 0)
+ : x_ (x)
+ {
+ }
+
+ ptr (const ptr& y)
+ : x_ (y.x_)
+ {
+ // Yes, hostile takeover.
+ //
+ y.x_ = 0;
+ }
+
+ ptr&
+ operator= (const ptr& y)
+ {
+ if (this != &y)
+ {
+ // Yes, hostile takeover.
+ //
+ if (x_)
+ x_->release ();
+
+ x_ = y.x_;
+ y.x_ = 0;
+ }
+
+ return *this;
+ }
+
+ public:
+ xercesc::DOMElement&
+ operator* () const
+ {
+ return *x_;
+ }
+
+ xercesc::DOMElement*
+ get () const
+ {
+ return x_;
+ }
+
+ private:
+ mutable xercesc::DOMElement* x_;
+ };
+
+ typedef std::vector<ptr> base_sequence;
+ typedef base_sequence::iterator base_iterator;
+ typedef base_sequence::const_iterator base_const_iterator;
+
+ public:
+ typedef xercesc::DOMElement value_type;
+ typedef xercesc::DOMElement* pointer;
+ typedef const xercesc::DOMElement* const_pointer;
+ typedef xercesc::DOMElement& reference;
+ typedef const xercesc::DOMElement& const_reference;
+
+ typedef
+ iterator_adapter<base_sequence::iterator, xercesc::DOMElement>
+ iterator;
+
+ typedef
+ iterator_adapter<base_sequence::const_iterator,
+ const xercesc::DOMElement>
+ const_iterator;
+
+ typedef
+ iterator_adapter<base_sequence::reverse_iterator, xercesc::DOMElement>
+ reverse_iterator;
+
+ typedef
+ iterator_adapter<base_sequence::const_reverse_iterator,
+ const xercesc::DOMElement>
+ const_reverse_iterator;
+
+ typedef base_sequence::size_type size_type;
+ typedef base_sequence::difference_type difference_type;
+ typedef base_sequence::allocator_type allocator_type;
+
+ public:
+ explicit
+ element_sequence (xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ }
+
+ // DOMElement cannot be default-constructed.
+ //
+ // explicit
+ // element_sequence (size_type n);
+
+ element_sequence (size_type n,
+ const xercesc::DOMElement& x,
+ xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ assign (n, x);
+ }
+
+ template <typename I>
+ element_sequence (const I& begin, const I& end,
+ xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ assign (begin, end);
+ }
+
+ element_sequence (const element_sequence& v,
+ xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ v_.reserve (v.v_.size ());
+
+ for (base_const_iterator i (v.v_.begin ()), e (v.v_.end ());
+ i != e; ++i)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (i->get (), true)));
+
+ v_.push_back (p);
+ }
+ }
+
+ element_sequence&
+ operator= (const element_sequence& v)
+ {
+ if (this == &v)
+ return *this;
+
+ v_.assign (v.v_.size (), ptr ());
+
+ base_iterator di (v_.begin ()), de (v_.end ());
+ base_const_iterator si (v.v_.begin ()), se (v.v_.end ());
+
+ for (; si != se && di != de; ++si, ++di)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (si->get (), true)));
+ *di = p;
+ }
+
+ return *this;
+ }
+
+ public:
+ void
+ assign (size_type n, const xercesc::DOMElement& x)
+ {
+ v_.assign (n, ptr ());
+
+ for (base_iterator i (v_.begin ()), e (v_.end ()); i != e; ++i)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMElement*> (&x), true)));
+ *i = p;
+ }
+ }
+
+ template <typename I>
+ void
+ assign (const I& begin, const I& end)
+ {
+ // This is not the fastest way to do it.
+ //
+ v_.clear ();
+
+ for (I i (begin); i != end; ++i)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMElement*> (&(*i)), true)));
+ v_.push_back (p);
+ }
+ }
+
+ public:
+ // This version of resize can only be used to shrink the
+ // sequence because DOMElement cannot be default-constructed.
+ //
+ void
+ resize (size_type n)
+ {
+ assert (n <= v_.size ());
+ v_.resize (n, ptr ());
+ }
+
+ void
+ resize (size_type n, const xercesc::DOMElement& x)
+ {
+ size_type old (v_.size ());
+ v_.resize (n, ptr ());
+
+ if (old < n)
+ {
+ for (base_iterator i (v_.begin () + old), e (v_.end ());
+ i != e; ++i)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMElement*> (&x), true)));
+ *i = p;
+ }
+ }
+ }
+
+ public:
+ size_type
+ size () const
+ {
+ return v_.size ();
+ }
+
+ size_type
+ max_size () const
+ {
+ return v_.max_size ();
+ }
+
+ size_type
+ capacity () const
+ {
+ return v_.capacity ();
+ }
+
+ bool
+ empty () const
+ {
+ return v_.empty ();
+ }
+
+ void
+ reserve (size_type n)
+ {
+ v_.reserve (n);
+ }
+
+ void
+ clear ()
+ {
+ v_.clear ();
+ }
+
+ public:
+ const_iterator
+ begin () const
+ {
+ return const_iterator (v_.begin ());
+ }
+
+ const_iterator
+ end () const
+ {
+ return const_iterator (v_.end ());
+ }
+
+ iterator
+ begin ()
+ {
+ return iterator (v_.begin ());
+ }
+
+ iterator
+ end ()
+ {
+ return iterator (v_.end ());
+ }
+
+ // reverse
+ //
+
+ const_reverse_iterator
+ rbegin () const
+ {
+ return const_reverse_iterator (v_.rbegin ());
+ }
+
+ const_reverse_iterator
+ rend () const
+ {
+ return const_reverse_iterator (v_.rend ());
+ }
+
+ reverse_iterator
+ rbegin ()
+ {
+ return reverse_iterator (v_.rbegin ());
+ }
+
+ reverse_iterator
+ rend ()
+ {
+ return reverse_iterator (v_.rend ());
+ }
+
+ public:
+ xercesc::DOMElement&
+ operator[] (size_type n)
+ {
+ return *(v_[n]);
+ }
+
+ const xercesc::DOMElement&
+ operator[] (size_type n) const
+ {
+ return *(v_[n]);
+ }
+
+ xercesc::DOMElement&
+ at (size_type n)
+ {
+ return *(v_.at (n));
+ }
+
+ const xercesc::DOMElement&
+ at (size_type n) const
+ {
+ return *(v_.at (n));
+ }
+
+ xercesc::DOMElement&
+ front ()
+ {
+ return *(v_.front ());
+ }
+
+ const xercesc::DOMElement&
+ front () const
+ {
+ return *(v_.front ());
+ }
+
+ xercesc::DOMElement&
+ back ()
+ {
+ return *(v_.back ());
+ }
+
+ const xercesc::DOMElement&
+ back () const
+ {
+ return *(v_.back ());
+ }
+
+ public:
+ // Makes a deep copy.
+ //
+ void
+ push_back (const xercesc::DOMElement& x)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMElement*> (&x), true)));
+
+ v_.push_back (p);
+ }
+
+ // Assumes ownership.
+ //
+ void
+ push_back (xercesc::DOMElement* x)
+ {
+ assert (x->getOwnerDocument () == &doc_);
+ v_.push_back (ptr (x));
+ }
+
+ void
+ pop_back ()
+ {
+ v_.pop_back ();
+ }
+
+ // Makes a deep copy.
+ //
+ iterator
+ insert (iterator position, const xercesc::DOMElement& x)
+ {
+ ptr p (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMElement*> (&x), true)));
+
+ return iterator (v_.insert (position.base (), p));
+ }
+
+ // Assumes ownership.
+ //
+ iterator
+ insert (iterator position, xercesc::DOMElement* x)
+ {
+ assert (x->getOwnerDocument () == &doc_);
+ return iterator (v_.insert (position.base (), ptr (x)));
+ }
+
+ void
+ insert (iterator position, size_type n, const xercesc::DOMElement& x)
+ {
+ difference_type d (v_.end () - position.base ());
+ v_.insert (position.base (), n, ptr ());
+
+ for (base_iterator i (v_.end () - d); n != 0; --n)
+ {
+ ptr r (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMElement*> (&x), true)));
+ *(--i) = r;
+ }
+ }
+
+ template <typename I>
+ void
+ insert (iterator position, const I& begin, const I& end)
+ {
+ // This is not the fastest way to do it.
+ //
+ if (begin != end)
+ {
+ base_iterator p (position.base ());
+
+ for (I i (end);;)
+ {
+ --i;
+ ptr r (static_cast<xercesc::DOMElement*> (
+ doc_.importNode (i->get (), true)));
+
+ p = v_.insert (p, r);
+
+ if (i == begin)
+ break;
+ }
+ }
+ }
+
+ iterator
+ erase (iterator position)
+ {
+ return iterator (v_.erase (position.base ()));
+ }
+
+ iterator
+ erase (iterator begin, iterator end)
+ {
+ return iterator (v_.erase (begin.base (), end.base ()));
+ }
+
+ public:
+ // Note that the DOMDocument object of the two sequences being
+ // swapped should be the same.
+ //
+ void
+ swap (element_sequence& x)
+ {
+ assert (&doc_ == &x.doc_);
+ v_.swap (x.v_);
+ }
+
+ private:
+ base_sequence v_;
+ xercesc::DOMDocument& doc_;
+ };
+
+ // Comparison operators.
+ //
+
+ inline bool
+ operator== (const element_sequence& a, const element_sequence& b)
+ {
+ if (a.size () != b.size ())
+ return false;
+
+ element_sequence::const_iterator
+ ai (a.begin ()), ae (a.end ()), bi (b.begin ());
+
+ for (; ai != ae; ++ai, ++bi)
+ if (!ai->isEqualNode (&(*bi)))
+ return false;
+
+ return true;
+ }
+
+ inline bool
+ operator!= (const element_sequence& a, const element_sequence& b)
+ {
+ return !(a == b);
+ }
+
+
+ // Attribute set.
+ //
+
+ class attribute_set_common
+ {
+ protected:
+ // Set entry. It can either act as a dangerously destructive
+ // automatic pointer for DOMAttr or as an entry containing the
+ // name we are searching for.
+ //
+ struct entry
+ {
+ ~entry ()
+ {
+ if (a_)
+ a_->release ();
+ }
+
+ explicit
+ entry (xercesc::DOMAttr* a)
+ : a_ (a), ns_ (0), name_ (0)
+ {
+ ns_ = a->getNamespaceURI ();
+ name_ = ns_ == 0 ? a->getName () : a->getLocalName ();
+ }
+
+ // Note: uses shallow copy.
+ //
+ explicit
+ entry (const XMLCh* ns, const XMLCh* name)
+ : a_ (0), ns_ (ns), name_ (name)
+ {
+ }
+
+ entry (const entry& y)
+ : a_ (y.a_), ns_ (y.ns_), name_ (y.name_)
+ {
+ // Yes, hostile takeover.
+ //
+ y.a_ = 0;
+ y.ns_ = 0;
+ y.name_ = 0;
+ }
+
+ entry&
+ operator= (const entry& y)
+ {
+ if (this != &y)
+ {
+ // Yes, hostile takeover.
+ //
+ if (a_)
+ a_->release ();
+
+ a_ = y.a_;
+ ns_ = y.ns_;
+ name_ = y.name_;
+
+ y.a_ = 0;
+ y.ns_ = 0;
+ y.name_ = 0;
+ }
+
+ return *this;
+ }
+
+ public:
+ xercesc::DOMAttr&
+ operator* () const
+ {
+ return *a_;
+ }
+
+ xercesc::DOMAttr*
+ get () const
+ {
+ return a_;
+ }
+
+ const XMLCh*
+ ns () const
+ {
+ return ns_;
+ }
+
+ const XMLCh*
+ name () const
+ {
+ return name_;
+ }
+
+ void
+ release ()
+ {
+ a_ = 0;
+ }
+
+ private:
+ mutable xercesc::DOMAttr* a_;
+ mutable const XMLCh* ns_;
+ mutable const XMLCh* name_;
+ };
+
+ struct entry_cmp
+ {
+ bool
+ operator() (const entry& a, const entry& b) const
+ {
+ using xercesc::XMLString;
+
+ const XMLCh* ans (a.ns ());
+ const XMLCh* bns (b.ns ());
+
+ const XMLCh* an (a.name ());
+ const XMLCh* bn (b.name ());
+
+ if (ans == 0)
+ return bns != 0
+ ? true
+ : (XMLString::compareString (an, bn) < 0);
+
+ if (ans != 0 && bns == 0)
+ return false;
+
+ int r (XMLString::compareString (ans, bns));
+
+ return r < 0
+ ? true
+ : (r > 0 ? false : XMLString::compareString (an, bn));
+ }
+ };
+
+ typedef std::set<entry, entry_cmp> base_set;
+ typedef base_set::iterator base_iterator;
+ typedef base_set::const_iterator base_const_iterator;
+ };
+
+ template <typename C>
+ class attribute_set: public attribute_set_common
+ {
+ public:
+ typedef xercesc::DOMAttr key_type;
+ typedef xercesc::DOMAttr value_type;
+ typedef xercesc::DOMAttr* pointer;
+ typedef const xercesc::DOMAttr* const_pointer;
+ typedef xercesc::DOMAttr& reference;
+ typedef const xercesc::DOMAttr& const_reference;
+
+ typedef
+ iterator_adapter<base_set::iterator, xercesc::DOMAttr>
+ iterator;
+
+ typedef
+ iterator_adapter<base_set::const_iterator, const xercesc::DOMAttr>
+ const_iterator;
+
+ typedef
+ iterator_adapter<base_set::reverse_iterator, xercesc::DOMAttr>
+ reverse_iterator;
+
+ typedef
+ iterator_adapter<base_set::const_reverse_iterator,
+ const xercesc::DOMAttr>
+ const_reverse_iterator;
+
+ typedef base_set::size_type size_type;
+ typedef base_set::difference_type difference_type;
+ typedef base_set::allocator_type allocator_type;
+
+ public:
+ attribute_set (xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ }
+
+ template <typename I>
+ attribute_set (const I& begin,
+ const I& end,
+ xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ insert (begin, end);
+ }
+
+ attribute_set (const attribute_set& s, xercesc::DOMDocument& doc)
+ : doc_ (doc)
+ {
+ // Can be done faster with the "hinted" insert.
+ //
+ insert (s.begin (), s.end ());
+ }
+
+ attribute_set&
+ operator= (const attribute_set& s)
+ {
+ if (this == &s)
+ return *this;
+
+ // Can be done faster with the "hinted" insert.
+ //
+ clear ();
+ insert (s.begin (), s.end ());
+
+ return *this;
+ }
+
+ public:
+ const_iterator
+ begin () const
+ {
+ return const_iterator (s_.begin ());
+ }
+
+ const_iterator
+ end () const
+ {
+ return const_iterator (s_.end ());
+ }
+
+ iterator
+ begin ()
+ {
+ return iterator (s_.begin ());
+ }
+
+ iterator
+ end ()
+ {
+ return iterator (s_.end ());
+ }
+
+ // reverse
+ //
+
+ const_reverse_iterator
+ rbegin () const
+ {
+ return const_reverse_iterator (s_.rbegin ());
+ }
+
+ const_reverse_iterator
+ rend () const
+ {
+ return const_reverse_iterator (s_.rend ());
+ }
+
+ reverse_iterator
+ rbegin ()
+ {
+ return reverse_iterator (s_.rbegin ());
+ }
+
+ reverse_iterator
+ rend ()
+ {
+ return reverse_iterator (s_.rend ());
+ }
+
+ public:
+ size_type
+ size () const
+ {
+ return s_.size ();
+ }
+
+ size_type
+ max_size () const
+ {
+ return s_.max_size ();
+ }
+
+ bool
+ empty () const
+ {
+ return s_.empty ();
+ }
+
+ void
+ clear ()
+ {
+ s_.clear ();
+ }
+
+ public:
+ // Makes a deep copy.
+ //
+ std::pair<iterator, bool>
+ insert (const xercesc::DOMAttr& a)
+ {
+ entry e (static_cast<xercesc::DOMAttr*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMAttr*> (&a), true)));
+
+ std::pair<base_iterator, bool> r (s_.insert (e));
+
+ return std::pair<iterator, bool> (iterator (r.first), r.second);
+ }
+
+ // Assumes ownership.
+ //
+ std::pair<iterator, bool>
+ insert (xercesc::DOMAttr* a)
+ {
+ assert (a->getOwnerDocument () == &doc_);
+ entry e (a);
+ std::pair<base_iterator, bool> r (s_.insert (e));
+
+ if (!r.second)
+ e.release (); // Detach the attribute of insert failed.
+
+ return std::pair<iterator, bool> (iterator (r.first), r.second);
+ }
+
+ // Makes a deep copy.
+ //
+ iterator
+ insert (iterator position, const xercesc::DOMAttr& a)
+ {
+ entry e (static_cast<xercesc::DOMAttr*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMAttr*> (&a), true)));
+
+ return iterator (s_.insert (position.base (), e));
+ }
+
+ // Assumes ownership.
+ //
+ iterator
+ insert (iterator position, xercesc::DOMAttr* a)
+ {
+ assert (a->getOwnerDocument () == &doc_);
+ entry e (a);
+ base_iterator r (s_.insert (position.base (), e));
+
+ if (r->get () != a)
+ e.release (); // Detach the attribute of insert failed.
+
+ return iterator (r);
+ }
+
+ template <typename I>
+ void
+ insert (const I& begin, const I& end)
+ {
+ for (I i (begin); i != end; ++i)
+ {
+ entry e (static_cast<xercesc::DOMAttr*> (
+ doc_.importNode (
+ const_cast<xercesc::DOMAttr*> (&(*i)), true)));
+
+ s_.insert (e);
+ }
+ }
+
+ public:
+ void
+ erase (iterator position)
+ {
+ s_.erase (position.base ());
+ }
+
+ size_type
+ erase (const std::basic_string<C>& name)
+ {
+ return s_.erase (entry (0, xml::string (name).c_str ()));
+ }
+
+ size_type
+ erase (const std::basic_string<C>& namespace_,
+ const std::basic_string<C>& name)
+ {
+ return s_.erase (entry (xml::string (namespace_).c_str (),
+ xml::string (name).c_str ()));
+ }
+
+ size_type
+ erase (const XMLCh* name)
+ {
+ return s_.erase (entry (0, name));
+ }
+
+ size_type
+ erase (const XMLCh* namespace_, const XMLCh* name)
+ {
+ return s_.erase (entry (namespace_, name));
+ }
+
+ void
+ erase (iterator begin, iterator end)
+ {
+ s_.erase (begin.base (), end.base ());
+ }
+
+ public:
+ size_type
+ count (const std::basic_string<C>& name) const
+ {
+ return s_.count (entry (0, xml::string (name).c_str ()));
+ }
+
+ size_type
+ count (const std::basic_string<C>& namespace_,
+ const std::basic_string<C>& name) const
+ {
+ return s_.count (entry (xml::string (namespace_).c_str (),
+ xml::string (name).c_str ()));
+ }
+
+ size_type
+ count (const XMLCh* name) const
+ {
+ return s_.count (entry (0, name));
+ }
+
+ size_type
+ count (const XMLCh* namespace_, const XMLCh* name) const
+ {
+ return s_.count (entry (namespace_, name));
+ }
+
+ // find
+ //
+
+ iterator
+ find (const std::basic_string<C>& name)
+ {
+ return iterator (s_.find (entry (0, xml::string (name).c_str ())));
+ }
+
+ iterator
+ find (const std::basic_string<C>& namespace_,
+ const std::basic_string<C>& name)
+ {
+ return iterator (
+ s_.find (entry (xml::string (namespace_).c_str (),
+ xml::string (name).c_str ())));
+ }
+
+ iterator
+ find (const XMLCh* name)
+ {
+ return iterator (s_.find (entry (0, name)));
+ }
+
+ iterator
+ find (const XMLCh* namespace_, const XMLCh* name)
+ {
+ return iterator (s_.find (entry (namespace_, name)));
+ }
+
+ const_iterator
+ find (const std::basic_string<C>& name) const
+ {
+ return const_iterator (
+ s_.find (entry (0, xml::string (name).c_str ())));
+ }
+
+ const_iterator
+ find (const std::basic_string<C>& namespace_,
+ const std::basic_string<C>& name) const
+ {
+ return const_iterator (
+ s_.find (entry (xml::string (namespace_).c_str (),
+ xml::string (name).c_str ())));
+ }
+
+ const_iterator
+ find (const XMLCh* name) const
+ {
+ return const_iterator (s_.find (entry (0, name)));
+ }
+
+ const_iterator
+ find (const XMLCh* namespace_, const XMLCh* name) const
+ {
+ return const_iterator (s_.find (entry (namespace_, name)));
+ }
+
+ public:
+ // Note that the DOMDocument object of the two sets being
+ // swapped should be the same.
+ //
+ void
+ swap (attribute_set& x)
+ {
+ assert (&doc_ == &x.doc_);
+ s_.swap (x.s_);
+ }
+
+ private:
+ base_set s_;
+ xercesc::DOMDocument& doc_;
+ };
+
+ // Comparison operators.
+ //
+
+ template <typename C>
+ inline bool
+ operator== (const attribute_set<C>& a, const attribute_set<C>& b)
+ {
+ if (a.size () != b.size ())
+ return false;
+
+ typename attribute_set<C>::const_iterator
+ ai (a.begin ()), ae (a.end ()), bi (b.begin ());
+
+ for (; ai != ae; ++ai, ++bi)
+ if (!ai->isEqualNode (&(*bi)))
+ return false;
+
+ return true;
+ }
+
+ template <typename C>
+ inline bool
+ operator!= (const attribute_set<C>& a, const attribute_set<C>& b)
+ {
+ return !(a == b);
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_CONTAINERS_WILDCARD_HXX
diff --git a/libxsd/xsd/cxx/tree/containers.hxx b/libxsd/xsd/cxx/tree/containers.hxx
new file mode 100644
index 0000000..7cb6bd3
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/containers.hxx
@@ -0,0 +1,1398 @@
+// file : xsd/cxx/tree/containers.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_CONTAINERS_HXX
+#define XSD_CXX_TREE_CONTAINERS_HXX
+
+
+#include <cstddef> // std::ptrdiff_t
+#include <string>
+#include <vector>
+#include <memory> // std::auto_ptr
+#include <iterator> // std::iterator_traits
+#include <algorithm> // std::equal, std::lexicographical_compare
+#include <iosfwd>
+
+#include <xsd/cxx/tree/elements.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // Test whether T is a fundamental C++ type.
+ //
+
+ template <typename T>
+ struct fundamental_p
+ {
+ static const bool r = false;
+ };
+
+ // byte
+ //
+ template <>
+ struct fundamental_p<signed char>
+ {
+ static const bool r = true;
+ };
+
+ template <>
+ struct fundamental_p<unsigned char>
+ {
+ static const bool r = true;
+ };
+
+ // short
+ //
+ template <>
+ struct fundamental_p<short>
+ {
+ static const bool r = true;
+ };
+
+ template <>
+ struct fundamental_p<unsigned short>
+ {
+ static const bool r = true;
+ };
+
+ // int
+ //
+ template <>
+ struct fundamental_p<int>
+ {
+ static const bool r = true;
+ };
+
+ template <>
+ struct fundamental_p<unsigned int>
+ {
+ static const bool r = true;
+ };
+
+ // long
+ //
+ template <>
+ struct fundamental_p<long>
+ {
+ static const bool r = true;
+ };
+
+ template <>
+ struct fundamental_p<unsigned long>
+ {
+ static const bool r = true;
+ };
+
+ template <>
+ struct fundamental_p<long long>
+ {
+ static const bool r = true;
+ };
+
+ template <>
+ struct fundamental_p<unsigned long long>
+ {
+ static const bool r = true;
+ };
+
+ // bool
+ //
+ template <>
+ struct fundamental_p<bool>
+ {
+ static const bool r = true;
+ };
+
+ // float
+ //
+ template <>
+ struct fundamental_p<float>
+ {
+ static const bool r = true;
+ };
+
+ template <>
+ struct fundamental_p<double>
+ {
+ static const bool r = true;
+ };
+
+ // one (for internal use only)
+ //
+ template <typename T, bool fund = fundamental_p<T>::r>
+ class one;
+
+ template <typename T>
+ class one<T, false>
+ {
+ public:
+ ~one ();
+
+ one (flags, container*);
+
+ one (const T&, flags, container*);
+
+ one (std::auto_ptr<T>, flags, container*);
+
+ one (const one&, flags, container*);
+
+ one&
+ operator= (const one&);
+
+ public:
+ const T&
+ get () const
+ {
+ return *x_;
+ }
+
+ T&
+ get ()
+ {
+ return *x_;
+ }
+
+ void
+ set (const T&);
+
+ void
+ set (std::auto_ptr<T>);
+
+ bool
+ present () const
+ {
+ return x_ != 0;
+ }
+
+ protected:
+ T* x_;
+ flags flags_;
+ container* container_;
+ };
+
+
+ template <typename T>
+ class one<T, true>
+ {
+ public:
+ one (flags, container*)
+ : present_ (false)
+ {
+ }
+
+ one (const T& x, flags, container*)
+ : x_ (x), present_ (true)
+ {
+ }
+
+ one (const one& x, flags, container*)
+ : x_ (x.x_), present_ (x.present_)
+ {
+ }
+
+ one&
+ operator= (const one& x)
+ {
+ if (this == &x)
+ return *this;
+
+ x_ = x.x_;
+ present_ = x.present_;
+
+ return *this;
+ }
+
+ public:
+ const T&
+ get () const
+ {
+ return x_;
+ }
+
+ T&
+ get ()
+ {
+ return x_;
+ }
+
+ void
+ set (const T& x)
+ {
+ x_ = x;
+ present_ = true;
+ }
+
+ bool
+ present () const
+ {
+ return present_;
+ }
+
+ protected:
+ T x_;
+ bool present_;
+ };
+
+
+ // Note that I cannot get rid of fund because of HP aCC3.
+ //
+ template <typename T, bool fund = fundamental_p<T>::r>
+ class optional;
+
+ template <typename T>
+ class optional<T, false>
+ {
+ public:
+ ~optional ();
+
+ explicit
+ optional (flags = 0, container* = 0);
+
+ explicit
+ optional (const T&, flags = 0, container* = 0);
+
+ explicit
+ optional (std::auto_ptr<T>, flags = 0, container* = 0);
+
+ optional (const optional&, flags = 0, container* = 0);
+
+ optional&
+ operator= (const T&);
+
+ optional&
+ operator= (const optional&);
+
+ // Pointer-like interface.
+ //
+ public:
+ const T*
+ operator-> () const
+ {
+ return x_;
+ }
+
+ T*
+ operator-> ()
+ {
+ return x_;
+ }
+
+ const T&
+ operator* () const
+ {
+ return *x_;
+ }
+
+ T&
+ operator* ()
+ {
+ return *x_;
+ }
+
+ typedef optional self_; // Simplifier for Sun C++ 5.7.
+ typedef void (self_::*bool_convertible) ();
+
+ operator bool_convertible () const
+ {
+ return x_ != 0 ? &self_::true_ : 0;
+ }
+
+ // Get/set interface.
+ //
+ public:
+ bool
+ present () const
+ {
+ return x_ != 0;
+ }
+
+ const T&
+ get () const
+ {
+ return *x_;
+ }
+
+ T&
+ get ()
+ {
+ return *x_;
+ }
+
+ void
+ set (const T&);
+
+ void
+ set (std::auto_ptr<T>);
+
+ void
+ reset ();
+
+ private:
+ void
+ true_ ();
+
+ private:
+ T* x_;
+ flags flags_;
+ container* container_;
+ };
+
+
+ //
+ //
+ template <typename T>
+ class optional<T, true>
+ {
+ public:
+ explicit
+ optional (flags = 0, container* = 0)
+ : present_ (false)
+ {
+ }
+
+ explicit
+ optional (const T&, flags = 0, container* = 0);
+
+ optional (const optional&, flags = 0, container* = 0);
+
+ optional&
+ operator= (const T&);
+
+ optional&
+ operator= (const optional&);
+
+ // Pointer-like interface.
+ //
+ public:
+ const T*
+ operator-> () const
+ {
+ return &x_;
+ }
+
+ T*
+ operator-> ()
+ {
+ return &x_;
+ }
+
+ const T&
+ operator* () const
+ {
+ return get ();
+ }
+
+ T&
+ operator* ()
+ {
+ return get ();
+ }
+
+ typedef optional self_; // Simplifier for Sun C++ 5.7.
+ typedef void (self_::*bool_convertible) ();
+
+ operator bool_convertible () const
+ {
+ return present () ? &self_::true_ : 0;
+ }
+
+ // Get/set interface.
+ //
+ public:
+ bool
+ present () const
+ {
+ return present_;
+ }
+
+ const T&
+ get () const
+ {
+ return x_;
+ }
+
+ T&
+ get ()
+ {
+ return x_;
+ }
+
+ void
+ set (const T& y)
+ {
+ x_ = y;
+ present_ = true;
+ }
+
+ void
+ reset ()
+ {
+ present_ = false;
+ }
+
+ private:
+ void
+ true_ ();
+
+ private:
+ bool present_;
+ T x_;
+ };
+
+ // Comparison operators.
+ //
+
+ template <typename T, bool fund>
+ inline bool
+ operator== (const optional<T, fund>& a, const optional<T, fund>& b)
+ {
+ return !a || !b ? a.present () == b.present () : *a == *b;
+ }
+
+ template <typename T, bool fund>
+ inline bool
+ operator!= (const optional<T, fund>& a, const optional<T, fund>& b)
+ {
+ return !(a == b);
+ }
+
+ template <typename T, bool fund>
+ inline bool
+ operator< (const optional<T, fund>& a, const optional<T, fund>& b)
+ {
+ return a && (!b || *a < *b);
+ }
+
+ template <typename T, bool fund>
+ inline bool
+ operator> (const optional<T, fund>& a, const optional<T, fund>& b)
+ {
+ return b < a;
+ }
+
+ template <typename T, bool fund>
+ inline bool
+ operator<= (const optional<T, fund>& a, const optional<T, fund>& b)
+ {
+ return !(a > b);
+ }
+
+ template <typename T, bool fund>
+ inline bool
+ operator>= (const optional<T, fund>& a, const optional<T, fund>& b)
+ {
+ return !(a < b);
+ }
+
+ // Provide an ostream insertion opretaor to prevent confusion from
+ // the implicit bool conversion.
+ //
+ template <typename C, typename T, bool fund>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>&, const optional<T, fund>&);
+
+
+ // Sequence.
+ //
+
+ // Note that I cannot get rid of 'fund' because HP aCC3 likes it
+ // this way.
+ //
+ template <typename T, bool fund = fundamental_p<T>::r>
+ class sequence;
+
+
+ // Sun CC's <iterator> does not have iterator_traits. To overcome
+ // this, we will wrap std::iterator_traits into our own and also
+ // specialize it for pointer types. Since Sun CC uses pointer
+ // for vector::iterator, it will use the specialization and won't
+ // notice the std::iterator_traits.
+ //
+#ifndef _RWSTD_NO_CLASS_PARTIAL_SPEC
+ template <typename I>
+ struct iterator_traits
+ {
+ typedef
+ typename std::iterator_traits<I>::iterator_category
+ iterator_category;
+
+ typedef
+ typename std::iterator_traits<I>::value_type
+ value_type;
+
+ typedef
+ typename std::iterator_traits<I>::difference_type
+ difference_type;
+ };
+#else
+ // The Pointer specialization does not work for reverse and
+ // set iterators. But these iterators are user-dfined types
+ // and have suitable typedefs that we can use.
+ //
+ template <typename I>
+ struct iterator_traits
+ {
+ typedef typename I::iterator_category iterator_category;
+ typedef typename I::value_type value_type;
+ typedef typename I::difference_type difference_type;
+ };
+
+ template <typename T>
+ struct iterator_traits<T*>
+ {
+ typedef std::random_access_iterator_tag iterator_category;
+ typedef T value_type;
+ typedef std::ptrdiff_t difference_type;
+ };
+#endif
+
+ // Iterator adapter for complex types. It expects I to point to
+ // a smart pointer-like object that has operator*() that returns
+ // a refernce to a type static_cast'able to T and get() that
+ // returns a pointer to a type static_cast'able to T.
+ //
+
+ template <typename I, typename T>
+ struct iterator_adapter
+ {
+ typedef T value_type;
+ typedef value_type& reference;
+ typedef value_type* pointer;
+
+ typedef
+ typename iterator_traits<I>::iterator_category
+ iterator_category;
+
+ typedef
+ typename iterator_traits<I>::difference_type
+ difference_type;
+
+
+ public:
+ iterator_adapter ()
+ : i_ () // i_ can be of a pointer type.
+ {
+ }
+
+ // Allow iterator to const_iterator conversion.
+ //
+ template <typename J, typename T2>
+ iterator_adapter (const iterator_adapter<J, T2>& j)
+ : i_ (j.base ())
+ {
+ }
+
+ explicit
+ iterator_adapter (const I& i)
+ : i_ (i)
+ {
+ }
+
+ public:
+ // Forward iterator requirements.
+ //
+ reference
+ operator* () const
+ {
+ return static_cast<reference> (**i_);
+ }
+
+ pointer
+ operator-> () const
+ {
+ return static_cast<pointer> (i_->get ());
+ }
+
+ iterator_adapter&
+ operator++ ()
+ {
+ ++i_;
+ return *this;
+ }
+
+ iterator_adapter
+ operator++ (int)
+ {
+ iterator_adapter r (*this);
+ ++i_;
+ return r;
+ }
+
+ // Bidirectional iterator requirements.
+ //
+ iterator_adapter&
+ operator-- ()
+ {
+ --i_;
+ return *this;
+ }
+
+ iterator_adapter
+ operator-- (int)
+ {
+ iterator_adapter r (*this);
+ --i_;
+ return r;
+ }
+
+ // Random access iterator requirements.
+ //
+ reference
+ operator[] (difference_type n) const
+ {
+ return static_cast<reference> (*(i_[n]));
+ }
+
+ iterator_adapter&
+ operator+= (difference_type n)
+ {
+ i_ += n;
+ return *this;
+ }
+
+ iterator_adapter
+ operator+ (difference_type n) const
+ {
+ return iterator_adapter (i_ + n);
+ }
+
+ iterator_adapter&
+ operator-= (difference_type n)
+ {
+ i_ -= n;
+ return *this;
+ }
+
+ iterator_adapter
+ operator- (difference_type n) const
+ {
+ return iterator_adapter (i_ - n);
+ }
+
+ public:
+ const I&
+ base () const
+ {
+ return i_;
+ }
+
+ private:
+ I i_;
+ };
+
+ // Note: We use different types for left- and right-hand-side
+ // arguments to allow comparison between iterator and const_iterator.
+ //
+
+ // Forward iterator requirements.
+ //
+ template <typename I, typename J, typename T1, typename T2>
+ inline bool
+ operator== (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () == j.base ();
+ }
+
+ template <typename I, typename J, typename T1, typename T2>
+ inline bool
+ operator!= (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () != j.base ();
+ }
+
+ // Random access iterator requirements
+ //
+ template <typename I, typename J, typename T1, typename T2>
+ inline bool
+ operator< (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () < j.base ();
+ }
+
+ template <typename I, typename J, typename T1, typename T2>
+ inline bool
+ operator> (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () > j.base ();
+ }
+
+ template <typename I, typename J, typename T1, typename T2>
+ inline bool
+ operator<= (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () <= j.base ();
+ }
+
+ template <typename I, typename J, typename T1, typename T2>
+ inline bool
+ operator>= (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () >= j.base ();
+ }
+
+ template <typename I, typename J, typename T1, typename T2>
+ inline typename iterator_adapter<I, T1>::difference_type
+ operator- (const iterator_adapter<I, T1>& i,
+ const iterator_adapter<J, T2>& j)
+ {
+ return i.base () - j.base ();
+ }
+
+ template <typename I, typename T>
+ inline iterator_adapter<I, T>
+ operator+ (typename iterator_adapter<I, T>::difference_type n,
+ const iterator_adapter<I, T>& i)
+ {
+ return iterator_adapter<I, T> (i.base () + n);
+ }
+
+ //
+ //
+ class sequence_common
+ {
+ protected:
+ // This is a dangerously destructive automatic pointer. We are going
+ // to use it in a controlled environment to save us a lot of coding.
+ //
+ struct ptr
+ {
+ ~ptr ()
+ {
+ delete x_;
+ }
+
+ explicit
+ ptr (type* x = 0)
+ : x_ (x)
+ {
+ }
+
+ ptr (const ptr& y)
+ : x_ (y.x_)
+ {
+ // Yes, hostile takeover.
+ //
+ y.x_ = 0;
+ }
+
+ ptr&
+ operator= (const ptr& y)
+ {
+ if (this != &y)
+ {
+ // Yes, hostile takeover.
+ //
+ delete x_;
+ x_ = y.x_;
+ y.x_ = 0;
+ }
+
+ return *this;
+ }
+
+ public:
+ type&
+ operator* () const
+ {
+ return *x_;
+ }
+
+ type*
+ get () const
+ {
+ return x_;
+ }
+
+ private:
+ mutable type* x_;
+ };
+
+ protected:
+ typedef std::vector<ptr> base_sequence;
+ typedef base_sequence::iterator base_iterator;
+ typedef base_sequence::const_iterator base_const_iterator;
+
+ typedef base_sequence::size_type size_type;
+ typedef base_sequence::difference_type difference_type;
+ typedef base_sequence::allocator_type allocator_type;
+
+ protected:
+ sequence_common (flags f, container* c)
+ : flags_ (f), container_ (c)
+ {
+ }
+
+ sequence_common (size_type n, const type& x)
+ : flags_ (0), container_ (0)
+ {
+ assign (n, x);
+ }
+
+ template <typename I>
+ sequence_common (const I& begin, const I& end)
+ : flags_ (0), container_ (0)
+ {
+ assign (begin, end);
+ }
+
+ sequence_common (const sequence_common& v, flags f, container* c)
+ : flags_ (f), container_ (c)
+ {
+ v_.reserve (v.v_.size ());
+
+ for (base_const_iterator i (v.v_.begin ()), e (v.v_.end ());
+ i != e; ++i)
+ {
+ ptr p ((**i)._clone (flags_, container_));
+ v_.push_back (p);
+ }
+ }
+
+ public:
+ sequence_common&
+ operator= (const sequence_common& v)
+ {
+ if (this == &v)
+ return *this;
+
+ v_.assign (v.v_.size (), ptr ());
+
+ base_iterator di (v_.begin ()), de (v_.end ());
+ base_const_iterator si (v.v_.begin ()), se (v.v_.end ());
+
+ for (; si != se && di != de; ++si, ++di)
+ {
+ // We have no ptr_ref.
+ //
+ ptr p ((**si)._clone (flags_, container_));
+ *di = p;
+ }
+
+ return *this;
+ }
+
+ public:
+ size_type
+ size () const
+ {
+ return v_.size ();
+ }
+
+ size_type
+ max_size () const
+ {
+ return v_.max_size ();
+ }
+
+ size_type
+ capacity () const
+ {
+ return v_.capacity ();
+ }
+
+ bool
+ empty () const
+ {
+ return v_.empty ();
+ }
+
+ void
+ reserve (size_type n)
+ {
+ v_.reserve (n);
+ }
+
+ void
+ clear ()
+ {
+ v_.clear ();
+ }
+
+ protected:
+ void
+ assign (size_type n, const type& x)
+ {
+ v_.assign (n, ptr ());
+
+ for (base_iterator i (v_.begin ()), e (v_.end ()); i != e; ++i)
+ {
+ ptr p (x._clone (flags_, container_));
+ *i = p;
+ }
+ }
+
+ template <typename I>
+ void
+ assign (const I& begin, const I& end)
+ {
+ // This is not the fastest way to do it. Also I's type may not
+ // have _clone.
+ //
+ v_.clear ();
+
+ for (I i (begin); i != end; ++i)
+ {
+ ptr p (i->_clone (flags_, container_));
+ v_.push_back (p);
+ }
+ }
+
+ void
+ resize (size_type n, const type& x)
+ {
+ size_type old (v_.size ());
+ v_.resize (n, ptr ());
+
+ if (old < n)
+ {
+ for (base_iterator i (v_.begin () + old), e (v_.end ());
+ i != e; ++i)
+ {
+ ptr p (x._clone (flags_, container_));
+ *i = p;
+ }
+ }
+ }
+
+ void
+ insert (base_iterator p, size_type n, const type& x)
+ {
+ difference_type d (v_.end () - p);
+ v_.insert (p, n, ptr ());
+
+ for (base_iterator i (v_.end () - d); n != 0; --n)
+ {
+ ptr r (x._clone (flags_, container_));
+ *(--i) = r;
+ }
+ }
+
+ template <typename I>
+ void
+ insert (base_iterator p, const I& begin, const I& end)
+ {
+ // This is not the fastest way to do it. Also I's type may not
+ // have _clone.
+ //
+ if (begin != end)
+ {
+ for (I i (end);;)
+ {
+ --i;
+ ptr r (i->_clone (flags_, container_));
+ p = v_.insert (p, r);
+
+ if (i == begin)
+ break;
+ }
+ }
+ }
+
+ protected:
+ flags flags_;
+ container* container_;
+ base_sequence v_;
+ };
+
+ //
+ //
+ template <typename T>
+ class sequence<T, false>: public sequence_common
+ {
+ protected:
+ // For IBM XL C++ 8.0.
+ //
+ typedef sequence_common::ptr ptr;
+
+ public:
+ typedef T value_type;
+ typedef T* pointer;
+ typedef const T* const_pointer;
+ typedef T& reference;
+ typedef const T& const_reference;
+
+ typedef
+ iterator_adapter<base_sequence::iterator, T>
+ iterator;
+
+ typedef
+ iterator_adapter<base_sequence::const_iterator, const T>
+ const_iterator;
+
+ typedef
+ iterator_adapter<base_sequence::reverse_iterator, T>
+ reverse_iterator;
+
+ typedef
+ iterator_adapter<base_sequence::const_reverse_iterator, const T>
+ const_reverse_iterator;
+
+ typedef sequence_common::size_type size_type;
+ typedef sequence_common::difference_type difference_type;
+ typedef sequence_common::allocator_type allocator_type;
+
+ public:
+ explicit
+ sequence (flags f = 0, container* c = 0)
+ : sequence_common (f, c)
+ {
+ }
+
+ // The first version causes trouble on IBM XL C++ 7.0 when
+ // a type does not have the default c-tor. While the second
+ // breaks VC++ 8.0 when using dllexport (it appears to
+ // instantiate everything instead of only what's used).
+ //
+#ifdef _MSC_VER
+ explicit
+ sequence (size_type n, const T& x = T ())
+ : sequence_common (n, x)
+ {
+ }
+#else
+ explicit
+ sequence (size_type n)
+ : sequence_common (n, T ())
+ {
+ }
+
+ sequence (size_type n, const T& x)
+ : sequence_common (n, x)
+ {
+ }
+#endif
+
+ template <typename I>
+ sequence (const I& begin, const I& end)
+ : sequence_common (begin, end)
+ {
+ }
+
+ sequence (const sequence& v, flags f = 0, container* c = 0)
+ : sequence_common (v, f, c)
+ {
+ }
+
+ public:
+ void
+ assign (size_type n, const T& x)
+ {
+ sequence_common::assign (n, x);
+ }
+
+ template <typename I>
+ void
+ assign (const I& begin, const I& end)
+ {
+ sequence_common::assign (begin, end);
+ }
+
+ public:
+ // The first version causes trouble on IBM XL C++ 7.0 when
+ // a type does not have the default c-tor. While the second
+ // breaks VC++ 8.0 when using dllexport (it appears to
+ // instantiate everything instead of only what's used).
+ //
+#ifdef _MSC_VER
+ void
+ resize (size_type n, const T& x = T ())
+ {
+ sequence_common::resize (n, x);
+ }
+#else
+ void
+ resize (size_type n)
+ {
+ sequence_common::resize (n, T ());
+ }
+
+ void
+ resize (size_type n, const T& x)
+ {
+ sequence_common::resize (n, x);
+ }
+#endif
+
+ public:
+ const_iterator
+ begin () const
+ {
+ return const_iterator (v_.begin ());
+ }
+
+ const_iterator
+ end () const
+ {
+ return const_iterator (v_.end ());
+ }
+
+ iterator
+ begin ()
+ {
+ return iterator (v_.begin ());
+ }
+
+ iterator
+ end ()
+ {
+ return iterator (v_.end ());
+ }
+
+ // reverse
+ //
+
+ const_reverse_iterator
+ rbegin () const
+ {
+ return const_reverse_iterator (v_.rbegin ());
+ }
+
+ const_reverse_iterator
+ rend () const
+ {
+ return const_reverse_iterator (v_.rend ());
+ }
+
+ reverse_iterator
+ rbegin ()
+ {
+ return reverse_iterator (v_.rbegin ());
+ }
+
+ reverse_iterator
+ rend ()
+ {
+ return reverse_iterator (v_.rend ());
+ }
+
+ public:
+ T&
+ operator[] (size_type n)
+ {
+ return static_cast<T&> (*(v_[n]));
+ }
+
+ const T&
+ operator[] (size_type n) const
+ {
+ return static_cast<const T&> (*(v_[n]));
+ }
+
+ T&
+ at (size_type n)
+ {
+ return static_cast<T&> (*(v_.at (n)));
+ }
+
+ const T&
+ at (size_type n) const
+ {
+ return static_cast<const T&> (*(v_.at (n)));
+ }
+
+ T&
+ front ()
+ {
+ return static_cast<T&> (*(v_.front ()));
+ }
+
+ const T&
+ front () const
+ {
+ return static_cast<const T&> (*(v_.front ()));
+ }
+
+ T&
+ back ()
+ {
+ return static_cast<T&> (*(v_.back ()));
+ }
+
+ const T&
+ back () const
+ {
+ return static_cast<const T&> (*(v_.back ()));
+ }
+
+ public:
+ void
+ push_back (const T& x)
+ {
+ v_.push_back (ptr (x._clone (flags_, container_)));
+ }
+
+ void
+ push_back (std::auto_ptr<T> x)
+ {
+ if (x->_container () != container_)
+ x->_container (container_);
+
+ v_.push_back (ptr (x.release ()));
+ }
+
+ void
+ pop_back ()
+ {
+ v_.pop_back ();
+ }
+
+ iterator
+ insert (iterator position, const T& x)
+ {
+ return iterator (
+ v_.insert (
+ position.base (), ptr (x._clone (flags_, container_))));
+ }
+
+ iterator
+ insert (iterator position, std::auto_ptr<T> x)
+ {
+ if (x->_container () != container_)
+ x->_container (container_);
+
+ return iterator (v_.insert (position.base (), ptr (x.release ())));
+ }
+
+ void
+ insert (iterator position, size_type n, const T& x)
+ {
+ sequence_common::insert (position.base (), n, x);
+ }
+
+ template <typename I>
+ void
+ insert (iterator position, const I& begin, const I& end)
+ {
+ sequence_common::insert (position.base (), begin, end);
+ }
+
+ iterator
+ erase (iterator position)
+ {
+ return iterator (v_.erase (position.base ()));
+ }
+
+ iterator
+ erase (iterator begin, iterator end)
+ {
+ return iterator (v_.erase (begin.base (), end.base ()));
+ }
+
+ // Note that the container object of the two sequences being
+ // swapped should be the same.
+ //
+ void
+ swap (sequence& x)
+ {
+ assert (container_ == x.container_);
+ v_.swap (x.v_);
+ }
+ };
+
+
+ // Specialization for fundamental types.
+ //
+ template <typename T>
+ class sequence<T, true>: public std::vector<T>
+ {
+ typedef std::vector<T> base_sequence;
+
+ public:
+ explicit
+ sequence (flags = 0, container* = 0)
+ {
+ }
+
+ explicit
+ sequence (typename base_sequence::size_type n, const T& x = T ())
+ : base_sequence (n, x)
+ {
+ }
+
+ template <typename I>
+ sequence (const I& begin, const I& end)
+ : base_sequence (begin, end)
+ {
+ }
+
+ sequence (const sequence& s, flags = 0, container* = 0)
+ : base_sequence (s)
+ {
+ }
+ };
+
+
+ // Comparison operators.
+ //
+
+ template <typename T, bool fund>
+ inline bool
+ operator== (const sequence<T, fund>& a, const sequence<T, fund>& b)
+ {
+ return (a.size () == b.size ()
+ && std::equal (a.begin (), a.end (), b.begin ()));
+ }
+
+ template <typename T, bool fund>
+ inline bool
+ operator!= (const sequence<T, fund>& a, const sequence<T, fund>& b)
+ {
+ return !(a == b);
+ }
+
+ template <typename T, bool fund>
+ inline bool
+ operator< (const sequence<T, fund>& a, const sequence<T, fund>& b)
+ {
+ return std::lexicographical_compare (a.begin (), a.end (),
+ b.begin (), b.end ());
+ }
+
+ template <typename T, bool fund>
+ inline bool
+ operator> (const sequence<T, fund>& a, const sequence<T, fund>& b)
+ {
+ return b < a;
+ }
+
+ template <typename T, bool fund>
+ inline bool
+ operator<= (const sequence<T, fund>& a, const sequence<T, fund>& b)
+ {
+ return !(a > b);
+ }
+
+ template <typename T, bool fund>
+ inline bool
+ operator>= (const sequence<T, fund>& a, const sequence<T, fund>& b)
+ {
+ return !(a < b);
+ }
+
+ // Note that the container object of the two sequences being
+ // swapped should be the same.
+ //
+ template <typename T, bool fund>
+ inline void
+ swap (sequence<T, fund>& x, sequence<T, fund>& y)
+ {
+ x.swap (y);
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/tree/containers.txx>
+
+#endif // XSD_CXX_TREE_CONTAINERS_HXX
diff --git a/libxsd/xsd/cxx/tree/containers.txx b/libxsd/xsd/cxx/tree/containers.txx
new file mode 100644
index 0000000..5cd79ba
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/containers.txx
@@ -0,0 +1,284 @@
+// file : xsd/cxx/tree/containers.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <ostream>
+#include <xsd/cxx/tree/bits/literals.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // one
+ //
+ template<typename T>
+ one<T, false>::
+ ~one ()
+ {
+ delete x_;
+ }
+
+ template<typename T>
+ one<T, false>::
+ one (flags f, container* c)
+ : x_ (0), flags_ (f), container_ (c)
+ {
+ }
+
+ template<typename T>
+ one<T, false>::
+ one (const T& x, flags f, container* c)
+ : x_ (0), flags_ (f), container_ (c)
+ {
+ set (x);
+ }
+
+ template<typename T>
+ one<T, false>::
+ one (std::auto_ptr<T> x, flags f, container* c)
+ : x_ (0), flags_ (f), container_ (c)
+ {
+ set (x);
+ }
+
+ template<typename T>
+ one<T, false>::
+ one (const one<T, false>& x, flags f, container* c)
+ : x_ (0), flags_ (f), container_ (c)
+ {
+ if (x.present ())
+ set (x.get ());
+ }
+
+ template<typename T>
+ one<T, false>& one<T, false>::
+ operator= (const one<T, false>& x)
+ {
+ if (this == &x)
+ return *this;
+
+ if (x.present ())
+ set (x.get ());
+ else
+ {
+ delete x_;
+ x_ = 0;
+ }
+
+ return *this;
+ }
+
+ template<typename T>
+ void one<T, false>::
+ set (const T& x)
+ {
+ // We always do a fresh copy because T may not be x's
+ // dynamic type.
+ //
+ T* r (x._clone (flags_, container_));
+
+ delete x_;
+ x_ = r;
+ }
+
+ template<typename T>
+ void one<T, false>::
+ set (std::auto_ptr<T> x)
+ {
+ T* r (0);
+
+ if (x.get () != 0)
+ {
+ if (x->_container () != container_)
+ x->_container (container_);
+
+ r = x.release ();
+ }
+
+ delete x_;
+ x_ = r;
+ }
+
+ // optional
+ //
+ template <typename T>
+ optional<T, false>::
+ ~optional ()
+ {
+ delete x_;
+ }
+
+ template <typename T>
+ optional<T, false>::
+ optional (flags f, container* c)
+ : x_ (0), flags_ (f), container_ (c)
+ {
+ }
+
+ template <typename T>
+ optional<T, false>::
+ optional (const T& x, flags f, container* c)
+ : x_ (0), flags_ (f), container_ (c)
+ {
+ set (x);
+ }
+
+ template <typename T>
+ optional<T, false>::
+ optional (std::auto_ptr<T> x, flags f, container* c)
+ : x_ (0), flags_ (f), container_ (c)
+ {
+ set (x);
+ }
+
+ template <typename T>
+ optional<T, false>::
+ optional (const optional<T, false>& x, flags f, container* c)
+ : x_ (0), flags_ (f), container_ (c)
+ {
+ if (x)
+ set (*x);
+ }
+
+ template <typename T>
+ optional<T, false>& optional<T, false>::
+ operator= (const T& x)
+ {
+ if (x_ == &x)
+ return *this;
+
+ set (x);
+
+ return *this;
+ }
+
+ template <typename T>
+ optional<T, false>& optional<T, false>::
+ operator= (const optional<T, false>& x)
+ {
+ if (this == &x)
+ return *this;
+
+ if (x)
+ set (*x);
+ else
+ reset ();
+
+ return *this;
+ }
+
+ template <typename T>
+ void optional<T, false>::
+ set (const T& x)
+ {
+ // We always do a fresh copy because T may not be x's
+ // dynamic type.
+ //
+ T* r (x._clone (flags_, container_));
+
+ delete x_;
+ x_ = r;
+ }
+
+ template <typename T>
+ void optional<T, false>::
+ set (std::auto_ptr<T> x)
+ {
+ T* r (0);
+
+ if (x.get () != 0)
+ {
+ if (x->_container () != container_)
+ x->_container (container_);
+
+ r = x.release ();
+ }
+
+ delete x_;
+ x_ = r;
+ }
+
+ template <typename T>
+ void optional<T, false>::
+ reset ()
+ {
+ delete x_;
+ x_ = 0;
+ }
+
+ template <typename T>
+ void optional<T, false>::
+ true_ ()
+ {
+ }
+
+
+ // optional
+ //
+ template <typename T>
+ optional<T, true>::
+ optional (const T& y, flags, container*)
+ : present_ (false)
+ {
+ set (y);
+ }
+
+ template <typename T>
+ optional<T, true>::
+ optional (const optional<T, true>& y, flags, container*)
+ : present_ (false)
+ {
+ if (y)
+ set (*y);
+ }
+
+ template <typename T>
+ optional<T, true>& optional<T, true>::
+ operator= (const T& y)
+ {
+ if (&x_ == &y)
+ return *this;
+
+ set (y);
+
+ return *this;
+ }
+
+ template <typename T>
+ optional<T, true>& optional<T, true>::
+ operator= (const optional<T, true>& y)
+ {
+ if (this == &y)
+ return *this;
+
+ if (y)
+ set (*y);
+ else
+ reset ();
+
+ return *this;
+ }
+
+ template <typename T>
+ void optional<T, true>::
+ true_ ()
+ {
+ }
+
+ template <typename C, typename T, bool fund>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const optional<T, fund>& x)
+ {
+ if (x)
+ os << *x;
+ else
+ os << bits::not_present<C> ();
+
+ return os;
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/date-time-extraction.txx b/libxsd/xsd/cxx/tree/date-time-extraction.txx
new file mode 100644
index 0000000..7803175
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/date-time-extraction.txx
@@ -0,0 +1,157 @@
+// file : xsd/cxx/tree/date-time-extraction.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // time_zone
+ //
+ template <typename S>
+ inline void time_zone::
+ zone_extract (istream<S>& s)
+ {
+ s >> hours_ >> minutes_;
+ present_ = true;
+ }
+
+ // gday
+ //
+ template <typename C, typename B>
+ template <typename S>
+ gday<C, B>::
+ gday (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ bool zp;
+ s >> day_ >> zp;
+
+ if (zp)
+ zone_extract (s);
+ }
+
+ // gmonth
+ //
+ template <typename C, typename B>
+ template <typename S>
+ gmonth<C, B>::
+ gmonth (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ bool zp;
+ s >> month_ >> zp;
+
+ if (zp)
+ zone_extract (s);
+ }
+
+ // gyear
+ //
+ template <typename C, typename B>
+ template <typename S>
+ gyear<C, B>::
+ gyear (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ bool zp;
+ s >> year_ >> zp;
+
+ if (zp)
+ zone_extract (s);
+ }
+
+ // gmonth_day
+ //
+ template <typename C, typename B>
+ template <typename S>
+ gmonth_day<C, B>::
+ gmonth_day (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ bool zp;
+ s >> month_ >> day_ >> zp;
+
+ if (zp)
+ zone_extract (s);
+ }
+
+ // gyear_month
+ //
+ template <typename C, typename B>
+ template <typename S>
+ gyear_month<C, B>::
+ gyear_month (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ bool zp;
+ s >> year_ >> month_ >> zp;
+
+ if (zp)
+ zone_extract (s);
+ }
+
+ // date
+ //
+ template <typename C, typename B>
+ template <typename S>
+ date<C, B>::
+ date (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ bool zp;
+ s >> year_ >> month_ >> day_ >> zp;
+
+ if (zp)
+ zone_extract (s);
+ }
+
+ // time
+ //
+ template <typename C, typename B>
+ template <typename S>
+ time<C, B>::
+ time (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ bool zp;
+ s >> hours_ >> minutes_ >> seconds_ >> zp;
+
+ if (zp)
+ zone_extract (s);
+ }
+
+ // date_time
+ //
+ template <typename C, typename B>
+ template <typename S>
+ date_time<C, B>::
+ date_time (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ bool zp;
+ s >> year_ >> month_ >> day_
+ >> hours_ >> minutes_ >> seconds_ >> zp;
+
+ if (zp)
+ zone_extract (s);
+ }
+
+ // duration
+ //
+ template <typename C, typename B>
+ template <typename S>
+ duration<C, B>::
+ duration (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ s >> negative_
+ >> years_ >> months_ >> days_
+ >> hours_ >> minutes_ >> seconds_;
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/date-time-insertion.txx b/libxsd/xsd/cxx/tree/date-time-insertion.txx
new file mode 100644
index 0000000..bd3cd3d
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/date-time-insertion.txx
@@ -0,0 +1,188 @@
+// file : xsd/cxx/tree/date-time-insertion.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // time_zone
+ //
+ template <typename S>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const time_zone& z)
+ {
+ return s << z.zone_hours () << z.zone_minutes ();
+ }
+
+ // gday
+ //
+ template <typename S, typename C, typename B>
+ ostream<S>&
+ operator<< (ostream<S>& s, const gday<C, B>& x)
+ {
+ bool zp (x.zone_present ());
+
+ s << x.day () << zp;
+
+ if (zp)
+ {
+ const time_zone& z (x);
+ s << z;
+ }
+
+ return s;
+ }
+
+ // gmonth
+ //
+ template <typename S, typename C, typename B>
+ ostream<S>&
+ operator<< (ostream<S>& s, const gmonth<C, B>& x)
+ {
+ bool zp (x.zone_present ());
+
+ s << x.month () << zp;
+
+ if (zp)
+ {
+ const time_zone& z (x);
+ s << z;
+ }
+
+ return s;
+ }
+
+ // gyear
+ //
+ template <typename S, typename C, typename B>
+ ostream<S>&
+ operator<< (ostream<S>& s, const gyear<C, B>& x)
+ {
+ bool zp (x.zone_present ());
+
+ s << x.year () << zp;
+
+ if (zp)
+ {
+ const time_zone& z (x);
+ s << z;
+ }
+
+ return s;
+ }
+
+ // gmonth_day
+ //
+ template <typename S, typename C, typename B>
+ ostream<S>&
+ operator<< (ostream<S>& s, const gmonth_day<C, B>& x)
+ {
+ bool zp (x.zone_present ());
+
+ s << x.month () << x.day () << zp;
+
+ if (zp)
+ {
+ const time_zone& z (x);
+ s << z;
+ }
+
+ return s;
+ }
+
+ // gyear_month
+ //
+ template <typename S, typename C, typename B>
+ ostream<S>&
+ operator<< (ostream<S>& s, const gyear_month<C, B>& x)
+ {
+ bool zp (x.zone_present ());
+
+ s << x.year () << x.month () << zp;
+
+ if (zp)
+ {
+ const time_zone& z (x);
+ s << z;
+ }
+
+ return s;
+ }
+
+ // date
+ //
+ template <typename S, typename C, typename B>
+ ostream<S>&
+ operator<< (ostream<S>& s, const date<C, B>& x)
+ {
+ bool zp (x.zone_present ());
+
+ s << x.year () << x.month () << x.day () << zp;
+
+ if (zp)
+ {
+ const time_zone& z (x);
+ s << z;
+ }
+
+ return s;
+ }
+
+ // time
+ //
+ template <typename S, typename C, typename B>
+ ostream<S>&
+ operator<< (ostream<S>& s, const time<C, B>& x)
+ {
+ bool zp (x.zone_present ());
+
+ s << x.hours () << x.minutes () << x.seconds () << zp;
+
+ if (zp)
+ {
+ const time_zone& z (x);
+ s << z;
+ }
+
+ return s;
+ }
+
+ // date_time
+ //
+ template <typename S, typename C, typename B>
+ ostream<S>&
+ operator<< (ostream<S>& s, const date_time<C, B>& x)
+ {
+ bool zp (x.zone_present ());
+
+ s << x.year () << x.month () << x.day ()
+ << x.hours () << x.minutes () << x.seconds () << zp;
+
+ if (zp)
+ {
+ const time_zone& z (x);
+ s << z;
+ }
+
+ return s;
+ }
+
+ // duration
+ //
+ template <typename S, typename C, typename B>
+ ostream<S>&
+ operator<< (ostream<S>& s, const duration<C, B>& x)
+ {
+ s << x.negative ()
+ << x.years () << x.months () << x.days ()
+ << x.hours () << x.minutes () << x.seconds ();
+
+ return s;
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/date-time-ostream.txx b/libxsd/xsd/cxx/tree/date-time-ostream.txx
new file mode 100644
index 0000000..85115d2
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/date-time-ostream.txx
@@ -0,0 +1,324 @@
+// file : xsd/cxx/tree/date-time-ostream.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <ostream>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // time_zone
+ //
+ template <typename C>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const time_zone& z)
+ {
+ short h = z.zone_hours ();
+ short m = z.zone_minutes ();
+
+ if (h == 0 && m == 0)
+ {
+ os << C ('Z');
+ }
+ else
+ {
+ if (h < 0 || m < 0)
+ {
+ h = -h;
+ m = -m;
+ os << C ('-');
+ }
+ else
+ os << C ('+');
+
+ C f (os.fill (C ('0')));
+
+ os.width (2);
+ os << h << C (':');
+ os.width (2);
+ os << m;
+
+ os.fill (f);
+ }
+
+ return os;
+ }
+
+ // gday
+ //
+ template <typename C, typename B>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const gday<C, B>& x)
+ {
+ C f (os.fill (C ('0')));
+ os.width (2);
+ os << x.day ();
+ os.fill (f);
+
+ if (x.zone_present ())
+ {
+ const time_zone& z (x);
+ os << z;
+ }
+
+ return os;
+ }
+
+ // gmonth
+ //
+ template <typename C, typename B>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const gmonth<C, B>& x)
+ {
+ C f (os.fill (C ('0')));
+ os.width (2);
+ os << x.month ();
+ os.fill (f);
+
+ if (x.zone_present ())
+ {
+ const time_zone& z (x);
+ os << z;
+ }
+
+ return os;
+ }
+
+ // gyear
+ //
+ template <typename C, typename B>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const gyear<C, B>& x)
+ {
+ C f (os.fill (C ('0')));
+ os.width (4);
+ os << x.year ();
+ os.fill (f);
+
+ if (x.zone_present ())
+ {
+ const time_zone& z (x);
+ os << z;
+ }
+
+ return os;
+ }
+
+ // gmonth_day
+ //
+ template <typename C, typename B>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const gmonth_day<C, B>& x)
+ {
+ C f (os.fill (C ('0')));
+
+ os.width (2);
+ os << x.month () << C ('-');
+
+ os.width (2);
+ os << x.day ();
+
+ os.fill (f);
+
+ if (x.zone_present ())
+ {
+ const time_zone& z (x);
+ os << z;
+ }
+
+ return os;
+ }
+
+
+ // gyear_month
+ //
+ template <typename C, typename B>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const gyear_month<C, B>& x)
+ {
+ C f (os.fill (C ('0')));
+
+ os.width (4);
+ os << x.year () << C ('-');
+
+ os.width (2);
+ os << x.month ();
+
+ os.fill (f);
+
+ if (x.zone_present ())
+ {
+ const time_zone& z (x);
+ os << z;
+ }
+
+ return os;
+ }
+
+ // date
+ //
+ template <typename C, typename B>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const date<C, B>& x)
+ {
+ C f (os.fill (C ('0')));
+
+ os.width (4);
+ os << x.year () << C ('-');
+
+ os.width (2);
+ os << x.month () << C ('-');
+
+ os.width (2);
+ os << x.day ();
+
+ os.fill (f);
+
+ if (x.zone_present ())
+ {
+ const time_zone& z (x);
+ os << z;
+ }
+
+ return os;
+ }
+
+ // time
+ //
+ template <typename C, typename B>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const time<C, B>& x)
+ {
+ C f (os.fill (C ('0')));
+
+ os.width (2);
+ os << x.hours () << C (':');
+
+ os.width (2);
+ os << x.minutes () << C (':');
+
+ os.width (9);
+ std::ios_base::fmtflags ff (
+ os.setf (std::ios::fixed, std::ios::floatfield));
+ os << x.seconds ();
+ os.setf (ff, std::ios::floatfield);
+
+ os.fill (f);
+
+ if (x.zone_present ())
+ {
+ const time_zone& z (x);
+ os << z;
+ }
+
+ return os;
+ }
+
+ // date_time
+ //
+ template <typename C, typename B>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const date_time<C, B>& x)
+ {
+ C f (os.fill (C ('0')));
+
+ os.width (4);
+ os << x.year () << C ('-');
+
+ os.width (2);
+ os << x.month () << C ('-');
+
+ os.width (2);
+ os << x.day () << C ('T');
+
+ os.width (2);
+ os << x.hours () << C (':');
+
+ os.width (2);
+ os << x.minutes () << C (':');
+
+ os.width (9);
+ std::ios_base::fmtflags ff (
+ os.setf (std::ios::fixed, std::ios::floatfield));
+ os << x.seconds ();
+ os.setf (ff, std::ios::floatfield);
+
+ os.fill (f);
+
+ if (x.zone_present ())
+ {
+ const time_zone& z (x);
+ os << z;
+ }
+
+ return os;
+ }
+
+ // duration
+ //
+ template <typename C, typename B>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const duration<C, B>& x)
+ {
+ if (x.negative ())
+ os << C ('-');
+
+ os << C ('P');
+
+ // In case it is 0-duration, use the years field to handle
+ // this case.
+ //
+ if (x.years () != 0 ||
+ (x.months () == 0 &&
+ x.days () == 0 &&
+ x.hours () == 0 &&
+ x.minutes () == 0 &&
+ x.seconds () == 0.0))
+ {
+ os << x.years () << C ('Y');
+ }
+
+ if (x.months () != 0)
+ {
+ os << x.months () << C ('M');
+ }
+
+ if (x.days () != 0)
+ {
+ os << x.days () << C ('D');
+ }
+
+ // Figure out if we need the 'T' delimiter.
+ //
+ if (x.hours () != 0 ||
+ x.minutes () != 0 ||
+ x.seconds () != 0.0)
+ os << C ('T');
+
+ if (x.hours () != 0)
+ {
+ os << x.hours () << C ('H');
+ }
+
+ if (x.minutes () != 0)
+ {
+ os << x.minutes () << C ('M');
+ }
+
+ if (x.seconds () > 0.0)
+ {
+ std::ios_base::fmtflags ff (
+ os.setf (std::ios::fixed, std::ios::floatfield));
+ os << x.seconds () << C ('S');
+ os.setf (ff, std::ios::floatfield);
+ }
+
+ return os;
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/date-time.hxx b/libxsd/xsd/cxx/tree/date-time.hxx
new file mode 100644
index 0000000..f945c01
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/date-time.hxx
@@ -0,0 +1,1951 @@
+// file : xsd/cxx/tree/date-time.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+/**
+ * @file
+ *
+ * @brief Contains C++ class definitions for the XML Schema date/time types.
+ *
+ * This is an internal header and is included by the generated code. You
+ * normally should not include it directly.
+ *
+ */
+
+#ifndef XSD_CXX_TREE_DATE_TIME_HXX
+#define XSD_CXX_TREE_DATE_TIME_HXX
+
+#include <string>
+#include <cstddef> // std::size_t
+
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMElement.hpp>
+
+#include <xsd/cxx/tree/elements.hxx>
+#include <xsd/cxx/tree/istream-fwd.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ /**
+ * @brief C++/Tree mapping runtime namespace.
+ *
+ * This is an internal namespace and normally should not be referenced
+ * directly. Instead you should use the aliases for types in this
+ * namespaces that are created in the generated code.
+ *
+ */
+ namespace tree
+ {
+ /**
+ * @brief Time zone representation
+ *
+ * The %time_zone class represents an optional %time zone and
+ * is used as a base class for date/time types.
+ *
+ * The %time zone can negative in which case both the hours and
+ * minutes components should be negative.
+ *
+ * @nosubgrouping
+ */
+ class time_zone
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Default constructor.
+ *
+ * This constructor initializes the instance to the 'not specified'
+ * state.
+ */
+ time_zone ();
+
+ /**
+ * @brief Initialize an instance with the hours and minutes
+ * components.
+ *
+ * @param hours The %time zone hours component.
+ * @param minutes The %time zone minutes component.
+ */
+ time_zone (short hours, short minutes);
+
+ //@}
+
+ /**
+ * @brief Determine if %time zone is specified.
+ *
+ * @return True if %time zone is specified, false otherwise.
+ */
+ bool
+ zone_present () const;
+
+ /**
+ * @brief Reset the %time zone to the 'not specified' state.
+ *
+ */
+ void
+ zone_reset ();
+
+ /**
+ * @brief Get the hours component of the %time zone.
+ *
+ * @return The hours component of the %time zone.
+ */
+ short
+ zone_hours () const;
+
+ /**
+ * @brief Set the hours component of the %time zone.
+ *
+ * @param h The new hours component.
+ */
+ void
+ zone_hours (short h);
+
+
+ /**
+ * @brief Get the minutes component of the %time zone.
+ *
+ * @return The minutes component of the %time zone.
+ */
+ short
+ zone_minutes () const;
+
+ /**
+ * @brief Set the minutes component of the %time zone.
+ *
+ * @param m The new minutes component.
+ */
+ void
+ zone_minutes (short m);
+
+ protected:
+ //@cond
+
+ template <typename C>
+ void
+ zone_parse (const C*, std::size_t);
+
+ template <typename S>
+ void
+ zone_extract (istream<S>&);
+
+ //@endcond
+
+ private:
+ bool present_;
+ short hours_;
+ short minutes_;
+ };
+
+ /**
+ * @brief %time_zone comparison operator.
+ *
+ * @return True if both %time zones are either not specified or
+ * have equal hours and minutes components, false otherwise.
+ */
+ bool
+ operator== (const time_zone&, const time_zone&);
+
+ /**
+ * @brief %time_zone comparison operator.
+ *
+ * @return False if both %time zones are either not specified or
+ * have equal hours and minutes components, true otherwise.
+ */
+ bool
+ operator!= (const time_zone&, const time_zone&);
+
+
+ /**
+ * @brief Class corresponding to the XML Schema gDay built-in type.
+ *
+ * The %gday class represents a day of the month with an optional
+ * %time zone.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class gday: public B, public time_zone
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with the day component.
+ *
+ * When this constructor is used, the %time zone is left
+ * unspecified.
+ *
+ * @param day The day component.
+ */
+ explicit
+ gday (unsigned short day);
+
+ /**
+ * @brief Initialize an instance with the day component and %time
+ * zone.
+ *
+ * @param day The day component.
+ * @param zone_hours The %time zone hours component.
+ * @param zone_minutes The %time zone minutes component.
+ */
+ gday (unsigned short day, short zone_hours, short zone_minutes);
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the _clone function instead.
+ */
+ gday (const gday& x, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual gday*
+ _clone (flags f = 0, container* c = 0) const;
+
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ gday (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gday (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gday (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gday (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Get the day component.
+ *
+ * @return The day component.
+ */
+ unsigned short
+ day () const;
+
+ /**
+ * @brief Set the day component.
+ *
+ * @param d The new day component.
+ */
+ void
+ day (unsigned short d);
+
+ protected:
+ //@cond
+
+ gday ();
+
+ void
+ parse (const std::basic_string<C>&);
+
+ //@endcond
+
+ private:
+ unsigned short day_;
+ };
+
+ /**
+ * @brief %gday comparison operator.
+ *
+ * @return True if the day components and %time zones are equal, false
+ * otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator== (const gday<C, B>&, const gday<C, B>&);
+
+ /**
+ * @brief %gday comparison operator.
+ *
+ * @return False if the day components and %time zones are equal, true
+ * otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator!= (const gday<C, B>&, const gday<C, B>&);
+
+ /**
+ * @brief Class corresponding to the XML Schema gMonth built-in type.
+ *
+ * The %gmonth class represents a month of the year with an optional
+ * %time zone.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class gmonth: public B, public time_zone
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with the month component.
+ *
+ * When this constructor is used, the %time zone is left
+ * unspecified.
+ *
+ * @param month The month component.
+ */
+ explicit
+ gmonth (unsigned short month);
+
+ /**
+ * @brief Initialize an instance with the month component and %time
+ * zone.
+ *
+ * @param month The month component.
+ * @param zone_hours The %time zone hours component.
+ * @param zone_minutes The %time zone minutes component.
+ */
+ gmonth (unsigned short month, short zone_hours, short zone_minutes);
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the _clone function instead.
+ */
+ gmonth (const gmonth& x, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual gmonth*
+ _clone (flags f = 0, container* c = 0) const;
+
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ gmonth (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gmonth (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gmonth (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gmonth (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Get the month component.
+ *
+ * @return The month component.
+ */
+ unsigned short
+ month () const;
+
+ /**
+ * @brief Set the month component.
+ *
+ * @param m The new month component.
+ */
+ void
+ month (unsigned short m);
+
+ protected:
+ //@cond
+
+ gmonth ();
+
+ void
+ parse (const std::basic_string<C>&);
+
+ //@endcond
+
+ private:
+ unsigned short month_;
+ };
+
+ /**
+ * @brief %gmonth comparison operator.
+ *
+ * @return True if the month components and %time zones are equal, false
+ * otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator== (const gmonth<C, B>&, const gmonth<C, B>&);
+
+ /**
+ * @brief %gmonth comparison operator.
+ *
+ * @return False if the month components and %time zones are equal, true
+ * otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator!= (const gmonth<C, B>&, const gmonth<C, B>&);
+
+
+ /**
+ * @brief Class corresponding to the XML Schema gYear built-in type.
+ *
+ * The %gyear class represents a year with an optional %time zone.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class gyear: public B, public time_zone
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with the year component.
+ *
+ * When this constructor is used, the %time zone is left
+ * unspecified.
+ *
+ * @param year The year component.
+ */
+ explicit
+ gyear (int year);
+
+ /**
+ * @brief Initialize an instance with the year component and %time
+ * zone.
+ *
+ * @param year The year component.
+ * @param zone_hours The %time zone hours component.
+ * @param zone_minutes The %time zone minutes component.
+ */
+ gyear (int year, short zone_hours, short zone_minutes);
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the _clone function instead.
+ */
+ gyear (const gyear& x, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual gyear*
+ _clone (flags f = 0, container* c = 0) const;
+
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ gyear (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gyear (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gyear (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gyear (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Get the year component.
+ *
+ * @return The year component.
+ */
+ int
+ year () const;
+
+ /**
+ * @brief Set the year component.
+ *
+ * @param y The new year component.
+ */
+ void
+ year (int y);
+
+ protected:
+ //@cond
+
+ gyear ();
+
+ void
+ parse (const std::basic_string<C>&);
+
+ //@endcond
+
+ private:
+ int year_;
+ };
+
+ /**
+ * @brief %gyear comparison operator.
+ *
+ * @return True if the year components and %time zones are equal, false
+ * otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator== (const gyear<C, B>&, const gyear<C, B>&);
+
+ /**
+ * @brief %gyear comparison operator.
+ *
+ * @return False if the year components and %time zones are equal, true
+ * otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator!= (const gyear<C, B>&, const gyear<C, B>&);
+
+
+ /**
+ * @brief Class corresponding to the XML Schema gMonthDay built-in type.
+ *
+ * The %gmonth_day class represents day and month of the year with an
+ * optional %time zone.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class gmonth_day: public B, public time_zone
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with the month and day components.
+ *
+ * When this constructor is used, the %time zone is left
+ * unspecified.
+ *
+ * @param month The month component.
+ * @param day The day component.
+ */
+ gmonth_day (unsigned short month, unsigned short day);
+
+ /**
+ * @brief Initialize an instance with the month and day components
+ * as well as %time zone.
+ *
+ * @param month The month component.
+ * @param day The day component.
+ * @param zone_hours The %time zone hours component.
+ * @param zone_minutes The %time zone minutes component.
+ */
+ gmonth_day (unsigned short month, unsigned short day,
+ short zone_hours, short zone_minutes);
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the _clone function instead.
+ */
+ gmonth_day (const gmonth_day& x, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual gmonth_day*
+ _clone (flags f = 0, container* c = 0) const;
+
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ gmonth_day (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gmonth_day (const xercesc::DOMElement& e,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gmonth_day (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gmonth_day (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Get the month component.
+ *
+ * @return The month component.
+ */
+ unsigned short
+ month () const;
+
+ /**
+ * @brief Set the month component.
+ *
+ * @param m The new month component.
+ */
+ void
+ month (unsigned short m);
+
+ /**
+ * @brief Get the day component.
+ *
+ * @return The day component.
+ */
+ unsigned short
+ day () const;
+
+ /**
+ * @brief Set the day component.
+ *
+ * @param d The new day component.
+ */
+ void
+ day (unsigned short d);
+
+ protected:
+ //@cond
+
+ gmonth_day ();
+
+ void
+ parse (const std::basic_string<C>&);
+
+ //@endcond
+
+ private:
+ unsigned short month_;
+ unsigned short day_;
+ };
+
+ /**
+ * @brief %gmonth_day comparison operator.
+ *
+ * @return True if the month and day components as well as %time zones
+ * are equal, false otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator== (const gmonth_day<C, B>&, const gmonth_day<C, B>&);
+
+ /**
+ * @brief %gmonth_day comparison operator.
+ *
+ * @return False if the month and day components as well as %time zones
+ * are equal, true otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator!= (const gmonth_day<C, B>&, const gmonth_day<C, B>&);
+
+
+ /**
+ * @brief Class corresponding to the XML Schema gYearMonth built-in
+ * type.
+ *
+ * The %gyear_month class represents year and month with an optional
+ * %time zone.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class gyear_month: public B, public time_zone
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with the year and month components.
+ *
+ * When this constructor is used, the %time zone is left
+ * unspecified.
+ *
+ * @param year The year component.
+ * @param month The month component.
+ */
+ gyear_month (int year, unsigned short month);
+
+ /**
+ * @brief Initialize an instance with the year and month components
+ * as well as %time zone.
+ *
+ * @param year The year component.
+ * @param month The month component.
+ * @param zone_hours The %time zone hours component.
+ * @param zone_minutes The %time zone minutes component.
+ */
+ gyear_month (int year, unsigned short month,
+ short zone_hours, short zone_minutes);
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the _clone function instead.
+ */
+ gyear_month (const gyear_month& x, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual gyear_month*
+ _clone (flags f = 0, container* c = 0) const;
+
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ gyear_month (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gyear_month (const xercesc::DOMElement& e,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gyear_month (const xercesc::DOMAttr& a,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ gyear_month (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Get the year component.
+ *
+ * @return The year component.
+ */
+ int
+ year () const;
+
+ /**
+ * @brief Set the year component.
+ *
+ * @param y The new year component.
+ */
+ void
+ year (int y);
+
+ /**
+ * @brief Get the month component.
+ *
+ * @return The month component.
+ */
+ unsigned short
+ month () const;
+
+ /**
+ * @brief Set the month component.
+ *
+ * @param m The new month component.
+ */
+ void
+ month (unsigned short m);
+
+ protected:
+ //@cond
+
+ gyear_month ();
+
+ void
+ parse (const std::basic_string<C>&);
+
+ //@endcond
+
+ private:
+ int year_;
+ unsigned short month_;
+ };
+
+ /**
+ * @brief %gyear_month comparison operator.
+ *
+ * @return True if the year and month components as well as %time zones
+ * are equal, false otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator== (const gyear_month<C, B>&, const gyear_month<C, B>&);
+
+ /**
+ * @brief %gyear_month comparison operator.
+ *
+ * @return False if the year and month components as well as %time zones
+ * are equal, true otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator!= (const gyear_month<C, B>&, const gyear_month<C, B>&);
+
+
+ /**
+ * @brief Class corresponding to the XML Schema %date built-in type.
+ *
+ * The %date class represents day, month, and year with an optional
+ * %time zone.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class date: public B, public time_zone
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with the year, month, and day
+ * components.
+ *
+ * When this constructor is used, the %time zone is left
+ * unspecified.
+ *
+ * @param year The year component.
+ * @param month The month component.
+ * @param day The day component.
+ */
+ date (int year, unsigned short month, unsigned short day);
+
+ /**
+ * @brief Initialize an instance with the year, month, and day
+ * components as well as %time zone.
+ *
+ * @param year The year component.
+ * @param month The month component.
+ * @param day The day component.
+ * @param zone_hours The %time zone hours component.
+ * @param zone_minutes The %time zone minutes component.
+ */
+ date (int year, unsigned short month, unsigned short day,
+ short zone_hours, short zone_minutes);
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the _clone function instead.
+ */
+ date (const date& x, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual date*
+ _clone (flags f = 0, container* c = 0) const;
+
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ date (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ date (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ date (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ date (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Get the year component.
+ *
+ * @return The year component.
+ */
+ int
+ year () const;
+
+ /**
+ * @brief Set the year component.
+ *
+ * @param y The new year component.
+ */
+ void
+ year (int y);
+
+ /**
+ * @brief Get the month component.
+ *
+ * @return The month component.
+ */
+ unsigned short
+ month () const;
+
+ /**
+ * @brief Set the month component.
+ *
+ * @param m The new month component.
+ */
+ void
+ month (unsigned short m);
+
+ /**
+ * @brief Get the day component.
+ *
+ * @return The day component.
+ */
+ unsigned short
+ day () const;
+
+ /**
+ * @brief Set the day component.
+ *
+ * @param d The new day component.
+ */
+ void
+ day (unsigned short d);
+
+ protected:
+ //@cond
+
+ date ();
+
+ void
+ parse (const std::basic_string<C>&);
+
+ //@endcond
+
+ private:
+ int year_;
+ unsigned short month_;
+ unsigned short day_;
+ };
+
+ /**
+ * @brief %date comparison operator.
+ *
+ * @return True if the year, month, and day components as well as %time
+ * zones are equal, false otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator== (const date<C, B>&, const date<C, B>&);
+
+ /**
+ * @brief %date comparison operator.
+ *
+ * @return False if the year, month, and day components as well as %time
+ * zones are equal, true otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator!= (const date<C, B>&, const date<C, B>&);
+
+
+ /**
+ * @brief Class corresponding to the XML Schema %time built-in type.
+ *
+ * The %time class represents hours, minutes, and seconds with an
+ * optional %time zone.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class time: public B, public time_zone
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with the hours, minutes, and
+ * seconds components.
+ *
+ * When this constructor is used, the %time zone is left
+ * unspecified.
+ *
+ * @param hours The hours component.
+ * @param minutes The minutes component.
+ * @param seconds The seconds component.
+ */
+ time (unsigned short hours, unsigned short minutes, double seconds);
+
+ /**
+ * @brief Initialize an instance with the hours, minutes, and
+ * seconds components as well as %time zone.
+ *
+ * @param hours The hours component.
+ * @param minutes The minutes component.
+ * @param seconds The seconds component.
+ * @param zone_hours The %time zone hours component.
+ * @param zone_minutes The %time zone minutes component.
+ */
+ time (unsigned short hours, unsigned short minutes, double seconds,
+ short zone_hours, short zone_minutes);
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the _clone function instead.
+ */
+ time (const time& x, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual time*
+ _clone (flags f = 0, container* c = 0) const;
+
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ time (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ time (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ time (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ time (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Get the hours component.
+ *
+ * @return The hours component.
+ */
+ unsigned short
+ hours () const;
+
+ /**
+ * @brief Set the hours component.
+ *
+ * @param h The new hours component.
+ */
+ void
+ hours (unsigned short h);
+
+ /**
+ * @brief Get the minutes component.
+ *
+ * @return The minutes component.
+ */
+ unsigned short
+ minutes () const;
+
+ /**
+ * @brief Set the minutes component.
+ *
+ * @param m The new minutes component.
+ */
+ void
+ minutes (unsigned short m);
+
+ /**
+ * @brief Get the seconds component.
+ *
+ * @return The seconds component.
+ */
+ double
+ seconds () const;
+
+ /**
+ * @brief Set the seconds component.
+ *
+ * @param s The new seconds component.
+ */
+ void
+ seconds (double s);
+
+ protected:
+ //@cond
+
+ time ();
+
+ void
+ parse (const std::basic_string<C>&);
+
+ //@endcond
+
+ private:
+ unsigned short hours_;
+ unsigned short minutes_;
+ double seconds_;
+ };
+
+ /**
+ * @brief %time comparison operator.
+ *
+ * @return True if the hours, seconds, and minutes components as well
+ * as %time zones are equal, false otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator== (const time<C, B>&, const time<C, B>&);
+
+ /**
+ * @brief %time comparison operator.
+ *
+ * @return False if the hours, seconds, and minutes components as well
+ * as %time zones are equal, true otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator!= (const time<C, B>&, const time<C, B>&);
+
+
+ /**
+ * @brief Class corresponding to the XML Schema dateTime built-in type.
+ *
+ * The %date_time class represents year, month, day, hours, minutes,
+ * and seconds with an optional %time zone.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class date_time: public B, public time_zone
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with the year, month, day, hours,
+ * minutes, and seconds components.
+ *
+ * When this constructor is used, the %time zone is left
+ * unspecified.
+ *
+ * @param year The year component.
+ * @param month The month component.
+ * @param day The day component.
+ * @param hours The hours component.
+ * @param minutes The minutes component.
+ * @param seconds The seconds component.
+ */
+ date_time (int year, unsigned short month, unsigned short day,
+ unsigned short hours, unsigned short minutes,
+ double seconds);
+
+ /**
+ * @brief Initialize an instance with the year, month, day, hours,
+ * minutes, and seconds components as well as %time zone.
+ *
+ * @param year The year component.
+ * @param month The month component.
+ * @param day The day component.
+ * @param hours The hours component.
+ * @param minutes The minutes component.
+ * @param seconds The seconds component.
+ * @param zone_hours The %time zone hours component.
+ * @param zone_minutes The %time zone minutes component.
+ */
+ date_time (int year, unsigned short month, unsigned short day,
+ unsigned short hours, unsigned short minutes,
+ double seconds, short zone_hours, short zone_minutes);
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the _clone function instead.
+ */
+ date_time (const date_time& x, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual date_time*
+ _clone (flags f = 0, container* c = 0) const;
+
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ date_time (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ date_time (const xercesc::DOMElement& e,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ date_time (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ date_time (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Get the year component.
+ *
+ * @return The year component.
+ */
+ int
+ year () const;
+
+ /**
+ * @brief Set the year component.
+ *
+ * @param y The new year component.
+ */
+ void
+ year (int y);
+
+ /**
+ * @brief Get the month component.
+ *
+ * @return The month component.
+ */
+ unsigned short
+ month () const;
+
+ /**
+ * @brief Set the month component.
+ *
+ * @param m The new month component.
+ */
+ void
+ month (unsigned short m);
+
+ /**
+ * @brief Get the day component.
+ *
+ * @return The day component.
+ */
+ unsigned short
+ day () const;
+
+ /**
+ * @brief Set the day component.
+ *
+ * @param d The new day component.
+ */
+ void
+ day (unsigned short d);
+
+ /**
+ * @brief Get the hours component.
+ *
+ * @return The hours component.
+ */
+ unsigned short
+ hours () const;
+
+ /**
+ * @brief Set the hours component.
+ *
+ * @param h The new hours component.
+ */
+ void
+ hours (unsigned short h);
+
+ /**
+ * @brief Get the minutes component.
+ *
+ * @return The minutes component.
+ */
+ unsigned short
+ minutes () const;
+
+ /**
+ * @brief Set the minutes component.
+ *
+ * @param m The new minutes component.
+ */
+ void
+ minutes (unsigned short m);
+
+ /**
+ * @brief Get the seconds component.
+ *
+ * @return The seconds component.
+ */
+ double
+ seconds () const;
+
+ /**
+ * @brief Set the seconds component.
+ *
+ * @param s The new seconds component.
+ */
+ void
+ seconds (double s);
+
+ protected:
+ //@cond
+
+ date_time ();
+
+ void
+ parse (const std::basic_string<C>&);
+
+ //@endcond
+
+ private:
+ int year_;
+ unsigned short month_;
+ unsigned short day_;
+ unsigned short hours_;
+ unsigned short minutes_;
+ double seconds_;
+ };
+
+ /**
+ * @brief %date_time comparison operator.
+ *
+ * @return True if the year, month, day, hours, seconds, and minutes
+ * components as well as %time zones are equal, false otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator== (const date_time<C, B>&, const date_time<C, B>&);
+
+ /**
+ * @brief %date_time comparison operator.
+ *
+ * @return False if the year, month, day, hours, seconds, and minutes
+ * components as well as %time zones are equal, true otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator!= (const date_time<C, B>&, const date_time<C, B>&);
+
+
+ /**
+ * @brief Class corresponding to the XML Schema %duration built-in type.
+ *
+ * The %duration class represents a potentially negative %duration in
+ * the form of years, months, days, hours, minutes, and seconds.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class duration: public B
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+ /**
+ * @brief Initialize a potentially negative instance with the years,
+ * months, days, hours, minutes, and seconds components.
+ *
+ * @param negative A boolean value indicating whether the %duration
+ * is negative (true) or positive (false).
+ * @param years The years component.
+ * @param months The months component.
+ * @param days The days component.
+ * @param hours The hours component.
+ * @param minutes The minutes component.
+ * @param seconds The seconds component.
+ */
+ duration (bool negative,
+ unsigned int years, unsigned int months, unsigned int days,
+ unsigned int hours, unsigned int minutes, double seconds);
+
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the _clone function instead.
+ */
+ duration (const duration& x, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual duration*
+ _clone (flags f = 0, container* c = 0) const;
+
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ duration (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ duration (const xercesc::DOMElement& e,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ duration (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ duration (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Determine if %duration is negative.
+ *
+ * @return True if %duration is negative, false otherwise.
+ */
+ bool
+ negative () const;
+
+ /**
+ * @brief Change %duration sign.
+ *
+ * @param n A boolean value indicating whether %duration is
+ * negative (true) or positive (false).
+ */
+ void
+ negative (bool n);
+
+ /**
+ * @brief Get the years component.
+ *
+ * @return The years component.
+ */
+ unsigned int
+ years () const;
+
+ /**
+ * @brief Set the years component.
+ *
+ * @param y The new years component.
+ */
+ void
+ years (unsigned int y);
+
+ /**
+ * @brief Get the months component.
+ *
+ * @return The months component.
+ */
+ unsigned int
+ months () const;
+
+ /**
+ * @brief Set the months component.
+ *
+ * @param m The new months component.
+ */
+ void
+ months (unsigned int m);
+
+ /**
+ * @brief Get the days component.
+ *
+ * @return The days component.
+ */
+ unsigned int
+ days () const;
+
+ /**
+ * @brief Set the days component.
+ *
+ * @param d The new days component.
+ */
+ void
+ days (unsigned int d);
+
+ /**
+ * @brief Get the hours component.
+ *
+ * @return The hours component.
+ */
+ unsigned int
+ hours () const;
+
+ /**
+ * @brief Set the hours component.
+ *
+ * @param h The new hours component.
+ */
+ void
+ hours (unsigned int h);
+
+ /**
+ * @brief Get the minutes component.
+ *
+ * @return The minutes component.
+ */
+ unsigned int
+ minutes () const;
+
+ /**
+ * @brief Set the minutes component.
+ *
+ * @param m The new minutes component.
+ */
+ void
+ minutes (unsigned int m);
+
+ /**
+ * @brief Get the seconds component.
+ *
+ * @return The seconds component.
+ */
+ double
+ seconds () const;
+
+ /**
+ * @brief Set the seconds component.
+ *
+ * @param s The new seconds component.
+ */
+ void
+ seconds (double s);
+
+ protected:
+ //@cond
+
+ duration ();
+
+ void
+ parse (const std::basic_string<C>&);
+
+ //@endcond
+
+ private:
+ bool negative_;
+ unsigned int years_;
+ unsigned int months_;
+ unsigned int days_;
+ unsigned int hours_;
+ unsigned int minutes_;
+ double seconds_;
+ };
+
+ /**
+ * @brief %duration comparison operator.
+ *
+ * @return True if the sings as well as years, months, days, hours,
+ * seconds, and minutes components are equal, false otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator== (const duration<C, B>&, const duration<C, B>&);
+
+ /**
+ * @brief %duration comparison operator.
+ *
+ * @return False if the sings as well as years, months, days, hours,
+ * seconds, and minutes components are equal, true otherwise.
+ */
+ template <typename C, typename B>
+ bool
+ operator!= (const duration<C, B>&, const duration<C, B>&);
+ }
+ }
+}
+
+#include <xsd/cxx/tree/date-time.ixx>
+#include <xsd/cxx/tree/date-time.txx>
+
+#endif // XSD_CXX_TREE_DATE_TIME_HXX
diff --git a/libxsd/xsd/cxx/tree/date-time.ixx b/libxsd/xsd/cxx/tree/date-time.ixx
new file mode 100644
index 0000000..7398bd3
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/date-time.ixx
@@ -0,0 +1,893 @@
+// file : xsd/cxx/tree/date-time.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // time_zone
+ //
+ inline time_zone::
+ time_zone ()
+ : present_ (false)
+ {
+ }
+
+ inline time_zone::
+ time_zone (short h, short m)
+ : present_ (true), hours_ (h), minutes_ (m)
+ {
+ }
+
+ inline bool time_zone::
+ zone_present () const
+ {
+ return present_;
+ }
+
+ inline void time_zone::
+ zone_reset ()
+ {
+ present_ = false;
+ }
+
+ inline short time_zone::
+ zone_hours () const
+ {
+ return hours_;
+ }
+
+ inline void time_zone::
+ zone_hours (short h)
+ {
+ hours_ = h;
+ present_ = true;
+ }
+
+ inline short time_zone::
+ zone_minutes () const
+ {
+ return minutes_;
+ }
+
+ inline void time_zone::
+ zone_minutes (short m)
+ {
+ minutes_ = m;
+ present_ = true;
+ }
+
+ inline bool
+ operator== (const time_zone& x, const time_zone& y)
+ {
+ return x.zone_present ()
+ ? y.zone_present () &&
+ x.zone_hours () == y.zone_hours () &&
+ x.zone_minutes () == y.zone_minutes ()
+ : !y.zone_present ();
+ }
+
+ inline bool
+ operator!= (const time_zone& x, const time_zone& y)
+ {
+ return !(x == y);
+ }
+
+ // gday
+ //
+ template <typename C, typename B>
+ inline gday<C, B>::
+ gday ()
+ {
+ }
+
+ template <typename C, typename B>
+ inline gday<C, B>::
+ gday (unsigned short day)
+ : day_ (day)
+ {
+ }
+
+ template <typename C, typename B>
+ inline gday<C, B>::
+ gday (unsigned short day, short zone_h, short zone_m)
+ : time_zone (zone_h, zone_m), day_ (day)
+ {
+ }
+
+ template <typename C, typename B>
+ inline gday<C, B>::
+ gday (const gday& x, flags f, container* c)
+ : B (x, f, c), time_zone (x), day_ (x.day_)
+ {
+ }
+
+ template <typename C, typename B>
+ inline unsigned short gday<C, B>::
+ day () const
+ {
+ return day_;
+ }
+
+ template <typename C, typename B>
+ inline void gday<C, B>::
+ day (unsigned short day)
+ {
+ day_ = day;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator== (const gday<C, B>& x, const gday<C, B>& y)
+ {
+ const time_zone& xz = x;
+ const time_zone& yz = y;
+
+ return x.day () == y.day () && xz == yz;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator!= (const gday<C, B>& x, const gday<C, B>& y)
+ {
+ return !(x == y);
+ }
+
+ // gmonth
+ //
+ template <typename C, typename B>
+ inline gmonth<C, B>::
+ gmonth ()
+ {
+ }
+
+ template <typename C, typename B>
+ inline gmonth<C, B>::
+ gmonth (unsigned short month)
+ : month_ (month)
+ {
+ }
+
+ template <typename C, typename B>
+ inline gmonth<C, B>::
+ gmonth (unsigned short month, short zone_h, short zone_m)
+ : time_zone (zone_h, zone_m), month_ (month)
+ {
+ }
+
+ template <typename C, typename B>
+ inline gmonth<C, B>::
+ gmonth (const gmonth& x, flags f, container* c)
+ : B (x, f, c), time_zone (x), month_ (x.month_)
+ {
+ }
+
+ template <typename C, typename B>
+ inline unsigned short gmonth<C, B>::
+ month () const
+ {
+ return month_;
+ }
+
+ template <typename C, typename B>
+ inline void gmonth<C, B>::
+ month (unsigned short month)
+ {
+ month_ = month;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator== (const gmonth<C, B>& x, const gmonth<C, B>& y)
+ {
+ const time_zone& xz = x;
+ const time_zone& yz = y;
+
+ return x.month () == y.month () && xz == yz;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator!= (const gmonth<C, B>& x, const gmonth<C, B>& y)
+ {
+ return !(x == y);
+ }
+
+ // gyear
+ //
+ template <typename C, typename B>
+ inline gyear<C, B>::
+ gyear ()
+ {
+ }
+
+ template <typename C, typename B>
+ inline gyear<C, B>::
+ gyear (int year)
+ : year_ (year)
+ {
+ }
+
+ template <typename C, typename B>
+ inline gyear<C, B>::
+ gyear (int year, short zone_h, short zone_m)
+ : time_zone (zone_h, zone_m), year_ (year)
+ {
+ }
+
+ template <typename C, typename B>
+ inline gyear<C, B>::
+ gyear (const gyear& x, flags f, container* c)
+ : B (x, f, c), time_zone (x), year_ (x.year_)
+ {
+ }
+
+ template <typename C, typename B>
+ inline int gyear<C, B>::
+ year () const
+ {
+ return year_;
+ }
+
+ template <typename C, typename B>
+ inline void gyear<C, B>::
+ year (int year)
+ {
+ year_ = year;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator== (const gyear<C, B>& x, const gyear<C, B>& y)
+ {
+ const time_zone& xz = x;
+ const time_zone& yz = y;
+
+ return x.year () == y.year () && xz == yz;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator!= (const gyear<C, B>& x, const gyear<C, B>& y)
+ {
+ return !(x == y);
+ }
+
+ // gmonth_day
+ //
+ template <typename C, typename B>
+ inline gmonth_day<C, B>::
+ gmonth_day ()
+ {
+ }
+
+ template <typename C, typename B>
+ inline gmonth_day<C, B>::
+ gmonth_day (unsigned short month, unsigned short day)
+ : month_ (month), day_ (day)
+ {
+ }
+
+ template <typename C, typename B>
+ inline gmonth_day<C, B>::
+ gmonth_day (unsigned short month, unsigned short day,
+ short zone_h, short zone_m)
+ : time_zone (zone_h, zone_m), month_ (month), day_ (day)
+ {
+ }
+
+ template <typename C, typename B>
+ inline gmonth_day<C, B>::
+ gmonth_day (const gmonth_day& x, flags f, container* c)
+ : B (x, f, c), time_zone (x), month_ (x.month_), day_ (x.day_)
+ {
+ }
+
+ template <typename C, typename B>
+ inline unsigned short gmonth_day<C, B>::
+ month () const
+ {
+ return month_;
+ }
+
+ template <typename C, typename B>
+ inline void gmonth_day<C, B>::
+ month (unsigned short month)
+ {
+ month_ = month;
+ }
+
+ template <typename C, typename B>
+ inline unsigned short gmonth_day<C, B>::
+ day () const
+ {
+ return day_;
+ }
+
+ template <typename C, typename B>
+ inline void gmonth_day<C, B>::
+ day (unsigned short day)
+ {
+ day_ = day;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator== (const gmonth_day<C, B>& x, const gmonth_day<C, B>& y)
+ {
+ const time_zone& xz = x;
+ const time_zone& yz = y;
+
+ return x.month () == y.month () &&
+ x.day () == y.day () &&
+ xz == yz;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator!= (const gmonth_day<C, B>& x, const gmonth_day<C, B>& y)
+ {
+ return !(x == y);
+ }
+
+ // gyear_month
+ //
+ template <typename C, typename B>
+ inline gyear_month<C, B>::
+ gyear_month ()
+ {
+ }
+
+ template <typename C, typename B>
+ inline gyear_month<C, B>::
+ gyear_month (int year, unsigned short month)
+ : year_ (year), month_ (month)
+ {
+ }
+
+ template <typename C, typename B>
+ inline gyear_month<C, B>::
+ gyear_month (int year, unsigned short month,
+ short zone_h, short zone_m)
+ : time_zone (zone_h, zone_m), year_ (year), month_ (month)
+ {
+ }
+
+ template <typename C, typename B>
+ inline gyear_month<C, B>::
+ gyear_month (const gyear_month& x, flags f, container* c)
+ : B (x, f, c), time_zone (x), year_ (x.year_), month_ (x.month_)
+ {
+ }
+
+ template <typename C, typename B>
+ inline int gyear_month<C, B>::
+ year () const
+ {
+ return year_;
+ }
+
+ template <typename C, typename B>
+ inline void gyear_month<C, B>::
+ year (int year)
+ {
+ year_ = year;
+ }
+
+ template <typename C, typename B>
+ inline unsigned short gyear_month<C, B>::
+ month () const
+ {
+ return month_;
+ }
+
+ template <typename C, typename B>
+ inline void gyear_month<C, B>::
+ month (unsigned short month)
+ {
+ month_ = month;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator== (const gyear_month<C, B>& x, const gyear_month<C, B>& y)
+ {
+ const time_zone& xz = x;
+ const time_zone& yz = y;
+
+ return x.year () == y.year () &&
+ x.month () == y.month () &&
+ xz == yz;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator!= (const gyear_month<C, B>& x, const gyear_month<C, B>& y)
+ {
+ return !(x == y);
+ }
+
+ // date
+ //
+ template <typename C, typename B>
+ inline date<C, B>::
+ date ()
+ {
+ }
+
+ template <typename C, typename B>
+ inline date<C, B>::
+ date (int year, unsigned short month, unsigned short day)
+ : year_ (year), month_ (month), day_ (day)
+ {
+ }
+
+ template <typename C, typename B>
+ inline date<C, B>::
+ date (int year, unsigned short month, unsigned short day,
+ short zone_h, short zone_m)
+ : time_zone (zone_h, zone_m),
+ year_ (year), month_ (month), day_ (day)
+ {
+ }
+
+ template <typename C, typename B>
+ inline date<C, B>::
+ date (const date& x, flags f, container* c)
+ : B (x, f, c), time_zone (x),
+ year_ (x.year_), month_ (x.month_), day_ (x.day_)
+ {
+ }
+
+ template <typename C, typename B>
+ inline int date<C, B>::
+ year () const
+ {
+ return year_;
+ }
+
+ template <typename C, typename B>
+ inline void date<C, B>::
+ year (int year)
+ {
+ year_ = year;
+ }
+
+ template <typename C, typename B>
+ inline unsigned short date<C, B>::
+ month () const
+ {
+ return month_;
+ }
+
+ template <typename C, typename B>
+ inline void date<C, B>::
+ month (unsigned short month)
+ {
+ month_ = month;
+ }
+
+ template <typename C, typename B>
+ inline unsigned short date<C, B>::
+ day () const
+ {
+ return day_;
+ }
+
+ template <typename C, typename B>
+ inline void date<C, B>::
+ day (unsigned short day)
+ {
+ day_ = day;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator== (const date<C, B>& x, const date<C, B>& y)
+ {
+ const time_zone& xz = x;
+ const time_zone& yz = y;
+
+ return x.year () == y.year () &&
+ x.month () == y.month () &&
+ x.day () == y.day () &&
+ xz == yz;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator!= (const date<C, B>& x, const date<C, B>& y)
+ {
+ return !(x == y);
+ }
+
+ // time
+ //
+ template <typename C, typename B>
+ inline time<C, B>::
+ time ()
+ {
+ }
+
+ template <typename C, typename B>
+ inline time<C, B>::
+ time (unsigned short hours, unsigned short minutes, double seconds)
+ : hours_ (hours), minutes_ (minutes), seconds_ (seconds)
+ {
+ }
+
+ template <typename C, typename B>
+ inline time<C, B>::
+ time (unsigned short hours, unsigned short minutes, double seconds,
+ short zone_h, short zone_m)
+ : time_zone (zone_h, zone_m),
+ hours_ (hours), minutes_ (minutes), seconds_ (seconds)
+ {
+ }
+
+ template <typename C, typename B>
+ inline time<C, B>::
+ time (const time& x, flags f, container* c)
+ : B (x, f, c), time_zone (x),
+ hours_ (x.hours_), minutes_ (x.minutes_), seconds_ (x.seconds_)
+ {
+ }
+
+ template <typename C, typename B>
+ inline unsigned short time<C, B>::
+ hours () const
+ {
+ return hours_;
+ }
+
+ template <typename C, typename B>
+ inline void time<C, B>::
+ hours (unsigned short hours)
+ {
+ hours_ = hours;
+ }
+
+ template <typename C, typename B>
+ inline unsigned short time<C, B>::
+ minutes () const
+ {
+ return minutes_;
+ }
+
+ template <typename C, typename B>
+ inline void time<C, B>::
+ minutes (unsigned short minutes)
+ {
+ minutes_ = minutes;
+ }
+
+ template <typename C, typename B>
+ inline double time<C, B>::
+ seconds () const
+ {
+ return seconds_;
+ }
+
+ template <typename C, typename B>
+ inline void time<C, B>::
+ seconds (double seconds)
+ {
+ seconds_ = seconds;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator== (const time<C, B>& x, const time<C, B>& y)
+ {
+ const time_zone& xz = x;
+ const time_zone& yz = y;
+
+ return x.hours () == y.hours () &&
+ x.minutes () == y.minutes () &&
+ x.seconds () == y.seconds () &&
+ xz == yz;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator!= (const time<C, B>& x, const time<C, B>& y)
+ {
+ return !(x == y);
+ }
+
+ // date_time
+ //
+ template <typename C, typename B>
+ inline date_time<C, B>::
+ date_time ()
+ {
+ }
+
+ template <typename C, typename B>
+ inline date_time<C, B>::
+ date_time (int year, unsigned short month, unsigned short day,
+ unsigned short hours, unsigned short minutes, double seconds)
+ : year_ (year), month_ (month), day_ (day),
+ hours_ (hours), minutes_ (minutes), seconds_ (seconds)
+ {
+ }
+
+ template <typename C, typename B>
+ inline date_time<C, B>::
+ date_time (int year, unsigned short month, unsigned short day,
+ unsigned short hours, unsigned short minutes, double seconds,
+ short zone_h, short zone_m)
+ : time_zone (zone_h, zone_m),
+ year_ (year), month_ (month), day_ (day),
+ hours_ (hours), minutes_ (minutes), seconds_ (seconds)
+ {
+ }
+
+ template <typename C, typename B>
+ inline date_time<C, B>::
+ date_time (const date_time& x, flags f, container* c)
+ : B (x, f, c), time_zone (x),
+ year_ (x.year_), month_ (x.month_), day_ (x.day_),
+ hours_ (x.hours_), minutes_ (x.minutes_), seconds_ (x.seconds_)
+ {
+ }
+
+ template <typename C, typename B>
+ inline int date_time<C, B>::
+ year () const
+ {
+ return year_;
+ }
+
+ template <typename C, typename B>
+ inline void date_time<C, B>::
+ year (int year)
+ {
+ year_ = year;
+ }
+
+ template <typename C, typename B>
+ inline unsigned short date_time<C, B>::
+ month () const
+ {
+ return month_;
+ }
+
+ template <typename C, typename B>
+ inline void date_time<C, B>::
+ month (unsigned short month)
+ {
+ month_ = month;
+ }
+
+ template <typename C, typename B>
+ inline unsigned short date_time<C, B>::
+ day () const
+ {
+ return day_;
+ }
+
+ template <typename C, typename B>
+ inline void date_time<C, B>::
+ day (unsigned short day)
+ {
+ day_ = day;
+ }
+
+ template <typename C, typename B>
+ inline unsigned short date_time<C, B>::
+ hours () const
+ {
+ return hours_;
+ }
+
+ template <typename C, typename B>
+ inline void date_time<C, B>::
+ hours (unsigned short hours)
+ {
+ hours_ = hours;
+ }
+
+ template <typename C, typename B>
+ inline unsigned short date_time<C, B>::
+ minutes () const
+ {
+ return minutes_;
+ }
+
+ template <typename C, typename B>
+ inline void date_time<C, B>::
+ minutes (unsigned short minutes)
+ {
+ minutes_ = minutes;
+ }
+
+ template <typename C, typename B>
+ inline double date_time<C, B>::
+ seconds () const
+ {
+ return seconds_;
+ }
+
+ template <typename C, typename B>
+ inline void date_time<C, B>::
+ seconds (double seconds)
+ {
+ seconds_ = seconds;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator== (const date_time<C, B>& x, const date_time<C, B>& y)
+ {
+ const time_zone& xz = x;
+ const time_zone& yz = y;
+
+ return x.year () == y.year () &&
+ x.month () == y.month () &&
+ x.day () == y.day () &&
+ x.hours () == y.hours () &&
+ x.minutes () == y.minutes () &&
+ x.seconds () == y.seconds () &&
+ xz == yz;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator!= (const date_time<C, B>& x, const date_time<C, B>& y)
+ {
+ return !(x == y);
+ }
+
+ // duration
+ //
+ template <typename C, typename B>
+ inline duration<C, B>::
+ duration ()
+ {
+ }
+
+ template <typename C, typename B>
+ inline duration<C, B>::
+ duration (bool negative,
+ unsigned int years, unsigned int months, unsigned int days,
+ unsigned int hours, unsigned int minutes, double seconds)
+ : negative_ (negative),
+ years_ (years), months_ (months), days_ (days),
+ hours_ (hours), minutes_ (minutes), seconds_ (seconds)
+ {
+ }
+
+ template <typename C, typename B>
+ inline duration<C, B>::
+ duration (const duration& x, flags f, container* c)
+ : B (x, f, c), negative_ (x.negative_),
+ years_ (x.years_), months_ (x.months_), days_ (x.days_),
+ hours_ (x.hours_), minutes_ (x.minutes_), seconds_ (x.seconds_)
+ {
+ }
+
+ template <typename C, typename B>
+ inline bool duration<C, B>::
+ negative () const
+ {
+ return negative_;
+ }
+
+ template <typename C, typename B>
+ inline void duration<C, B>::
+ negative (bool negative)
+ {
+ negative_ = negative;
+ }
+
+ template <typename C, typename B>
+ inline unsigned int duration<C, B>::
+ years () const
+ {
+ return years_;
+ }
+
+ template <typename C, typename B>
+ inline void duration<C, B>::
+ years (unsigned int years)
+ {
+ years_ = years;
+ }
+
+ template <typename C, typename B>
+ inline unsigned int duration<C, B>::
+ months () const
+ {
+ return months_;
+ }
+
+ template <typename C, typename B>
+ inline void duration<C, B>::
+ months (unsigned int months)
+ {
+ months_ = months;
+ }
+
+ template <typename C, typename B>
+ inline unsigned int duration<C, B>::
+ days () const
+ {
+ return days_;
+ }
+
+ template <typename C, typename B>
+ inline void duration<C, B>::
+ days (unsigned int days)
+ {
+ days_ = days;
+ }
+
+ template <typename C, typename B>
+ inline unsigned int duration<C, B>::
+ hours () const
+ {
+ return hours_;
+ }
+
+ template <typename C, typename B>
+ inline void duration<C, B>::
+ hours (unsigned int hours)
+ {
+ hours_ = hours;
+ }
+
+ template <typename C, typename B>
+ inline unsigned int duration<C, B>::
+ minutes () const
+ {
+ return minutes_;
+ }
+
+ template <typename C, typename B>
+ inline void duration<C, B>::
+ minutes (unsigned int minutes)
+ {
+ minutes_ = minutes;
+ }
+
+ template <typename C, typename B>
+ inline double duration<C, B>::
+ seconds () const
+ {
+ return seconds_;
+ }
+
+ template <typename C, typename B>
+ inline void duration<C, B>::
+ seconds (double seconds)
+ {
+ seconds_ = seconds;
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator== (const duration<C, B>& x, const duration<C, B>& y)
+ {
+ return x.negative () == y.negative () &&
+ x.years () == y.years () &&
+ x.months () == y.months () &&
+ x.days () == y.days () &&
+ x.hours () == y.hours () &&
+ x.minutes () == y.minutes () &&
+ x.seconds () == y.seconds ();
+ }
+
+ template <typename C, typename B>
+ inline bool
+ operator!= (const duration<C, B>& x, const duration<C, B>& y)
+ {
+ return !(x == y);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/date-time.txx b/libxsd/xsd/cxx/tree/date-time.txx
new file mode 100644
index 0000000..673efe4
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/date-time.txx
@@ -0,0 +1,94 @@
+// file : xsd/cxx/tree/date-time.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // gday
+ //
+ template <typename C, typename B>
+ gday<C, B>* gday<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new gday (*this, f, c);
+ }
+
+ // gmonth
+ //
+ template <typename C, typename B>
+ gmonth<C, B>* gmonth<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new gmonth (*this, f, c);
+ }
+
+ // gyear
+ //
+ template <typename C, typename B>
+ gyear<C, B>* gyear<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new gyear (*this, f, c);
+ }
+
+ // gmonth_day
+ //
+ template <typename C, typename B>
+ gmonth_day<C, B>* gmonth_day<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new gmonth_day (*this, f, c);
+ }
+
+ // gyear_month
+ //
+ template <typename C, typename B>
+ gyear_month<C, B>* gyear_month<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new gyear_month (*this, f, c);
+ }
+
+ // date
+ //
+ template <typename C, typename B>
+ date<C, B>* date<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new date (*this, f, c);
+ }
+
+ // time
+ //
+ template <typename C, typename B>
+ time<C, B>* time<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new time (*this, f, c);
+ }
+
+ // date_time
+ //
+ template <typename C, typename B>
+ date_time<C, B>* date_time<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new date_time (*this, f, c);
+ }
+
+ // duration
+ //
+ template <typename C, typename B>
+ duration<C, B>* duration<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new duration (*this, f, c);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/element-map.hxx b/libxsd/xsd/cxx/tree/element-map.hxx
new file mode 100644
index 0000000..668a261
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/element-map.hxx
@@ -0,0 +1,146 @@
+// file : xsd/cxx/tree/element-map.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_ELEMENT_MAP_HXX
+#define XSD_CXX_TREE_ELEMENT_MAP_HXX
+
+#include <map>
+#include <memory> // std::auto_ptr
+#include <cstddef> // std::size_t
+#include <string>
+
+#include <xsd/cxx/xml/qualified-name.hxx>
+#include <xsd/cxx/tree/elements.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ /**
+ * @brief Root element map.
+ *
+ * This class allows uniform parsing/serialization of multiple
+ * root elements via the element_type base class.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename T>
+ class element_map
+ {
+ public:
+ /**
+ * @brief Common base class for all element types.
+ */
+ typedef tree::element_type<C, T> element_type;
+
+ /**
+ * @brief Parse a DOM element.
+ *
+ * @param e A DOM element to parse.
+ * @param f Flags to create the new element object with.
+ * @return An automatic pointer to the new element object.
+ */
+ static std::auto_ptr<element_type>
+ parse (const xercesc::DOMElement& e, flags f = 0);
+
+ /**
+ * @brief Serialize an element object to a DOM element.
+ *
+ * @param e A DOM element to serialize to.
+ * @param x An element object to serialize.
+ */
+ static void
+ serialize (xercesc::DOMElement& e, const element_type& x);
+
+ public:
+ //@cond
+
+ typedef xml::qualified_name<C> qualified_name;
+
+ typedef std::auto_ptr<element_type>
+ (*parser) (const xercesc::DOMElement&, flags f);
+
+ typedef void
+ (*serializer) (xercesc::DOMElement&, const element_type&);
+
+ static void
+ register_parser (const qualified_name&, parser);
+
+ static void
+ register_serializer (const qualified_name&, serializer);
+
+ public:
+ struct map_entry
+ {
+ map_entry () : parser_ (0), serializer_ (0) {}
+
+ parser parser_;
+ serializer serializer_;
+ };
+
+ typedef
+ std::map<qualified_name, map_entry>
+ map;
+
+ static map* map_;
+ static std::size_t count_;
+
+ private:
+ element_map ();
+
+ //@endcond
+ };
+
+ //@cond
+
+ template <typename C, typename T>
+ typename element_map<C, T>::map* element_map<C, T>::map_ = 0;
+
+ template <typename C, typename T>
+ std::size_t element_map<C, T>::count_ = 0;
+
+ template <typename C, typename T>
+ struct element_map_init
+ {
+ element_map_init ();
+ ~element_map_init ();
+ };
+
+ //
+ //
+ template<typename T, typename C, typename B>
+ std::auto_ptr<element_type<C, B> >
+ parser_impl (const xercesc::DOMElement&, flags);
+
+ template<typename T, typename C, typename B>
+ struct parser_init
+ {
+ parser_init (const std::basic_string<C>& name,
+ const std::basic_string<C>& ns);
+ };
+
+ //
+ //
+ template<typename T, typename C, typename B>
+ void
+ serializer_impl (xercesc::DOMElement&, const element_type<C, B>&);
+
+ template<typename T, typename C, typename B>
+ struct serializer_init
+ {
+ serializer_init (const std::basic_string<C>& name,
+ const std::basic_string<C>& ns);
+ };
+
+ //@endcond
+ }
+ }
+}
+
+#include <xsd/cxx/tree/element-map.txx>
+
+#endif // XSD_CXX_TREE_ELEMENT_MAP_HXX
diff --git a/libxsd/xsd/cxx/tree/element-map.txx b/libxsd/xsd/cxx/tree/element-map.txx
new file mode 100644
index 0000000..2e40b81
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/element-map.txx
@@ -0,0 +1,71 @@
+// file : xsd/cxx/tree/element-map.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // element_map
+ //
+ template <typename C, typename T>
+ void element_map<C, T>::
+ register_parser (const qualified_name& n, parser p)
+ {
+ (*map_)[n].parser_ = p;
+ }
+
+ template <typename C, typename T>
+ void element_map<C, T>::
+ register_serializer (const qualified_name& n, serializer s)
+ {
+ (*map_)[n].serializer_ = s;
+ }
+
+ // element_map_init
+ //
+ template <typename C, typename T>
+ element_map_init<C, T>::
+ element_map_init ()
+ {
+ if (element_map<C, T>::count_ == 0)
+ element_map<C, T>::map_ = new typename element_map<C, T>::map;
+
+ ++element_map<C, T>::count_;
+ }
+
+ template <typename C, typename T>
+ element_map_init<C, T>::
+ ~element_map_init ()
+ {
+ if (--element_map<C, T>::count_ == 0)
+ delete element_map<C, T>::map_;
+ }
+
+ // parser_init
+ //
+ template<typename T, typename C, typename B>
+ parser_init<T, C, B>::
+ parser_init (const std::basic_string<C>& name,
+ const std::basic_string<C>& ns)
+ {
+ element_map<C, B>::register_parser (
+ xml::qualified_name<C> (name, ns), &parser_impl<T, C, B>);
+ }
+
+ // serializer_init
+ //
+ template<typename T, typename C, typename B>
+ serializer_init<T, C, B>::
+ serializer_init (const std::basic_string<C>& name,
+ const std::basic_string<C>& ns)
+ {
+ element_map<C, B>::register_serializer (
+ xml::qualified_name<C> (name, ns), &serializer_impl<T, C, B>);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/elements.hxx b/libxsd/xsd/cxx/tree/elements.hxx
new file mode 100644
index 0000000..3334d5f
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/elements.hxx
@@ -0,0 +1,1448 @@
+// file : xsd/cxx/tree/elements.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+/**
+ * @file
+ *
+ * @brief Contains C++ class definitions for XML Schema anyType and
+ * anySimpleType types as well as supporting code.
+ *
+ * This is an internal header and is included by the generated code. You
+ * normally should not include it directly.
+ *
+ */
+
+#ifndef XSD_CXX_TREE_ELEMENTS_HXX
+#define XSD_CXX_TREE_ELEMENTS_HXX
+
+#include <map>
+#include <string>
+#include <memory> // std::auto_ptr
+#include <istream>
+#include <sstream>
+#include <cassert>
+
+#include <xercesc/dom/DOMNode.hpp>
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMElement.hpp>
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xercesc/dom/DOMNamedNodeMap.hpp>
+
+#include <xsd/cxx/xml/elements.hxx> // xml::properties
+#include <xsd/cxx/xml/dom/auto-ptr.hxx> // dom::auto_ptr
+
+#include <xsd/cxx/tree/facet.hxx>
+#include <xsd/cxx/tree/exceptions.hxx>
+#include <xsd/cxx/tree/istream-fwd.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ /**
+ * @brief C++/Tree mapping runtime namespace.
+ *
+ * This is an internal namespace and normally should not be referenced
+ * directly. Instead you should use the aliases for types in this
+ * namespaces that are created in the generated code.
+ *
+ */
+ namespace tree
+ {
+ /**
+ * @brief Parsing and %serialization %flags.
+ *
+ * Flags are used to modify the default behavior of %parsing and
+ * %serialization functions as well as %parsing constructors.
+ *
+ * @nosubgrouping
+ */
+ class flags
+ {
+ public:
+ /**
+ * @name Flag constants
+ */
+ //@{
+
+ /**
+ * @brief Keep DOM association in the resulting tree.
+ */
+ static const unsigned long keep_dom = 0x00000100UL;
+
+ /**
+ * @brief Assume ownership of the DOM document.
+ *
+ * This flag only makes sense together with the @c keep_dom
+ * flag in the call to the %parsing function with the
+ * @c dom::auto_ptr<DOMDocument> argument.
+ *
+ */
+ static const unsigned long own_dom = 0x00000200UL;
+
+ /**
+ * @brief Turn off XML Schema validation in the underlying XML
+ * parser.
+ */
+ static const unsigned long dont_validate = 0x00000400UL;
+
+ /**
+ * @brief Do not initialize the Xerces-C++ runtime.
+ */
+ static const unsigned long dont_initialize = 0x00000001UL;
+
+ /**
+ * @brief Do not write XML declaration during %serialization.
+ */
+ static const unsigned long no_xml_declaration = 0x00010000UL;
+
+ /**
+ * @brief Do not add extra spaces or new lines that make the
+ * resulting XML easier to read.
+ */
+ static const unsigned long dont_pretty_print = 0x00020000UL;
+
+ //@cond
+
+ // The following flags are for internal use.
+ //
+ static const unsigned long base = 0x01000000UL;
+
+ //@endcond
+
+ // Notes on flag blocks:
+ //
+ // 0x000000FF - common (applicable to both parsing and serialization)
+ // 0x0000FF00 - parsing (values aligned with XML parsing)
+ // 0x00FF0000 - serialization (values aligned with XML serialization)
+ // 0xFF000000 - internal
+
+ //@}
+
+ public:
+ /**
+ * @brief Initialize an instance with an integer value.
+ *
+ * @param x A %flags value as an integer.
+ */
+ flags (unsigned long x = 0)
+ : x_ (x)
+ {
+ }
+
+ /**
+ * @brief Convert an instance to an integer value.
+ *
+ * @return An integer %flags value.
+ */
+ operator unsigned long () const
+ {
+ return x_;
+ }
+
+ /**
+ * @brief Combine two %flags.
+ *
+ * @return A %flags object that is a combination of the arguments.
+ */
+ friend flags
+ operator| (const flags& a, const flags& b)
+ {
+ return flags (a.x_ | b.x_);
+ }
+
+ /**
+ * @brief Combine two %flags.
+ *
+ * @return A %flags object that is a combination of the arguments.
+ */
+ friend flags
+ operator| (const flags& a, unsigned long b)
+ {
+ return flags (a.x_ | b);
+ }
+
+ /**
+ * @brief Combine two %flags.
+ *
+ * @return A %flags object that is a combination of the arguments.
+ */
+ friend flags
+ operator| (unsigned long a, const flags& b)
+ {
+ return flags (a | b.x_);
+ }
+
+ private:
+ unsigned long x_;
+ };
+
+
+ // Parsing properties. Refer to xsd/cxx/xml/elements.hxx for XML-
+ // related properties.
+ //
+ template <typename C>
+ class properties: public xml::properties<C>
+ {
+ };
+
+ //@cond
+
+ // DOM user data keys.
+ //
+ template <int dummy>
+ struct user_data_keys_template
+ {
+ // Back pointers to tree nodes.
+ //
+ static const XMLCh node[21];
+ };
+
+ typedef user_data_keys_template<0> user_data_keys;
+
+ // HP aCC3 complains about unresolved symbols without an explicit
+ // instantiation.
+ //
+#if defined(__HP_aCC) && __HP_aCC <= 39999
+ template struct user_data_keys_template<0>;
+#endif
+ //
+ //
+ struct identity
+ {
+ virtual
+ ~identity ()
+ {
+ }
+
+ identity ()
+ {
+ }
+
+ virtual bool
+ before (const identity&) const = 0;
+
+ virtual void
+ throw_duplicate_id () const = 0;
+
+ private:
+ identity (const identity&);
+
+ identity&
+ operator= (const identity&);
+ };
+
+ //@endcond
+
+
+ // anyType. VC++ has a name injection bug that makes it impossible
+ // to have a member with the same name as a base type. To address
+ // that we will have to choose some unique name for the definition
+ // and typedef it to 'type'.
+ //
+ class _type;
+
+ /**
+ * @brief Class corresponding to the XML Schema anyType built-in type.
+ *
+ */
+ typedef _type type;
+
+ /**
+ * @brief Container type.
+ *
+ */
+ typedef _type container;
+
+ /**
+ * @brief Class corresponding to the XML Schema anyType built-in type.
+ *
+ * This class is a base for every generated and built-in type in the
+ * C++/Tree mapping.
+ *
+ * @nosubgrouping
+ */
+ class _type
+ {
+ public:
+ virtual
+ ~_type ()
+ {
+ // Everything should have been unregistered by now.
+ //
+ assert (map_.get () == 0 || map_->size () == 0);
+ }
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Default constructor.
+ */
+ _type ()
+ : container_ (0)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ _type (const type& x, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual type*
+ _clone (flags f = 0, container* c = 0) const
+ {
+ return new type (*this, f, c);
+ }
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ _type (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ _type (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ _type (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename C>
+ _type (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ type&
+ operator= (const type& x)
+ {
+ while (&x == 0) /* unused */;
+ return *this;
+ }
+
+ // Container API.
+ //
+ public:
+ /**
+ * @brief Get a constant pointer to container, an object model
+ * node that contains this instance.
+ *
+ * @return A constant pointer to container, or 0 if this instance
+ * is not contained.
+ */
+ const container*
+ _container () const
+ {
+ return container_;
+ }
+
+ /**
+ * @brief Get a pointer to container, an object model node that
+ * contains this instance.
+ *
+ * @return A pointer to container, or 0 if this instance is not
+ * contained.
+ */
+ container*
+ _container ()
+ {
+ return container_;
+ }
+
+ /**
+ * @brief Set this instance's new container, an object model node
+ * that contains this instance.
+ *
+ * @param c A pointer to container.
+ */
+ virtual void
+ _container (container* c)
+ {
+ assert (container_ == 0);
+
+ if (c != 0)
+ {
+ if (map_.get () != 0)
+ {
+ // Propagate our IDs to the new container.
+ //
+ for (map::iterator i (map_->begin ()), e (map_->end ());
+ i != e; ++i)
+ {
+ c->_register_id (*i->first, i->second);
+ }
+ }
+
+ container_ = c;
+ }
+ }
+
+ /**
+ * @brief Get a constant pointer to object model's root node.
+ *
+ * @return A constant pointer to root node, or 0 if this instance
+ * is not contained.
+ */
+ const container*
+ _root () const
+ {
+ const container* r (container_);
+
+ for (const container* c (r); c != 0; c = c->container_)
+ r = c;
+
+ return r;
+ }
+
+ /**
+ * @brief Get a pointer to object model's root node.
+ *
+ * @return A pointer to root node, or 0 if this instance is not
+ * contained.
+ */
+ container*
+ _root ()
+ {
+ container* r (container_);
+
+ for (container* c (r); c != 0; c = c->container_)
+ r = c;
+
+ return r;
+ }
+
+ // DOM association.
+ //
+ public:
+ /**
+ * @brief Get a constant pointer to a DOM node associated with
+ * this object model node.
+ *
+ * @return A constant pointer to DOM node, or 0 if none associated.
+ */
+ const xercesc::DOMNode*
+ _node () const
+ {
+ return dom_info_.get () ? dom_info_->node() : 0;
+ }
+
+ /**
+ * @brief Get a pointer to a DOM node associated with this object
+ * model node.
+ *
+ * @return A pointer to DOM node, or 0 if none associated.
+ */
+ xercesc::DOMNode*
+ _node ()
+ {
+ return dom_info_.get () ? dom_info_->node () : 0;
+ }
+
+ /**
+ * @brief Exception indicating that a DOM node cannot be associated
+ * with an object model node.
+ */
+ class bad_dom_node_type: public std::exception //@@ Inherit exception.
+ {
+ public:
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ()
+ {
+ return "DOM node is not an attribute node or element node";
+ }
+ };
+
+ /**
+ * @brief Manually set a DOM node associated with this object
+ * model node.
+ *
+ * The DOM node should be a child of the parent's DOM node. If
+ * this object model node is a root of the tree, then it will
+ * assume the ownership of the whole DOM document to which this
+ * DOM node belongs.
+ *
+ * @param n A pointer to DOM node (should be either an element or
+ * an attribute).
+ */
+ void
+ _node (xercesc::DOMNode* n)
+ {
+ switch (n->getNodeType ())
+ {
+ case xercesc::DOMNode::ELEMENT_NODE:
+ {
+ if (container_ != 0)
+ {
+ // @@ Should be a throw.
+ //
+ assert (_root ()->_node () != 0);
+ assert (_root ()->_node ()->getOwnerDocument () ==
+ n->getOwnerDocument ());
+ }
+
+ std::auto_ptr<dom_info> r (
+ dom_info_factory::create (
+ *static_cast<xercesc::DOMElement*> (n),
+ *this,
+ container_ == 0));
+
+ dom_info_ = r;
+ break;
+ }
+ case xercesc::DOMNode::ATTRIBUTE_NODE:
+ {
+ //@@ Should be a throw.
+ //
+ assert (container_ != 0);
+ assert (_root ()->_node () != 0);
+ assert (_root ()->_node ()->getOwnerDocument () ==
+ n->getOwnerDocument ());
+
+ std::auto_ptr<dom_info> r (
+ dom_info_factory::create (
+ *static_cast<xercesc::DOMAttr*> (n),
+ *this));
+
+ dom_info_ = r;
+ break;
+ }
+ default:
+ {
+ throw bad_dom_node_type ();
+ }
+ }
+ }
+
+ public:
+ //@cond
+
+ void
+ _register_id (const identity& id, type* t)
+ {
+ if (map_.get () == 0)
+ map_.reset (new map);
+
+ // First register on our container. If there are any duplications,
+ // they will be detected by this call and we don't need to clean
+ // the map.
+ //
+ if (container_ != 0)
+ container_->_register_id (id, t);
+
+ if (!map_->insert (
+ std::pair<const identity*, type*> (&id, t)).second)
+ {
+ id.throw_duplicate_id ();
+ }
+ }
+
+ //@@ Does not inherit from exception.
+ //
+ struct not_registered: std::exception
+ {
+ virtual const char*
+ what () const throw ()
+ {
+ return "attempt to unregister non-existent id";
+ }
+ };
+
+ void
+ _unregister_id (const identity& id)
+ {
+ if (map_.get ())
+ {
+ map::iterator it (map_->find (&id));
+
+ if (it != map_->end ())
+ {
+ map_->erase (it);
+
+ if (container_ != 0)
+ container_->_unregister_id (id);
+
+ return;
+ }
+ }
+
+ throw not_registered ();
+ }
+
+ type*
+ _lookup_id (const identity& id) const
+ {
+ if (map_.get ())
+ {
+ map::const_iterator it (map_->find (&id));
+
+ if (it != map_->end ())
+ return it->second;
+ }
+
+ return 0;
+ }
+
+ //@endcond
+
+ private:
+ //@cond
+
+ struct dom_info
+ {
+ virtual
+ ~dom_info ()
+ {
+ }
+
+ dom_info ()
+ {
+ }
+
+ virtual std::auto_ptr<dom_info>
+ clone (type& tree_node, container*) const = 0;
+
+ virtual xercesc::DOMNode*
+ node () = 0;
+
+ private:
+ dom_info (const dom_info&);
+
+ dom_info&
+ operator= (const dom_info&);
+ };
+
+
+ struct dom_element_info: public dom_info
+ {
+ dom_element_info (xercesc::DOMElement& e, type& n, bool root)
+ : doc_ (0), e_ (e)
+ {
+ e_.setUserData (user_data_keys::node, &n, 0);
+
+ if (root)
+ {
+ // The caller should have associated a dom::auto_ptr object
+ // that owns this document with the document node using the
+ // xml_schema::dom::tree_node_key key.
+ //
+ xml::dom::auto_ptr<xercesc::DOMDocument>* pd (
+ reinterpret_cast<xml::dom::auto_ptr<xercesc::DOMDocument>*> (
+ e.getOwnerDocument ()->getUserData (user_data_keys::node)));
+
+ assert (pd != 0);
+ assert (pd->get () == e.getOwnerDocument ());
+
+ doc_ = *pd; // Transfer ownership.
+ }
+ }
+
+ virtual std::auto_ptr<dom_info>
+ clone (type& tree_node, container* c) const
+ {
+ using std::auto_ptr;
+
+ // Check if we are a document root.
+ //
+ if (c == 0)
+ {
+ // We preserver DOM associations only in complete
+ // copies from root.
+ //
+ if (doc_.get () == 0)
+ return auto_ptr<dom_info> (0);
+
+ return auto_ptr<dom_info> (
+ new dom_element_info (*doc_, tree_node));
+ }
+
+ // Check if our container does not have DOM association (e.g.,
+ // because it wasn't a complete copy of the tree).
+ //
+ using xercesc::DOMNode;
+
+ DOMNode* cn (c->_node ());
+
+ if (cn == 0)
+ return auto_ptr<dom_info> (0);
+
+
+ // Now we are going to find the corresponding element in
+ // the new tree.
+ //
+ {
+ using xercesc::DOMElement;
+
+ DOMNode& pn (*e_.getParentNode ());
+ assert (pn.getNodeType () == DOMNode::ELEMENT_NODE);
+
+ DOMNode* sn (pn.getFirstChild ()); // Source.
+ DOMNode* dn (cn->getFirstChild ()); // Destination.
+
+ // We should have at least one child.
+ //
+ assert (sn != 0);
+
+ // Move in parallel until we get to the needed node.
+ //
+ for (; sn != 0 && !e_.isSameNode (sn);)
+ {
+ sn = sn->getNextSibling ();
+ dn = dn->getNextSibling ();
+ }
+
+ // e_ should be on the list.
+ //
+ assert (sn != 0);
+
+ assert (dn->getNodeType () == DOMNode::ELEMENT_NODE);
+
+ return auto_ptr<dom_info> (
+ new dom_element_info (static_cast<DOMElement&> (*dn),
+ tree_node,
+ false));
+ }
+ }
+
+ virtual xercesc::DOMNode*
+ node ()
+ {
+ return &e_;
+ }
+
+ private:
+ dom_element_info (const xercesc::DOMDocument& d, type& n)
+ : doc_ (static_cast<xercesc::DOMDocument*> (
+ d.cloneNode (true))),
+ e_ (*doc_->getDocumentElement ())
+ {
+ e_.setUserData (user_data_keys::node, &n, 0);
+ }
+
+ private:
+ xml::dom::auto_ptr<xercesc::DOMDocument> doc_;
+ xercesc::DOMElement& e_;
+ };
+
+
+ struct dom_attribute_info: public dom_info
+ {
+ dom_attribute_info (xercesc::DOMAttr& a, type& n)
+ : a_ (a)
+ {
+ a_.setUserData (user_data_keys::node, &n, 0);
+ }
+
+ virtual std::auto_ptr<dom_info>
+ clone (type& tree_node, container* c) const
+ {
+ using std::auto_ptr;
+
+ // Check if we are a document root.
+ //
+ if (c == 0)
+ {
+ // We preserver DOM associations only in complete
+ // copies from root.
+ //
+ return auto_ptr<dom_info> (0);
+ }
+
+ // Check if our container does not have DOM association (e.g.,
+ // because it wasn't a complete copy of the tree).
+ //
+ using xercesc::DOMNode;
+
+ DOMNode* cn (c->_node ());
+
+ if (cn == 0)
+ return auto_ptr<dom_info> (0);
+
+ // We are going to find the corresponding attribute in
+ // the new tree.
+ //
+ using xercesc::DOMAttr;
+ using xercesc::DOMElement;
+ using xercesc::DOMNamedNodeMap;
+
+ DOMElement& p (*a_.getOwnerElement ());
+ DOMNamedNodeMap& nl (*p.getAttributes ());
+
+ XMLSize_t size (nl.getLength ()), i (0);
+
+ // We should have at least one child.
+ //
+ assert (size != 0);
+
+ for ( ;i < size && !a_.isSameNode (nl.item (i)); ++i)/*noop*/;
+
+ // a_ should be in the list.
+ //
+ assert (i < size);
+
+ DOMNode& n (*cn->getAttributes ()->item (i));
+ assert (n.getNodeType () == DOMNode::ATTRIBUTE_NODE);
+
+ return auto_ptr<dom_info> (
+ new dom_attribute_info (static_cast<DOMAttr&> (n), tree_node));
+ }
+
+ virtual xercesc::DOMNode*
+ node ()
+ {
+ return &a_;
+ }
+
+ private:
+ xercesc::DOMAttr& a_;
+ };
+
+ // For Sun C++ 5.6.
+ //
+ struct dom_info_factory;
+ friend struct _type::dom_info_factory;
+
+ struct dom_info_factory
+ {
+ static std::auto_ptr<dom_info>
+ create (const xercesc::DOMElement& e, type& n, bool root)
+ {
+ return std::auto_ptr<dom_info> (
+ new dom_element_info (
+ const_cast<xercesc::DOMElement&> (e), n, root));
+ }
+
+ static std::auto_ptr<dom_info>
+ create (const xercesc::DOMAttr& a, type& n)
+ {
+ return std::auto_ptr<dom_info> (
+ new dom_attribute_info (
+ const_cast<xercesc::DOMAttr&> (a), n));
+ }
+ };
+
+ //@endcond
+
+ std::auto_ptr<dom_info> dom_info_;
+
+
+ // ID/IDREF map.
+ //
+ private:
+
+ //@cond
+
+ struct identity_comparator
+ {
+ bool operator () (const identity* x, const identity* y) const
+ {
+ return x->before (*y);
+ }
+ };
+
+ //@endcond
+
+ typedef
+ std::map<const identity*, type*, identity_comparator>
+ map;
+
+ std::auto_ptr<map> map_;
+
+ private:
+ container* container_;
+ };
+
+ inline _type::
+ _type (const type& x, flags, container* c)
+ : container_ (c)
+ {
+ if (x.dom_info_.get ())
+ {
+ std::auto_ptr<dom_info> r (x.dom_info_->clone (*this, c));
+ dom_info_ = r;
+ }
+ }
+
+
+ /**
+ * @brief Class corresponding to the XML Schema anySimpleType built-in
+ * type.
+ *
+ * @nosubgrouping
+ */
+ template <typename B>
+ class simple_type: public B
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Default constructor.
+ */
+ simple_type ()
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ simple_type (const simple_type& x, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual simple_type*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ simple_type (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ simple_type (const xercesc::DOMElement& e,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ simple_type (const xercesc::DOMAttr& a,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename C>
+ simple_type (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+ };
+
+
+ /**
+ * @brief Base class for element types.
+ *
+ * This class is a base for every generated element type.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename T>
+ class element_type
+ {
+ public:
+ virtual
+ ~element_type ()
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual element_type*
+ _clone (flags f = 0) const = 0;
+
+ /**
+ * @brief Return the element name.
+ *
+ * @return A read-only string reference containing the element
+ * name.
+ */
+ virtual const std::basic_string<C>&
+ _name () const = 0;
+
+ /**
+ * @brief Return the element namespace.
+ *
+ * @return A read-only string reference containing the element
+ * namespace. Empty string is returned if the element is
+ * unqualified.
+ */
+ virtual const std::basic_string<C>&
+ _namespace () const = 0;
+
+ /**
+ * @brief Return the element value.
+ *
+ * @return A pointer to the element value or 0 if the element
+ * is of a fundamental type.
+ */
+ virtual T*
+ _value () = 0;
+
+ /**
+ * @brief Return the element value.
+ *
+ * @return A read-only pointer to the element value or 0 if the
+ * element is of a fundamental type.
+ */
+ virtual const T*
+ _value () const = 0;
+ };
+
+
+ //@cond
+
+ // Extra schema type id to disambiguate certain cases where
+ // different XML Schema types (e.g., double and decimal) are
+ // mapped to the same fundamental C++ type (e.g., double).
+ //
+ struct schema_type
+ {
+ enum value
+ {
+ other,
+ double_,
+ decimal
+ };
+ };
+
+ //@endcond
+
+
+ //@cond
+ template <typename T,
+ typename C,
+ schema_type::value ST = schema_type::other>
+ struct traits
+ {
+ typedef T type;
+
+ static std::auto_ptr<T>
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return std::auto_ptr<T> (new T (e, f, c));
+ }
+
+ static std::auto_ptr<T>
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return std::auto_ptr<T> (new T (a, f, c));
+ }
+
+ static std::auto_ptr<T>
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ {
+ return std::auto_ptr<T> (new T (s, e, f, c));
+ }
+ };
+
+ //@endcond
+
+
+ /**
+ * @brief Class template that emulates inheritance from a
+ * fundamental C++ type.
+ *
+ * @nosubgrouping
+ */
+ template <typename T,
+ typename C,
+ typename B,
+ schema_type::value ST = schema_type::other>
+ class fundamental_base: public B
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Default constructor.
+ */
+ fundamental_base ()
+ : facet_table_ (0), x_ ()
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with an underlying type value.
+ *
+ * @param x An underlying type value.
+ */
+ fundamental_base (T x)
+ : facet_table_ (0), x_ (x)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ fundamental_base (const fundamental_base& x,
+ flags f = 0,
+ container* c = 0)
+ : B (x, f, c), facet_table_ (0), x_ (x.x_)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual fundamental_base*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ fundamental_base (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ fundamental_base (const xercesc::DOMElement& e,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ fundamental_base (const xercesc::DOMAttr& a,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ fundamental_base (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Assign an underlying type value to the instance.
+ *
+ * @param x An underlying type value.
+ * @return A reference to the instance.
+ */
+ fundamental_base&
+ operator= (const T& x)
+ {
+ if (&x_ != &x)
+ x_ = x;
+
+ return *this;
+ }
+
+ public:
+ /**
+ * @brief Implicitly convert the instance to constant reference to
+ * the underlying type.
+ *
+ * @return A constant reference to the underlying type.
+ */
+ operator const T& () const
+ {
+ return x_;
+ }
+
+ /**
+ * @brief Implicitly convert the instance to reference to the
+ * underlying type.
+ *
+ * @return A reference to the underlying type.
+ */
+ operator T& ()
+ {
+ return x_;
+ }
+
+ // The following extra conversion operators causes problems on
+ // some compilers (notably VC 7.1 and 9.0) and are disabled by
+ // default.
+ //
+#ifdef XSD_TREE_EXTRA_FUND_CONV
+ /**
+ * @brief Implicitly convert the instance to another type (const
+ * version).
+ *
+ * @return A value converted to the target type.
+ */
+ template <typename T2>
+ operator T2 () const
+ {
+ return x_;
+ }
+
+ /**
+ * @brief Implicitly convert the instance to another type.
+ *
+ * @return A value converted to the target type.
+ */
+ template <typename T2>
+ operator T2 ()
+ {
+ return x_;
+ }
+#endif // XSD_TREE_EXTRA_FUND_CONV
+
+ public:
+ /**
+ * @brief Get the facet table associated with this type.
+ *
+ * @return A pointer to read-only facet table or 0.
+ */
+ const facet*
+ _facet_table () const
+ {
+ return facet_table_;
+ }
+
+ protected:
+ /**
+ * @brief Set the facet table associated with this type.
+ *
+ * @param ft A pointer to read-only facet table.
+ */
+ void
+ _facet_table (const facet* ft)
+ {
+ facet_table_ = ft;
+ }
+
+ private:
+ const facet* facet_table_;
+ T x_;
+ };
+
+ // While thse operators are not normally necessary, they
+ // help resolve ambiguities between implicit conversion and
+ // construction.
+ //
+
+ /**
+ * @brief %fundamental_base comparison operator.
+ *
+ * @return True if the underlying values are equal, false otherwise.
+ */
+ template <typename T, typename C, typename B, schema_type::value ST>
+ inline bool
+ operator== (const fundamental_base<T, C, B, ST>& x,
+ const fundamental_base<T, C, B, ST>& y)
+ {
+ T x_ (x);
+ T y_ (y);
+ return x_ == y_;
+ }
+
+ /**
+ * @brief %fundamental_base comparison operator.
+ *
+ * @return True if the underlying values are not equal, false otherwise.
+ */
+ template <typename T, typename C, typename B, schema_type::value ST>
+ inline bool
+ operator!= (const fundamental_base<T, C, B, ST>& x,
+ const fundamental_base<T, C, B, ST>& y)
+ {
+ T x_ (x);
+ T y_ (y);
+ return x_ != y_;
+ }
+
+
+ //@cond
+
+ // Comparator for enum tables.
+ //
+ template <typename C>
+ struct enum_comparator
+ {
+ enum_comparator (const C* const* table)
+ : table_ (table)
+ {
+ }
+
+ bool
+ operator() (std::size_t i, const std::basic_string<C>& s) const
+ {
+ return table_[i] < s;
+ }
+
+ bool
+ operator() (const std::basic_string<C>& s, std::size_t i) const
+ {
+ return s < table_[i];
+ }
+
+ bool
+ operator() (std::size_t i, std::size_t j) const
+ {
+ return std::basic_string<C> (table_[i]) < table_[j];
+ }
+
+ private:
+ const C* const* table_;
+ };
+
+ //@endcond
+ }
+ }
+}
+
+#include <xsd/cxx/tree/elements.txx>
+
+#endif // XSD_CXX_TREE_ELEMENTS_HXX
diff --git a/libxsd/xsd/cxx/tree/elements.txx b/libxsd/xsd/cxx/tree/elements.txx
new file mode 100644
index 0000000..a0cb8f6
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/elements.txx
@@ -0,0 +1,57 @@
+// file : xsd/cxx/tree/elements.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xercesc/util/XMLUniDefs.hpp>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // user_data_keys_template
+ //
+ template <int dummy>
+ const XMLCh user_data_keys_template<dummy>::node[21] =
+ {xercesc::chLatin_x, xercesc::chLatin_s, xercesc::chLatin_d, // xsd
+ xercesc::chColon, xercesc::chColon, // ::
+ xercesc::chLatin_c, xercesc::chLatin_x, xercesc::chLatin_x, // cxx
+ xercesc::chColon, xercesc::chColon, // ::
+ xercesc::chLatin_t, xercesc::chLatin_r, xercesc::chLatin_e, // tre
+ xercesc::chLatin_e, xercesc::chColon, xercesc::chColon, // e::
+ xercesc::chLatin_n, xercesc::chLatin_o, xercesc::chLatin_d, // nod
+ xercesc::chLatin_e, xercesc::chNull // e\0
+ };
+
+
+ // simple_type
+ //
+ template <typename B>
+ simple_type<B>::
+ simple_type (const simple_type& other,
+ flags f,
+ container* c)
+ : B (other, f, c)
+ {
+ }
+
+ template <typename B>
+ simple_type<B>* simple_type<B>::
+ _clone (flags f, container* c) const
+ {
+ return new simple_type (*this, f, c);
+ }
+
+ // fundamental_base
+ //
+ template <typename T, typename C, typename B, schema_type::value ST>
+ fundamental_base<T, C, B, ST>* fundamental_base<T, C, B, ST>::
+ _clone (flags f, container* c) const
+ {
+ return new fundamental_base (*this, f, c);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/error-handler.hxx b/libxsd/xsd/cxx/tree/error-handler.hxx
new file mode 100644
index 0000000..13e41a5
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/error-handler.hxx
@@ -0,0 +1,62 @@
+// file : xsd/cxx/tree/error-handler.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_ERROR_HANDLER_HXX
+#define XSD_CXX_TREE_ERROR_HANDLER_HXX
+
+#include <xsd/cxx/xml/error-handler.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ class error_handler: public xml::error_handler<C>
+ {
+ typedef typename xml::error_handler<C>::severity severity;
+
+ public:
+ error_handler ()
+ : failed_ (false)
+ {
+ }
+
+ virtual bool
+ handle (const std::basic_string<C>& id,
+ unsigned long line,
+ unsigned long column,
+ severity,
+ const std::basic_string<C>& message);
+
+ template <typename E>
+ void
+ throw_if_failed () const
+ {
+ if (failed_)
+ throw E (diagnostics_);
+ }
+
+ void
+ reset ()
+ {
+ failed_ = false;
+ diagnostics_.clear ();
+ }
+
+ private:
+ bool failed_;
+ diagnostics<C> diagnostics_;
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/tree/error-handler.txx>
+
+#endif // XSD_CXX_TREE_ERROR_HANDLER_HXX
diff --git a/libxsd/xsd/cxx/tree/error-handler.txx b/libxsd/xsd/cxx/tree/error-handler.txx
new file mode 100644
index 0000000..d64c51b
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/error-handler.txx
@@ -0,0 +1,34 @@
+// file : xsd/cxx/tree/error-handler.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <iostream>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ bool error_handler<C>::
+ handle (const std::basic_string<C>& id,
+ unsigned long line,
+ unsigned long column,
+ severity s,
+ const std::basic_string<C>& message)
+ {
+ diagnostics_.push_back (
+ error<C> (s == severity::warning
+ ? tree::severity::warning
+ : tree::severity::error, id, line, column, message));
+
+ if (!failed_ && s != severity::warning)
+ failed_ = true;
+
+ return true;
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/exceptions.hxx b/libxsd/xsd/cxx/tree/exceptions.hxx
new file mode 100644
index 0000000..6856270
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/exceptions.hxx
@@ -0,0 +1,1036 @@
+// file : xsd/cxx/tree/exceptions.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+/**
+ * @file
+ *
+ * @brief Contains exception definitions for the C++/Tree mapping.
+ *
+ * This is an internal header and is included by the generated code.
+ * You normally should not include it directly.
+ *
+ */
+
+#ifndef XSD_CXX_TREE_EXCEPTIONS_HXX
+#define XSD_CXX_TREE_EXCEPTIONS_HXX
+
+#include <string>
+#include <vector>
+#include <ostream>
+
+#include <xsd/cxx/exceptions.hxx> // xsd::cxx::exception
+
+namespace xsd
+{
+ namespace cxx
+ {
+ /**
+ * @brief C++/Tree mapping runtime namespace.
+ *
+ * This is an internal namespace and normally should not be referenced
+ * directly. Instead you should use the aliases for types in this
+ * namespaces that are created in the generated code.
+ *
+ */
+ namespace tree
+ {
+ /**
+ * @brief Root of the C++/Tree %exception hierarchy.
+ *
+ * You can catch this %exception in order to handle all C++/Tree
+ * errors.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class exception: public xsd::cxx::exception
+ {
+ public:
+ /**
+ * @brief Stream insertion operator for %exception.
+ */
+ friend
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const exception& e)
+ {
+ e.print (os);
+ return os;
+ }
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const = 0;
+
+ //@endcond
+ };
+
+
+ /**
+ * @brief Error %severity.
+ *
+ * @nosubgrouping
+ */
+ class severity
+ {
+ public:
+ /**
+ * @brief Underlying enum type.
+ */
+ enum value
+ {
+ /**
+ * @brief Indicates the warning condition.
+ */
+ warning,
+
+ /**
+ * @brief Indicates the %error condition.
+ */
+ error
+ };
+
+ /**
+ * @brief Initialize an instance with the underlying enum value.
+ *
+ * @param v An underlying enum value.
+ */
+ severity (value v) : v_ (v) {}
+
+ /**
+ * @brief Implicitly convert the instance to the underlying enum
+ * value.
+ *
+ * @return The underlying enum value.
+ */
+ operator value () const { return v_; }
+
+ private:
+ value v_;
+ };
+
+ /**
+ * @brief Error condition.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class error
+ {
+ public:
+ /**
+ * @brief Initialize an instance with %error description.
+ *
+ * @param s An %error %severity.
+ * @param res_id A resource %id where the %error occurred.
+ * @param line A line number where the %error occurred.
+ * @param column A column number where the %error occurred.
+ * @param message A message describing the %error.
+ */
+ error (tree::severity s,
+ const std::basic_string<C>& res_id,
+ unsigned long line,
+ unsigned long column,
+ const std::basic_string<C>& message);
+
+ /**
+ * @brief Get %error %severity.
+ *
+ * @return The %severity of this %error.
+ */
+ tree::severity
+ severity () const
+ {
+ return severity_;
+ }
+
+ /**
+ * @brief Get resource %id.
+ *
+ * @return The %id of the resource where this %error occurred.
+ */
+ const std::basic_string<C>&
+ id () const
+ {
+ return id_;
+ }
+
+ /**
+ * @brief Get %error line.
+ *
+ * @return The line number where this %error occurred.
+ */
+ unsigned long
+ line () const
+ {
+ return line_;
+ }
+
+ /**
+ * @brief Get %error column.
+ *
+ * @return The column number where this %error occurred.
+ */
+ unsigned long
+ column () const
+ {
+ return column_;
+ }
+
+ /**
+ * @brief Get %error message.
+ *
+ * @return The message for this %error.
+ */
+ const std::basic_string<C>&
+ message () const
+ {
+ return message_;
+ }
+
+ //@cond
+
+ // Default c-tor that shouldn't be. Needed when we completely
+ // instantiate std::vector in diagnostics below.
+ //
+ error ();
+
+ //@endcond
+
+
+ private:
+ tree::severity severity_;
+ std::basic_string<C> id_;
+ unsigned long line_;
+ unsigned long column_;
+ std::basic_string<C> message_;
+ };
+
+ // See exceptions.ixx for operator<< (error).
+
+
+ /**
+ * @brief List of %error conditions.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class diagnostics: public std::vector<error<C> >
+ {
+ };
+
+ // See exceptions.ixx for operator<< (diagnostics).
+
+ /**
+ * @brief Exception indicating a %parsing failure.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class parsing: public exception<C>
+ {
+ public:
+ virtual
+ ~parsing () throw ();
+
+ /**
+ * @brief Default constructor.
+ */
+ parsing ();
+
+ /**
+ * @brief Initialize an instance with a %list of %error conditions.
+ *
+ * @param d A %list of %error conditions.
+ */
+ parsing (const tree::diagnostics<C>& d);
+
+ public:
+ /**
+ * @brief Get the %list of %error conditions.
+ *
+ * @return The %list of %error conditions.
+ */
+ const tree::diagnostics<C>&
+ diagnostics () const
+ {
+ return diagnostics_;
+ }
+
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ //@endcond
+
+ private:
+ tree::diagnostics<C> diagnostics_;
+ };
+
+
+ /**
+ * @brief Exception indicating that an expected element was not
+ * encountered.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class expected_element: public exception<C>
+ {
+ public:
+ virtual
+ ~expected_element () throw ();
+
+ /**
+ * @brief Initialize an instance with the expected element
+ * description.
+ *
+ * @param name A name of the expected element.
+ * @param ns A namespace of the expected element.
+ */
+ expected_element (const std::basic_string<C>& name,
+ const std::basic_string<C>& ns);
+
+
+ public:
+ /**
+ * @brief Get the name of the expected element.
+ *
+ * @return The name of the expected element.
+ */
+ const std::basic_string<C>&
+ name () const
+ {
+ return name_;
+ }
+
+ /**
+ * @brief Get the namespace of the expected element.
+ *
+ * @return The namespace of the expected element.
+ */
+ const std::basic_string<C>&
+ namespace_ () const
+ {
+ return namespace__;
+ }
+
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ //@endcond
+
+ private:
+ std::basic_string<C> name_;
+ std::basic_string<C> namespace__;
+ };
+
+
+ /**
+ * @brief Exception indicating that an unexpected element was
+ * encountered.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class unexpected_element: public exception<C>
+ {
+ public:
+ virtual
+ ~unexpected_element () throw ();
+
+ /**
+ * @brief Initialize an instance with the encountered and expected
+ * element descriptions.
+ *
+ * @param encountered_name A name of the encountered element.
+ * @param encountered_ns A namespace of the encountered element.
+ * @param expected_name A name of the expected element.
+ * @param expected_ns A namespace of the expected element.
+ */
+ unexpected_element (const std::basic_string<C>& encountered_name,
+ const std::basic_string<C>& encountered_ns,
+ const std::basic_string<C>& expected_name,
+ const std::basic_string<C>& expected_ns);
+
+ public:
+ /**
+ * @brief Get the name of the encountered element.
+ *
+ * @return The name of the encountered element.
+ */
+ const std::basic_string<C>&
+ encountered_name () const
+ {
+ return encountered_name_;
+ }
+
+ /**
+ * @brief Get the namespace of the encountered element.
+ *
+ * @return The namespace of the encountered element.
+ */
+ const std::basic_string<C>&
+ encountered_namespace () const
+ {
+ return encountered_namespace_;
+ }
+
+ /**
+ * @brief Get the name of the expected element.
+ *
+ * @return The name of the expected element.
+ */
+ const std::basic_string<C>&
+ expected_name () const
+ {
+ return expected_name_;
+ }
+
+ /**
+ * @brief Get the namespace of the expected element.
+ *
+ * @return The namespace of the expected element.
+ */
+ const std::basic_string<C>&
+ expected_namespace () const
+ {
+ return expected_namespace_;
+ }
+
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ //@endcond
+
+ private:
+ std::basic_string<C> encountered_name_;
+ std::basic_string<C> encountered_namespace_;
+ std::basic_string<C> expected_name_;
+ std::basic_string<C> expected_namespace_;
+ };
+
+
+ /**
+ * @brief Exception indicating that an expected attribute was not
+ * encountered.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class expected_attribute: public exception<C>
+ {
+ public:
+ virtual
+ ~expected_attribute () throw ();
+
+ /**
+ * @brief Initialize an instance with the expected attribute
+ * description.
+ *
+ * @param name A name of the expected attribute.
+ * @param ns A namespace of the expected attribute.
+ */
+ expected_attribute (const std::basic_string<C>& name,
+ const std::basic_string<C>& ns);
+
+ public:
+ /**
+ * @brief Get the name of the expected attribute.
+ *
+ * @return The name of the expected attribute.
+ */
+ const std::basic_string<C>&
+ name () const
+ {
+ return name_;
+ }
+
+ /**
+ * @brief Get the namespace of the expected attribute.
+ *
+ * @return The namespace of the expected attribute.
+ */
+ const std::basic_string<C>&
+ namespace_ () const
+ {
+ return namespace__;
+ }
+
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ //@endcond
+
+ private:
+ std::basic_string<C> name_;
+ std::basic_string<C> namespace__;
+ };
+
+
+ /**
+ * @brief Exception indicating that an unexpected enumerator was
+ * encountered.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class unexpected_enumerator: public exception<C>
+ {
+ public:
+ virtual
+ ~unexpected_enumerator () throw ();
+
+ /**
+ * @brief Initialize an instance with the encountered enumerator.
+ *
+ * @param e A value of the encountered enumerator.
+ */
+ unexpected_enumerator (const std::basic_string<C>& e);
+
+ public:
+ /**
+ * @brief Get the value of the encountered enumerator.
+ *
+ * @return The value of the encountered enumerator.
+ */
+ const std::basic_string<C>&
+ enumerator () const
+ {
+ return enumerator_;
+ }
+
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ //@endcond
+
+ private:
+ std::basic_string<C> enumerator_;
+ };
+
+
+ /**
+ * @brief Exception indicating that the text content was expected
+ * for an element.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class expected_text_content: public exception<C>
+ {
+ public:
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ //@endcond
+ };
+
+
+ /**
+ * @brief Exception indicating that the type information is not
+ * available for a type.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class no_type_info: public exception<C>
+ {
+ public:
+ virtual
+ ~no_type_info () throw ();
+
+ /**
+ * @brief Initialize an instance with the type description.
+ *
+ * @param type_name A name of the type.
+ * @param type_ns A namespace of the type.
+ */
+ no_type_info (const std::basic_string<C>& type_name,
+ const std::basic_string<C>& type_ns);
+
+ public:
+ /**
+ * @brief Get the type name.
+ *
+ * @return The type name.
+ */
+ const std::basic_string<C>&
+ type_name () const
+ {
+ return type_name_;
+ }
+
+ /**
+ * @brief Get the type namespace.
+ *
+ * @return The type namespace.
+ */
+ const std::basic_string<C>&
+ type_namespace () const
+ {
+ return type_namespace_;
+ }
+
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ //@endcond
+
+ private:
+ std::basic_string<C> type_name_;
+ std::basic_string<C> type_namespace_;
+ };
+
+ /**
+ * @brief Exception indicating that %parsing or %serialization
+ * information is not available for an element.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class no_element_info: public exception<C>
+ {
+ public:
+ virtual
+ ~no_element_info () throw ();
+
+ /**
+ * @brief Initialize an instance with the element description.
+ *
+ * @param element_name An element name.
+ * @param element_ns An element namespace.
+ */
+ no_element_info (const std::basic_string<C>& element_name,
+ const std::basic_string<C>& element_ns);
+
+ public:
+ /**
+ * @brief Get the element name.
+ *
+ * @return The element name.
+ */
+ const std::basic_string<C>&
+ element_name () const
+ {
+ return element_name_;
+ }
+
+ /**
+ * @brief Get the element namespace.
+ *
+ * @return The element namespace.
+ */
+ const std::basic_string<C>&
+ element_namespace () const
+ {
+ return element_namespace_;
+ }
+
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ //@endcond
+
+ private:
+ std::basic_string<C> element_name_;
+ std::basic_string<C> element_namespace_;
+ };
+
+ /**
+ * @brief Exception indicating that the types are not related by
+ * inheritance.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class not_derived: public exception<C>
+ {
+ public:
+ virtual
+ ~not_derived () throw ();
+
+ //@cond
+
+ // @@ tmp
+ //
+ not_derived ()
+ {
+ }
+
+ //@endcond
+
+ /**
+ * @brief Initialize an instance with the type descriptions.
+ *
+ * @param base_type_name A name of the base type.
+ * @param base_type_ns A namespace of the base type.
+ * @param derived_type_name A name of the derived type.
+ * @param derived_type_ns A namespace of the derived type.
+ */
+ not_derived (const std::basic_string<C>& base_type_name,
+ const std::basic_string<C>& base_type_ns,
+ const std::basic_string<C>& derived_type_name,
+ const std::basic_string<C>& derived_type_ns);
+
+ public:
+ /**
+ * @brief Get the base type name.
+ *
+ * @return The base type name.
+ */
+ const std::basic_string<C>&
+ base_type_name () const
+ {
+ return base_type_name_;
+ }
+
+ /**
+ * @brief Get the base type namespace.
+ *
+ * @return The base type namespace.
+ */
+ const std::basic_string<C>&
+ base_type_namespace () const
+ {
+ return base_type_namespace_;
+ }
+
+ /**
+ * @brief Get the derived type name.
+ *
+ * @return The derived type name.
+ */
+ const std::basic_string<C>&
+ derived_type_name () const
+ {
+ return derived_type_name_;
+ }
+
+ /**
+ * @brief Get the derived type namespace.
+ *
+ * @return The derived type namespace.
+ */
+ const std::basic_string<C>&
+ derived_type_namespace () const
+ {
+ return derived_type_namespace_;
+ }
+
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ //@endcond
+
+ private:
+ std::basic_string<C> base_type_name_;
+ std::basic_string<C> base_type_namespace_;
+ std::basic_string<C> derived_type_name_;
+ std::basic_string<C> derived_type_namespace_;
+ };
+
+
+ /**
+ * @brief Exception indicating that a duplicate ID value was
+ * encountered in the object model.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class duplicate_id: public exception<C>
+ {
+ public:
+ virtual
+ ~duplicate_id () throw ();
+
+ /**
+ * @brief Initialize an instance with the offending ID value.
+ *
+ * @param id An offending ID value.
+ */
+ duplicate_id (const std::basic_string<C>& id);
+
+ public:
+ /**
+ * @brief Get the offending ID value.
+ *
+ * @return The offending ID value.
+ */
+ const std::basic_string<C>&
+ id () const
+ {
+ return id_;
+ }
+
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ //@endcond
+
+ private:
+ std::basic_string<C> id_;
+ };
+
+
+ /**
+ * @brief Exception indicating a %serialization failure.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class serialization: public exception<C>
+ {
+ public:
+ virtual
+ ~serialization () throw ();
+
+ /**
+ * @brief Default constructor.
+ */
+ serialization ();
+
+ /**
+ * @brief Initialize an instance with a %list of %error conditions.
+ *
+ * @param d A %list of %error conditions.
+ */
+ serialization (const tree::diagnostics<C>& d);
+
+ public:
+ /**
+ * @brief Get the %list of %error conditions.
+ *
+ * @return The %list of %error conditions.
+ */
+ const tree::diagnostics<C>&
+ diagnostics () const
+ {
+ return diagnostics_;
+ }
+
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ //@endcond
+
+ private:
+ tree::diagnostics<C> diagnostics_;
+ };
+
+
+ /**
+ * @brief Exception indicating that a prefix-namespace mapping was
+ * not provided.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class no_prefix_mapping: public exception<C>
+ {
+ public:
+ virtual
+ ~no_prefix_mapping () throw ();
+
+ /**
+ * @brief Initialize an instance with the prefix for which the
+ * prefix-namespace mapping was not provided.
+ *
+ * @param prefix A prefix.
+ */
+ no_prefix_mapping (const std::basic_string<C>& prefix);
+
+ public:
+ /**
+ * @brief Get the prefix for which the prefix-namespace mapping was
+ * not provided.
+ *
+ * @return The prefix.
+ */
+ const std::basic_string<C>&
+ prefix () const
+ {
+ return prefix_;
+ }
+
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ //@endcond
+
+ private:
+ std::basic_string<C> prefix_;
+ };
+
+
+ /**
+ * @brief Exception indicating that the size argument exceeds
+ * the capacity argument.
+ *
+ * See the buffer class for details.
+ *
+ * @nosubgrouping
+ */
+ template <typename C>
+ class bounds: public exception<C>
+ {
+ public:
+ /**
+ * @brief Get %exception description.
+ *
+ * @return A C %string describing the %exception.
+ */
+ virtual const char*
+ what () const throw ();
+
+ protected:
+ //@cond
+
+ virtual void
+ print (std::basic_ostream<C>&) const;
+
+ //@endcond
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/tree/exceptions.txx>
+
+#endif // XSD_CXX_TREE_EXCEPTIONS_HXX
+
+#include <xsd/cxx/tree/exceptions.ixx>
diff --git a/libxsd/xsd/cxx/tree/exceptions.ixx b/libxsd/xsd/cxx/tree/exceptions.ixx
new file mode 100644
index 0000000..427cae3
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/exceptions.ixx
@@ -0,0 +1,467 @@
+// file : xsd/cxx/tree/exceptions.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#if defined(XSD_CXX_TREE_USE_CHAR) || !defined(XSD_CXX_TREE_USE_WCHAR)
+
+#ifndef XSD_CXX_TREE_EXCEPTIONS_IXX_CHAR
+#define XSD_CXX_TREE_EXCEPTIONS_IXX_CHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+
+ // error
+ //
+ inline
+ std::basic_ostream<char>&
+ operator<< (std::basic_ostream<char>& os, const error<char>& e)
+ {
+ return os << e.id () << ':' << e.line () << ':' << e.column ()
+ << (e.severity () == severity::error
+ ? " error: "
+ : " warning: ") << e.message ();
+ }
+
+
+ // diagnostics
+ //
+ inline
+ std::basic_ostream<char>&
+ operator<< (std::basic_ostream<char>& os, const diagnostics<char>& d)
+ {
+ for (diagnostics<char>::const_iterator b (d.begin ()), i (b);
+ i != d.end ();
+ ++i)
+ {
+ if (i != b)
+ os << "\n";
+
+ os << *i;
+ }
+
+ return os;
+ }
+
+
+ // parsing
+ //
+ template<>
+ inline
+ void parsing<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ if (diagnostics_.empty ())
+ os << "instance document parsing failed";
+ else
+ os << diagnostics_;
+ }
+
+
+ // expected_element
+ //
+ template<>
+ inline
+ void expected_element<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ os << "expected element '"
+ << namespace_ () << (namespace_ ().empty () ? "" : "#")
+ << name () << "'";
+ }
+
+
+ // unexpected_element
+ //
+ template<>
+ inline
+ void unexpected_element<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ if (!expected_name ().empty ())
+ {
+ os << "expected element '"
+ << expected_namespace ()
+ << (expected_namespace ().empty () ? "" : "#")
+ << expected_name ()
+ << "' instead of '"
+ << encountered_namespace ()
+ << (encountered_namespace ().empty () ? "" : "#")
+ << encountered_name () << "'";
+ }
+ else
+ {
+ os << "unexpected element '"
+ << encountered_namespace ()
+ << (encountered_namespace ().empty () ? "" : "#")
+ << encountered_name () << "'";
+ }
+ }
+
+
+ // expected_attribute
+ //
+ template<>
+ inline
+ void expected_attribute<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ os << "expected attribute '"
+ << namespace_ () << (namespace_ ().empty () ? "" : "#")
+ << name () << "'";
+ }
+
+
+ // unexpected_enumerator
+ //
+ template<>
+ inline
+ void unexpected_enumerator<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ os << "unexpected enumerator '" << enumerator () << "'";
+ }
+
+
+ // expected_text_content
+ //
+ template<>
+ inline
+ void expected_text_content<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ os << "expected text content";
+ }
+
+
+ // no_type_info
+ //
+ template<>
+ inline
+ void no_type_info<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ os << "no type information available for type '"
+ << type_namespace () << (type_namespace ().empty () ? "" : "#")
+ << type_name () << "'";
+ }
+
+ // no_element_info
+ //
+ template<>
+ inline
+ void no_element_info<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ os << "no parsing or serialization information available for "
+ << "element '" << element_namespace ()
+ << (element_namespace ().empty () ? "" : "#")
+ << element_name () << "'";
+ }
+
+ // not_derived
+ //
+ template<>
+ inline
+ void not_derived<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ os << "type '"
+ << derived_type_namespace ()
+ << (derived_type_namespace ().empty () ? "" : "#")
+ << derived_type_name ()
+ << "' is not derived from '"
+ << base_type_namespace ()
+ << (base_type_namespace ().empty () ? "" : "#")
+ << base_type_name () << "'";
+ }
+
+
+ // duplicate_id
+ //
+ template<>
+ inline
+ void duplicate_id<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ os << "ID '" << id () << "' already exist";
+ }
+
+
+ // serialization
+ //
+ template<>
+ inline
+ void serialization<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ if (diagnostics_.empty ())
+ os << "serialization failed";
+ else
+ os << diagnostics_;
+ }
+
+
+ // no_prefix_mapping
+ //
+ template<>
+ inline
+ void no_prefix_mapping<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ os << "no mapping provided for namespace prefix '"
+ << prefix () << "'";
+ }
+
+
+ // bounds
+ //
+ template<>
+ inline
+ void bounds<char>::
+ print (std::basic_ostream<char>& os) const
+ {
+ os << "buffer boundary rules have been violated";
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_EXCEPTIONS_IXX_CHAR
+#endif // XSD_CXX_TREE_USE_CHAR
+
+
+#if defined(XSD_CXX_TREE_USE_WCHAR) || !defined(XSD_CXX_TREE_USE_CHAR)
+
+#ifndef XSD_CXX_TREE_EXCEPTIONS_IXX_WCHAR
+#define XSD_CXX_TREE_EXCEPTIONS_IXX_WCHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // error
+ //
+ inline
+ std::basic_ostream<wchar_t>&
+ operator<< (std::basic_ostream<wchar_t>& os, const error<wchar_t>& e)
+ {
+ return os << e.id () << L':' << e.line () << L':' << e.column ()
+ << (e.severity () == severity::error
+ ? L" error: "
+ : L" warning: ") << e.message ();
+ }
+
+
+ // diagnostics
+ //
+ inline
+ std::basic_ostream<wchar_t>&
+ operator<< (std::basic_ostream<wchar_t>& os,
+ const diagnostics<wchar_t>& d)
+ {
+ for (diagnostics<wchar_t>::const_iterator b (d.begin ()), i (b);
+ i != d.end ();
+ ++i)
+ {
+ if (i != b)
+ os << L"\n";
+
+ os << *i;
+ }
+
+ return os;
+ }
+
+
+ // parsing
+ //
+ template<>
+ inline
+ void parsing<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ if (diagnostics_.empty ())
+ os << L"instance document parsing failed";
+ else
+ os << diagnostics_;
+ }
+
+
+ // expected_element
+ //
+ template<>
+ inline
+ void expected_element<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ os << L"expected element '"
+ << namespace_ () << (namespace_ ().empty () ? L"" : L"#")
+ << name () << L"'";
+ }
+
+
+ // unexpected_element
+ //
+ template<>
+ inline
+ void unexpected_element<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ if (!expected_name ().empty ())
+ {
+ os << L"expected element '"
+ << expected_namespace ()
+ << (expected_namespace ().empty () ? L"" : L"#")
+ << expected_name ()
+ << L"' instead of '"
+ << encountered_namespace ()
+ << (encountered_namespace ().empty () ? L"" : L"#")
+ << encountered_name () << L"'";
+ }
+ else
+ {
+ os << L"unexpected element '"
+ << encountered_namespace ()
+ << (encountered_namespace ().empty () ? L"" : L"#")
+ << encountered_name () << L"'";
+ }
+ }
+
+
+ // expected_attribute
+ //
+ template<>
+ inline
+ void expected_attribute<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ os << L"expected attribute '"
+ << namespace_ () << (namespace_ ().empty () ? L"" : L"#")
+ << name () << L"'";
+ }
+
+
+ // unexpected_enumerator
+ //
+ template<>
+ inline
+ void unexpected_enumerator<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ os << L"unexpected enumerator '" << enumerator () << L"'";
+ }
+
+
+ // expected_text_content
+ //
+ template<>
+ inline
+ void expected_text_content<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ os << L"expected text content";
+ }
+
+
+ // no_type_info
+ //
+ template<>
+ inline
+ void no_type_info<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ os << L"no type information available for type '"
+ << type_namespace () << (type_namespace ().empty () ? L"" : L"#")
+ << type_name () << L"'";
+ }
+
+ // no_element_info
+ //
+ template<>
+ inline
+ void no_element_info<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ os << L"no parsing or serialization information available for "
+ << L"element '" << element_namespace ()
+ << (element_namespace ().empty () ? L"" : L"#")
+ << element_name () << L"'";
+ }
+
+ // not_derived
+ //
+ template<>
+ inline
+ void not_derived<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ os << L"type '"
+ << derived_type_namespace ()
+ << (derived_type_namespace ().empty () ? L"" : L"#")
+ << derived_type_name ()
+ << L"' is not derived from '"
+ << base_type_namespace ()
+ << (base_type_namespace ().empty () ? L"" : L"#")
+ << base_type_name () << L"'";
+ }
+
+
+ // duplicate_id
+ //
+ template<>
+ inline
+ void duplicate_id<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ os << L"ID '" << id () << L"' already exist";
+ }
+
+
+ // serialization
+ //
+ template<>
+ inline
+ void serialization<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ if (diagnostics_.empty ())
+ os << L"serialization failed";
+ else
+ os << diagnostics_;
+ }
+
+
+ // no_prefix_mapping
+ //
+ template<>
+ inline
+ void no_prefix_mapping<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ os << L"no mapping provided for namespace prefix '"
+ << prefix () << L"'";
+ }
+
+
+ // bounds
+ //
+ template<>
+ inline
+ void bounds<wchar_t>::
+ print (std::basic_ostream<wchar_t>& os) const
+ {
+ os << L"buffer boundary rules have been violated";
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_EXCEPTIONS_IXX_WCHAR
+#endif // XSD_CXX_TREE_USE_WCHAR
diff --git a/libxsd/xsd/cxx/tree/exceptions.txx b/libxsd/xsd/cxx/tree/exceptions.txx
new file mode 100644
index 0000000..cd9bb3a
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/exceptions.txx
@@ -0,0 +1,338 @@
+// file : xsd/cxx/tree/exceptions.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // error
+ //
+ template <typename C>
+ error<C>::
+ error (tree::severity s,
+ const std::basic_string<C>& id,
+ unsigned long line,
+ unsigned long column,
+ const std::basic_string<C>& message)
+ : severity_ (s),
+ id_ (id),
+ line_ (line),
+ column_ (column),
+ message_ (message)
+ {
+ }
+
+ template <typename C>
+ error<C>::
+ error ()
+ : severity_ (tree::severity::error), line_ (0), column_ (0)
+ {
+ }
+
+ // parsing
+ //
+ template <typename C>
+ parsing<C>::
+ ~parsing () throw ()
+ {
+ }
+
+ template <typename C>
+ parsing<C>::
+ parsing ()
+ {
+ }
+
+ template <typename C>
+ parsing<C>::
+ parsing (const tree::diagnostics<C>& diagnostics)
+ : diagnostics_ (diagnostics)
+ {
+ }
+
+ template <typename C>
+ const char* parsing<C>::
+ what () const throw ()
+ {
+ return "instance document parsing failed";
+ }
+
+
+ // expected_element
+ //
+ template <typename C>
+ expected_element<C>::
+ ~expected_element () throw ()
+ {
+ }
+
+ template <typename C>
+ expected_element<C>::
+ expected_element (const std::basic_string<C>& name,
+ const std::basic_string<C>& namespace_)
+ : name_ (name), namespace__ (namespace_)
+ {
+ }
+
+ template <typename C>
+ const char* expected_element<C>::
+ what () const throw ()
+ {
+ return "expected element not encountered";
+ }
+
+
+ // unexpected_element
+ //
+ template <typename C>
+ unexpected_element<C>::
+ ~unexpected_element () throw ()
+ {
+ }
+
+ template <typename C>
+ unexpected_element<C>::
+ unexpected_element (const std::basic_string<C>& encountered_name,
+ const std::basic_string<C>& encountered_namespace,
+ const std::basic_string<C>& expected_name,
+ const std::basic_string<C>& expected_namespace)
+ : encountered_name_ (encountered_name),
+ encountered_namespace_ (encountered_namespace),
+ expected_name_ (expected_name),
+ expected_namespace_ (expected_namespace)
+ {
+ }
+
+ template <typename C>
+ const char* unexpected_element<C>::
+ what () const throw ()
+ {
+ return "unexpected element encountered";
+ }
+
+
+ // expected_attribute
+ //
+ template <typename C>
+ expected_attribute<C>::
+ ~expected_attribute () throw ()
+ {
+ }
+
+ template <typename C>
+ expected_attribute<C>::
+ expected_attribute (const std::basic_string<C>& name,
+ const std::basic_string<C>& namespace_)
+ : name_ (name), namespace__ (namespace_)
+ {
+ }
+
+ template <typename C>
+ const char* expected_attribute<C>::
+ what () const throw ()
+ {
+ return "expected attribute not encountered";
+ }
+
+
+ // unexpected_enumerator
+ //
+ template <typename C>
+ unexpected_enumerator<C>::
+ ~unexpected_enumerator () throw ()
+ {
+ }
+
+ template <typename C>
+ unexpected_enumerator<C>::
+ unexpected_enumerator (const std::basic_string<C>& enumerator)
+ : enumerator_ (enumerator)
+ {
+ }
+
+ template <typename C>
+ const char* unexpected_enumerator<C>::
+ what () const throw ()
+ {
+ return "unexpected enumerator encountered";
+ }
+
+
+ // expected_text_content
+ //
+ template <typename C>
+ const char* expected_text_content<C>::
+ what () const throw ()
+ {
+ return "expected text content";
+ }
+
+
+ // no_type_info
+ //
+ template <typename C>
+ no_type_info<C>::
+ ~no_type_info () throw ()
+ {
+ }
+
+ template <typename C>
+ no_type_info<C>::
+ no_type_info (const std::basic_string<C>& type_name,
+ const std::basic_string<C>& type_namespace)
+ : type_name_ (type_name),
+ type_namespace_ (type_namespace)
+ {
+ }
+
+ template <typename C>
+ const char* no_type_info<C>::
+ what () const throw ()
+ {
+ return "no type information available for a type";
+ }
+
+ // no_element_info
+ //
+ template <typename C>
+ no_element_info<C>::
+ ~no_element_info () throw ()
+ {
+ }
+
+ template <typename C>
+ no_element_info<C>::
+ no_element_info (const std::basic_string<C>& element_name,
+ const std::basic_string<C>& element_namespace)
+ : element_name_ (element_name),
+ element_namespace_ (element_namespace)
+ {
+ }
+
+ template <typename C>
+ const char* no_element_info<C>::
+ what () const throw ()
+ {
+ return "no parsing or serialization information available for "
+ "an element";
+ }
+
+ // not_derived
+ //
+ template <typename C>
+ not_derived<C>::
+ ~not_derived () throw ()
+ {
+ }
+
+ template <typename C>
+ not_derived<C>::
+ not_derived (const std::basic_string<C>& base_type_name,
+ const std::basic_string<C>& base_type_namespace,
+ const std::basic_string<C>& derived_type_name,
+ const std::basic_string<C>& derived_type_namespace)
+ : base_type_name_ (base_type_name),
+ base_type_namespace_ (base_type_namespace),
+ derived_type_name_ (derived_type_name),
+ derived_type_namespace_ (derived_type_namespace)
+ {
+ }
+
+ template <typename C>
+ const char* not_derived<C>::
+ what () const throw ()
+ {
+ return "type is not derived";
+ }
+
+
+ // duplicate_id
+ //
+ template <typename C>
+ duplicate_id<C>::
+ ~duplicate_id () throw ()
+ {
+ }
+
+ template <typename C>
+ duplicate_id<C>::
+ duplicate_id (const std::basic_string<C>& id)
+ : id_ (id)
+ {
+ }
+
+ template <typename C>
+ const char* duplicate_id<C>::
+ what () const throw ()
+ {
+ return "ID already exist";
+ }
+
+
+ // serialization
+ //
+ template <typename C>
+ serialization<C>::
+ ~serialization () throw ()
+ {
+ }
+
+ template <typename C>
+ serialization<C>::
+ serialization ()
+ {
+ }
+
+ template <typename C>
+ serialization<C>::
+ serialization (const tree::diagnostics<C>& diagnostics)
+ : diagnostics_ (diagnostics)
+ {
+ }
+
+ template <typename C>
+ const char* serialization<C>::
+ what () const throw ()
+ {
+ return "serialization failed";
+ }
+
+
+ // no_prefix_mapping
+ //
+ template <typename C>
+ no_prefix_mapping<C>::
+ ~no_prefix_mapping () throw ()
+ {
+ }
+
+ template <typename C>
+ no_prefix_mapping<C>::
+ no_prefix_mapping (const std::basic_string<C>& prefix)
+ : prefix_ (prefix)
+ {
+ }
+
+ template <typename C>
+ const char* no_prefix_mapping<C>::
+ what () const throw ()
+ {
+ return "no mapping provided for a namespace prefix";
+ }
+
+
+ // bounds
+ //
+ template <typename C>
+ const char* bounds<C>::
+ what () const throw ()
+ {
+ return "buffer boundary rules have been violated";
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/facet.hxx b/libxsd/xsd/cxx/tree/facet.hxx
new file mode 100644
index 0000000..e8f585b
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/facet.hxx
@@ -0,0 +1,43 @@
+// file : xsd/cxx/tree/facet.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_FACET_HXX
+#define XSD_CXX_TREE_FACET_HXX
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // We need to keep this type POD in order to be able to create a
+ // static array.
+ //
+ struct facet
+ {
+ enum id_type
+ {
+ none,
+ total_digits,
+ fraction_digits
+ };
+
+ id_type id;
+ unsigned long value;
+
+ static const facet*
+ find (const facet* facets, facet::id_type id)
+ {
+ while (facets->id != id && facets->id != none)
+ ++facets;
+
+ return facets->id != none ? facets : 0;
+ }
+ };
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_FACET_HXX
diff --git a/libxsd/xsd/cxx/tree/istream-fwd.hxx b/libxsd/xsd/cxx/tree/istream-fwd.hxx
new file mode 100644
index 0000000..86bbea5
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/istream-fwd.hxx
@@ -0,0 +1,21 @@
+// file : xsd/cxx/tree/istream-fwd.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_ISTREAM_FWD_HXX
+#define XSD_CXX_TREE_ISTREAM_FWD_HXX
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template<typename S>
+ class istream;
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_ISTREAM_FWD_HXX
diff --git a/libxsd/xsd/cxx/tree/istream.hxx b/libxsd/xsd/cxx/tree/istream.hxx
new file mode 100644
index 0000000..1d58e85
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/istream.hxx
@@ -0,0 +1,258 @@
+// file : xsd/cxx/tree/istream.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_ISTREAM_HXX
+#define XSD_CXX_TREE_ISTREAM_HXX
+
+#include <cstddef> // std::size_t
+
+#include <xsd/cxx/tree/istream-fwd.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ class istream_common
+ {
+ public:
+ template <typename T>
+ struct as_size
+ {
+ explicit as_size (T& x) : x_ (x) {}
+ T& x_;
+ };
+
+
+ // 8-bit
+ //
+ template <typename T>
+ struct as_int8
+ {
+ explicit as_int8 (T& x) : x_ (x) {}
+ T& x_;
+ };
+
+ template <typename T>
+ struct as_uint8
+ {
+ explicit as_uint8 (T& x) : x_ (x) {}
+ T& x_;
+ };
+
+
+ // 16-bit
+ //
+ template <typename T>
+ struct as_int16
+ {
+ explicit as_int16 (T& x) : x_ (x) {}
+ T& x_;
+ };
+
+ template <typename T>
+ struct as_uint16
+ {
+ explicit as_uint16 (T& x) : x_ (x) {}
+ T& x_;
+ };
+
+
+ // 32-bit
+ //
+ template <typename T>
+ struct as_int32
+ {
+ explicit as_int32 (T& x) : x_ (x) {}
+ T& x_;
+ };
+
+ template <typename T>
+ struct as_uint32
+ {
+ explicit as_uint32 (T& x) : x_ (x) {}
+ T& x_;
+ };
+
+
+ // 64-bit
+ //
+ template <typename T>
+ struct as_int64
+ {
+ explicit as_int64 (T& x) : x_ (x) {}
+ T& x_;
+ };
+
+ template <typename T>
+ struct as_uint64
+ {
+ explicit as_uint64 (T& x) : x_ (x) {}
+ T& x_;
+ };
+
+
+ // Boolean
+ //
+ template <typename T>
+ struct as_bool
+ {
+ explicit as_bool (T& x) : x_ (x) {}
+ T& x_;
+ };
+
+
+ // Floating-point
+ //
+ template <typename T>
+ struct as_float32
+ {
+ explicit as_float32 (T& x) : x_ (x) {}
+ T& x_;
+ };
+
+ template <typename T>
+ struct as_float64
+ {
+ explicit as_float64 (T& x) : x_ (x) {}
+ T& x_;
+ };
+ };
+
+ template<typename S>
+ class istream: public istream_common
+ {
+ public:
+ explicit
+ istream (S& s)
+ : s_ (s)
+ {
+ }
+
+ S&
+ impl ()
+ {
+ return s_;
+ }
+
+ private:
+ istream (const istream&);
+ istream&
+ operator= (const istream&);
+
+ private:
+ S& s_;
+ };
+
+
+ // 8-bit
+ //
+ template <typename S>
+ inline istream<S>&
+ operator>> (istream<S>& s, signed char& x)
+ {
+ istream_common::as_int8<signed char> as_int8 (x);
+ return s >> as_int8;
+ }
+
+ template <typename S>
+ inline istream<S>&
+ operator>> (istream<S>& s, unsigned char& x)
+ {
+ istream_common::as_uint8<unsigned char> as_uint8 (x);
+ return s >> as_uint8;
+ }
+
+
+ // 16-bit
+ //
+ template <typename S>
+ inline istream<S>&
+ operator>> (istream<S>& s, short& x)
+ {
+ istream_common::as_int16<short> as_int16 (x);
+ return s >> as_int16;
+ }
+
+ template <typename S>
+ inline istream<S>&
+ operator>> (istream<S>& s, unsigned short& x)
+ {
+ istream_common::as_uint16<unsigned short> as_uint16 (x);
+ return s >> as_uint16;
+ }
+
+
+ // 32-bit
+ //
+ template <typename S>
+ inline istream<S>&
+ operator>> (istream<S>& s, int& x)
+ {
+ istream_common::as_int32<int> as_int32 (x);
+ return s >> as_int32;
+ }
+
+ template <typename S>
+ inline istream<S>&
+ operator>> (istream<S>& s, unsigned int& x)
+ {
+ istream_common::as_uint32<unsigned int> as_uint32 (x);
+ return s >> as_uint32;
+ }
+
+
+ // 64-bit
+ //
+ template <typename S>
+ inline istream<S>&
+ operator>> (istream<S>& s, long long& x)
+ {
+ istream_common::as_int64<long long> as_int64 (x);
+ return s >> as_int64;
+ }
+
+ template <typename S>
+ inline istream<S>&
+ operator>> (istream<S>& s, unsigned long long& x)
+ {
+ istream_common::as_uint64<unsigned long long> as_uint64 (x);
+ return s >> as_uint64;
+ }
+
+ // Boolean
+ //
+ template <typename S>
+ inline istream<S>&
+ operator>> (istream<S>& s, bool& x)
+ {
+ istream_common::as_bool<bool> as_bool (x);
+ return s >> as_bool;
+ }
+
+
+ // Floating-point
+ //
+ template <typename S>
+ inline istream<S>&
+ operator>> (istream<S>& s, float& x)
+ {
+ istream_common::as_float32<float> as_float32 (x);
+ return s >> as_float32;
+ }
+
+ template <typename S>
+ inline istream<S>&
+ operator>> (istream<S>& s, double& x)
+ {
+ istream_common::as_float64<double> as_float64 (x);
+ return s >> as_float64;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_ISTREAM_HXX
diff --git a/libxsd/xsd/cxx/tree/list.hxx b/libxsd/xsd/cxx/tree/list.hxx
new file mode 100644
index 0000000..75972c6
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/list.hxx
@@ -0,0 +1,132 @@
+// file : xsd/cxx/tree/list.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_LIST_HXX
+#define XSD_CXX_TREE_LIST_HXX
+
+#include <string>
+
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMElement.hpp>
+
+#include <xsd/cxx/tree/elements.hxx> // tree::istream
+#include <xsd/cxx/tree/istream-fwd.hxx> // tree::istream
+#include <xsd/cxx/tree/containers.hxx> // fundamental_p, sequence
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // Class template for xsd:list mapping. Based on the sequence
+ // template. Note that I cannot get rid of 'fund' because HP
+ // aCC3 likes it this way.
+ //
+ template <typename T,
+ typename C,
+ schema_type::value ST = schema_type::other,
+ bool fund = fundamental_p<T>::r>
+ class list;
+
+
+ //
+ //
+ template <typename T, typename C, schema_type::value ST>
+ class list<T, C, ST, false>: public sequence<T>
+ {
+ public:
+ explicit
+ list (flags f = 0, container* c = 0)
+ : sequence<T> (f, c)
+ {
+ }
+
+ list (typename sequence<T>::size_type n, const T& x)
+ : sequence<T> (n, x)
+ {
+ }
+
+ template<typename I>
+ list (const I& b, const I& e)
+ : sequence<T> (b, e)
+ {
+ }
+
+ template <typename S>
+ list (istream<S>&, flags = 0, container* c = 0);
+
+ list (const list<T, C, ST, false>& v, flags f = 0, container* c = 0)
+ : sequence<T> (v, f, c)
+ {
+ }
+
+ public:
+ list (const xercesc::DOMElement&, flags = 0, container* c = 0);
+
+ list (const xercesc::DOMAttr&, flags = 0, container* c = 0);
+
+ list (const std::basic_string<C>&,
+ const xercesc::DOMElement*,
+ flags = 0,
+ container* c = 0);
+
+ private:
+ void
+ init (const std::basic_string<C>&, const xercesc::DOMElement*);
+ };
+
+
+ //
+ //
+ template <typename T, typename C, schema_type::value ST>
+ class list<T, C, ST, true>: public sequence<T>
+ {
+ public:
+ explicit
+ list (flags f = 0, container* c = 0)
+ : sequence<T> (f, c)
+ {
+ }
+
+ explicit
+ list (typename sequence<T>::size_type n, const T& x)
+ : sequence<T> (n, x)
+ {
+ }
+
+ template<typename I>
+ list (const I& b, const I& e)
+ : sequence<T> (b, e)
+ {
+ }
+
+ template <typename S>
+ list (istream<S>&, flags = 0, container* c = 0);
+
+ list (const list<T, C, ST, true>& s, flags f = 0, container* c = 0)
+ : sequence<T> (s, f, c)
+ {
+ }
+
+ public:
+ list (const xercesc::DOMElement&, flags = 0, container* c = 0);
+
+ list (const xercesc::DOMAttr&, flags = 0, container* c = 0);
+
+ list (const std::basic_string<C>&,
+ const xercesc::DOMElement*,
+ flags = 0,
+ container* c = 0);
+
+ private:
+ void
+ init (const std::basic_string<C>&, const xercesc::DOMElement*);
+ };
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_LIST_HXX
diff --git a/libxsd/xsd/cxx/tree/ostream.hxx b/libxsd/xsd/cxx/tree/ostream.hxx
new file mode 100644
index 0000000..5cc854b
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/ostream.hxx
@@ -0,0 +1,245 @@
+// file : xsd/cxx/tree/ostream.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_OSTREAM_HXX
+#define XSD_CXX_TREE_OSTREAM_HXX
+
+#include <cstddef> // std::size_t
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ class ostream_common
+ {
+ public:
+ template <typename T>
+ struct as_size
+ {
+ explicit as_size (T x) : x_ (x) {}
+ T x_;
+ };
+
+
+ // 8-bit
+ //
+ template <typename T>
+ struct as_int8
+ {
+ explicit as_int8 (T x) : x_ (x) {}
+ T x_;
+ };
+
+ template <typename T>
+ struct as_uint8
+ {
+ explicit as_uint8 (T x) : x_ (x) {}
+ T x_;
+ };
+
+
+ // 16-bit
+ //
+ template <typename T>
+ struct as_int16
+ {
+ explicit as_int16 (T x) : x_ (x) {}
+ T x_;
+ };
+
+ template <typename T>
+ struct as_uint16
+ {
+ explicit as_uint16 (T x) : x_ (x) {}
+ T x_;
+ };
+
+
+ // 32-bit
+ //
+ template <typename T>
+ struct as_int32
+ {
+ explicit as_int32 (T x) : x_ (x) {}
+ T x_;
+ };
+
+ template <typename T>
+ struct as_uint32
+ {
+ explicit as_uint32 (T x) : x_ (x) {}
+ T x_;
+ };
+
+
+ // 64-bit
+ //
+ template <typename T>
+ struct as_int64
+ {
+ explicit as_int64 (T x) : x_ (x) {}
+ T x_;
+ };
+
+ template <typename T>
+ struct as_uint64
+ {
+ explicit as_uint64 (T x) : x_ (x) {}
+ T x_;
+ };
+
+
+ // Boolean
+ //
+ template <typename T>
+ struct as_bool
+ {
+ explicit as_bool (T x) : x_ (x) {}
+ T x_;
+ };
+
+
+ // Floating-point
+ //
+ template <typename T>
+ struct as_float32
+ {
+ explicit as_float32 (T x) : x_ (x) {}
+ T x_;
+ };
+
+ template <typename T>
+ struct as_float64
+ {
+ explicit as_float64 (T x) : x_ (x) {}
+ T x_;
+ };
+ };
+
+ template<typename S>
+ class ostream: public ostream_common
+ {
+ public:
+ explicit
+ ostream (S& s)
+ : s_ (s)
+ {
+ }
+
+ S&
+ impl ()
+ {
+ return s_;
+ }
+
+ private:
+ ostream (const ostream&);
+ ostream&
+ operator= (const ostream&);
+
+ private:
+ S& s_;
+ };
+
+
+ // 8-bit
+ //
+ template <typename S>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, signed char x)
+ {
+ return s << ostream_common::as_int8<signed char> (x);
+ }
+
+ template <typename S>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, unsigned char x)
+ {
+ return s << ostream_common::as_uint8<unsigned char> (x);
+ }
+
+
+ // 16-bit
+ //
+ template <typename S>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, short x)
+ {
+ return s << ostream_common::as_int16<short> (x);
+ }
+
+ template <typename S>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, unsigned short x)
+ {
+ return s << ostream_common::as_uint16<unsigned short> (x);
+ }
+
+
+ // 32-bit
+ //
+ template <typename S>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, int x)
+ {
+ return s << ostream_common::as_int32<int> (x);
+ }
+
+ template <typename S>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, unsigned int x)
+ {
+ return s << ostream_common::as_uint32<unsigned int> (x);
+ }
+
+
+ // 64-bit
+ //
+ template <typename S>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, long long x)
+ {
+ return s << ostream_common::as_int64<long long> (x);
+ }
+
+ template <typename S>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, unsigned long long x)
+ {
+ return s << ostream_common::as_uint64<unsigned long long> (x);
+ }
+
+ // Boolean
+ //
+ template <typename S>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, bool x)
+ {
+ return s << ostream_common::as_bool<bool> (x);
+ }
+
+
+ // Floating-point
+ //
+ template <typename S>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, float x)
+ {
+ return s << ostream_common::as_float32<float> (x);
+ }
+
+ template <typename S>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, double x)
+ {
+ return s << ostream_common::as_float64<double> (x);
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_OSTREAM_HXX
diff --git a/libxsd/xsd/cxx/tree/parsing.hxx b/libxsd/xsd/cxx/tree/parsing.hxx
new file mode 100644
index 0000000..6c21ade
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing.hxx
@@ -0,0 +1,12 @@
+// file : xsd/cxx/tree/parsing.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_HXX
+#define XSD_CXX_TREE_PARSING_HXX
+
+#include <xsd/cxx/tree/parsing.txx>
+#include <xsd/cxx/tree/parsing/date-time.txx>
+
+#endif // XSD_CXX_TREE_PARSING_HXX
diff --git a/libxsd/xsd/cxx/tree/parsing.txx b/libxsd/xsd/cxx/tree/parsing.txx
new file mode 100644
index 0000000..ebbf17b
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing.txx
@@ -0,0 +1,915 @@
+// file : xsd/cxx/tree/parsing.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <string>
+
+#include <xsd/cxx/ro-string.hxx> // trim
+
+#include <xsd/cxx/xml/string.hxx> // xml::{string, transcode}
+#include <xsd/cxx/xml/elements.hxx> // xml::{prefix, uq_name}
+#include <xsd/cxx/xml/bits/literals.hxx> // xml::bits::{xml_prefix,
+ // xml_namespace}
+
+#include <xsd/cxx/tree/exceptions.hxx> // no_prefix_mapping
+#include <xsd/cxx/tree/elements.hxx>
+#include <xsd/cxx/tree/types.hxx>
+#include <xsd/cxx/tree/list.hxx>
+#include <xsd/cxx/tree/text.hxx> // text_content
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // Note that most of the types implemented here (except string,
+ // (normalizedString, and base64Binary) cannot have whitespaces
+ // in the value. 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.
+ //
+
+ // type
+ //
+ inline _type::
+ _type (const xercesc::DOMElement& e, flags f, container* c)
+ : dom_info_ (0), container_ (c)
+ {
+ if (f & flags::keep_dom)
+ {
+ std::auto_ptr<dom_info> r (
+ dom_info_factory::create (e, *this, c == 0));
+ dom_info_ = r;
+ }
+ }
+
+ inline _type::
+ _type (const xercesc::DOMAttr& a, flags f, container* c)
+ : dom_info_ (0), container_ (c)
+ {
+ if (f & flags::keep_dom)
+ {
+ std::auto_ptr<dom_info> r (dom_info_factory::create (a, *this));
+ dom_info_ = r;
+ }
+ }
+
+ template <typename C>
+ inline _type::
+ _type (const std::basic_string<C>&,
+ const xercesc::DOMElement*,
+ flags,
+ container* c)
+ : dom_info_ (0), // List elements don't have associated DOM nodes.
+ container_ (c)
+ {
+ }
+
+ // simple_type
+ //
+ template <typename B>
+ inline simple_type<B>::
+ simple_type (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c)
+ {
+ }
+
+ template <typename B>
+ inline simple_type<B>::
+ simple_type (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c)
+ {
+ }
+
+ template <typename B>
+ template <typename C>
+ inline simple_type<B>::
+ simple_type (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c)
+ {
+ }
+
+ // fundamental_base
+ //
+ template <typename T, typename C, typename B, schema_type::value ST>
+ fundamental_base<T, C, B, ST>::
+ fundamental_base (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c),
+ facet_table_ (0),
+ x_ (traits<T, C, ST>::create (e, f, c))
+ {
+ }
+
+ template <typename T, typename C, typename B, schema_type::value ST>
+ fundamental_base<T, C, B, ST>::
+ fundamental_base (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c),
+ facet_table_ (0),
+ x_ (traits<T, C, ST>::create (a, f, c))
+ {
+ }
+
+ template <typename T, typename C, typename B, schema_type::value ST>
+ fundamental_base<T, C, B, ST>::
+ fundamental_base (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c),
+ facet_table_ (0),
+ x_ (traits<T, C, ST>::create (s, e, f, c))
+ {
+ }
+
+
+ // Parsing c-tors for list.
+ //
+
+ namespace bits
+ {
+ // Find first non-space character.
+ //
+ template <typename C>
+ typename std::basic_string<C>::size_type
+ find_ns (const C* s,
+ typename std::basic_string<C>::size_type size,
+ typename std::basic_string<C>::size_type pos)
+ {
+ while (pos < size &&
+ (s[pos] == C (0x20) || // space
+ s[pos] == C (0x0D) || // carriage return
+ s[pos] == C (0x09) || // tab
+ s[pos] == C (0x0A)))
+ ++pos;
+
+ return pos < size ? pos : std::basic_string<C>::npos;
+ }
+
+ // Find first space character.
+ //
+ template <typename C>
+ typename std::basic_string<C>::size_type
+ find_s (const C* s,
+ typename std::basic_string<C>::size_type size,
+ typename std::basic_string<C>::size_type pos)
+ {
+ while (pos < size &&
+ s[pos] != C (0x20) && // space
+ s[pos] != C (0x0D) && // carriage return
+ s[pos] != C (0x09) && // tab
+ s[pos] != C (0x0A))
+ ++pos;
+
+ return pos < size ? pos : std::basic_string<C>::npos;
+ }
+ }
+
+ // Individual items of the list have no DOM association. Therefore
+ // I clear keep_dom from flags.
+ //
+
+ template <typename T, typename C, schema_type::value ST>
+ list<T, C, ST, false>::
+ list (const xercesc::DOMElement& e, flags f, container* c)
+ : sequence<T> (flags (f & ~flags::keep_dom), c) // ambiguous
+ {
+ init (text_content<C> (e), &e);
+ }
+
+ template <typename T, typename C, schema_type::value ST>
+ list<T, C, ST, false>::
+ list (const xercesc::DOMAttr& a, flags f, container* c)
+ : sequence<T> (flags (f & ~flags::keep_dom), c) // ambiguous
+ {
+ init (xml::transcode<C> (a.getValue ()), a.getOwnerElement ());
+ }
+
+ template <typename T, typename C, schema_type::value ST>
+ list<T, C, ST, false>::
+ list (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : sequence<T> (flags (f & ~flags::keep_dom), c) // ambiguous
+ {
+ init (s, e);
+ }
+
+ template <typename T, typename C, schema_type::value ST>
+ void list<T, C, ST, false>::
+ init (const std::basic_string<C>& s, const xercesc::DOMElement* parent)
+ {
+ if (s.size () == 0)
+ return;
+
+ using std::basic_string;
+ typedef typename sequence<T>::ptr ptr;
+ typedef typename basic_string<C>::size_type size_type;
+
+ const C* data (s.c_str ());
+ size_type size (s.size ());
+
+ // Traverse the data while logically collapsing spaces.
+ //
+ for (size_type i (bits::find_ns<C> (data, size, 0));
+ i != basic_string<C>::npos;)
+ {
+ size_type j (bits::find_s (data, size, i));
+
+ if (j != basic_string<C>::npos)
+ {
+ ptr r (
+ new T (basic_string<C> (data + i, j - i),
+ parent,
+ this->flags_,
+ this->container_));
+
+ this->v_.push_back (r);
+
+ i = bits::find_ns (data, size, j);
+ }
+ else
+ {
+ // Last element.
+ //
+ ptr r (
+ new T (basic_string<C> (data + i, size - i),
+ parent,
+ this->flags_,
+ this->container_));
+
+ this->v_.push_back (r);
+
+ break;
+ }
+ }
+ }
+
+ template <typename T, typename C, schema_type::value ST>
+ list<T, C, ST, true>::
+ list (const xercesc::DOMElement& e, flags f, container* c)
+ : sequence<T> (flags (f & ~flags::keep_dom), c) // ambiguous
+ {
+ init (text_content<C> (e), &e);
+ }
+
+ template <typename T, typename C, schema_type::value ST>
+ inline list<T, C, ST, true>::
+ list (const xercesc::DOMAttr& a, flags f, container* c)
+ : sequence<T> (flags (f & ~flags::keep_dom), c) // ambiguous
+ {
+ init (xml::transcode<C> (a.getValue ()), a.getOwnerElement ());
+ }
+
+ template <typename T, typename C, schema_type::value ST>
+ inline list<T, C, ST, true>::
+ list (const std::basic_string<C>& s,
+ const xercesc::DOMElement* parent,
+ flags f,
+ container* c)
+ : sequence<T> (flags (f & ~flags::keep_dom), c) // ambiguous
+ {
+ init (s, parent);
+ }
+
+ template <typename T, typename C, schema_type::value ST>
+ inline void list<T, C, ST, true>::
+ init (const std::basic_string<C>& s, const xercesc::DOMElement* parent)
+ {
+ if (s.size () == 0)
+ return;
+
+ using std::basic_string;
+ typedef typename basic_string<C>::size_type size_type;
+
+ const C* data (s.c_str ());
+ size_type size (s.size ());
+
+ // Traverse the data while logically collapsing spaces.
+ //
+ for (size_type i (bits::find_ns<C> (data, size, 0));
+ i != basic_string<C>::npos;)
+ {
+ size_type j (bits::find_s (data, size, i));
+
+ if (j != basic_string<C>::npos)
+ {
+ push_back (
+ traits<T, C, ST>::create (
+ basic_string<C> (data + i, j - i), parent, 0, 0));
+
+ i = bits::find_ns (data, size, j);
+ }
+ else
+ {
+ // Last element.
+ //
+ push_back (
+ traits<T, C, ST>::create (
+ basic_string<C> (data + i, size - i), parent, 0, 0));
+
+ break;
+ }
+ }
+ }
+
+
+ // Parsing c-tors for built-in types.
+ //
+
+
+ // string
+ //
+ template <typename C, typename B>
+ string<C, B>::
+ string (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c),
+ base_type (text_content<C> (e))
+ {
+ }
+
+ template <typename C, typename B>
+ string<C, B>::
+ string (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c),
+ base_type (xml::transcode<C> (a.getValue ()))
+ {
+ }
+
+ template <typename C, typename B>
+ string<C, B>::
+ string (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c), base_type (s)
+ {
+ }
+
+
+ // normalized_string
+ //
+ template <typename C, typename B>
+ normalized_string<C, B>::
+ normalized_string (const xercesc::DOMElement& e, flags f, container* c)
+ : base_type (e, f, c)
+ {
+ normalize ();
+ }
+
+ template <typename C, typename B>
+ normalized_string<C, B>::
+ normalized_string (const xercesc::DOMAttr& a, flags f, container* c)
+ : base_type (a, f, c)
+ {
+ normalize ();
+ }
+
+ template <typename C, typename B>
+ normalized_string<C, B>::
+ normalized_string (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : base_type (s, e, f, c)
+ {
+ normalize ();
+ }
+
+ template <typename C, typename B>
+ void normalized_string<C, B>::
+ normalize ()
+ {
+ typedef typename std::basic_string<C>::size_type size_type;
+
+ size_type size (this->size ());
+
+ for (size_type i (0); i < size; ++i)
+ {
+ C& c ((*this)[i]);
+
+ if (c == C (0x0D) || // carriage return
+ c == C (0x09) || // tab
+ c == C (0x0A))
+ c = C (0x20);
+ }
+ }
+
+
+ // token
+ //
+ template <typename C, typename B>
+ token<C, B>::
+ token (const xercesc::DOMElement& e, flags f, container* c)
+ : base_type (e, f, c)
+ {
+ collapse ();
+ }
+
+ template <typename C, typename B>
+ token<C, B>::
+ token (const xercesc::DOMAttr& a, flags f, container* c)
+ : base_type (a, f, c)
+ {
+ collapse ();
+ }
+
+ template <typename C, typename B>
+ token<C, B>::
+ token (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : base_type (s, e, f, c)
+ {
+ collapse ();
+ }
+
+ template <typename C, typename B>
+ void token<C, B>::
+ collapse ()
+ {
+ // We have all whitespace normilized by our base. We just
+ // need to collapse them.
+ //
+ typedef typename std::basic_string<C>::size_type size_type;
+
+ size_type size (this->size ()), j (0);
+ bool subs (false), trim (true);
+
+ for (size_type i (0); i < size; ++i)
+ {
+ C c ((*this)[i]);
+
+ if (c == C (0x20))
+ {
+ subs = true;
+ }
+ else
+ {
+ if (subs)
+ {
+ subs = false;
+
+ if (!trim)
+ (*this)[j++] = C (0x20);
+ }
+
+ if (trim)
+ trim = false;
+
+ (*this)[j++] = c;
+ }
+ }
+
+ this->resize (j);
+ }
+
+
+ // nmtoken
+ //
+ template <typename C, typename B>
+ nmtoken<C, B>::
+ nmtoken (const xercesc::DOMElement& e, flags f, container* c)
+ : base_type (e, f, c)
+ {
+ }
+
+ template <typename C, typename B>
+ nmtoken<C, B>::
+ nmtoken (const xercesc::DOMAttr& a, flags f, container* c)
+ : base_type (a, f, c)
+ {
+ }
+
+ template <typename C, typename B>
+ nmtoken<C, B>::
+ nmtoken (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : base_type (s, e, f, c)
+ {
+ }
+
+
+ // nmtokens
+ //
+ template <typename C, typename B, typename nmtoken>
+ nmtokens<C, B, nmtoken>::
+ nmtokens (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c), base_type (e, f, c)
+ {
+ }
+
+ template <typename C, typename B, typename nmtoken>
+ nmtokens<C, B, nmtoken>::
+ nmtokens (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c), base_type (a, f, c)
+ {
+ }
+
+ template <typename C, typename B, typename nmtoken>
+ nmtokens<C, B, nmtoken>::
+ nmtokens (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c), base_type (s, e, f, c)
+ {
+ }
+
+
+ // name
+ //
+ template <typename C, typename B>
+ name<C, B>::
+ name (const xercesc::DOMElement& e, flags f, container* c)
+ : base_type (e, f, c)
+ {
+ }
+
+ template <typename C, typename B>
+ name<C, B>::
+ name (const xercesc::DOMAttr& a, flags f, container* c)
+ : base_type (a, f, c)
+ {
+ }
+
+ template <typename C, typename B>
+ name<C, B>::
+ name (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : base_type (s, e, f, c)
+ {
+ }
+
+
+ // ncname
+ //
+ template <typename C, typename B>
+ ncname<C, B>::
+ ncname (const xercesc::DOMElement& e, flags f, container* c)
+ : base_type (e, f, c)
+ {
+ }
+
+ template <typename C, typename B>
+ ncname<C, B>::
+ ncname (const xercesc::DOMAttr& a, flags f, container* c)
+ : base_type (a, f, c)
+ {
+ }
+
+ template <typename C, typename B>
+ ncname<C, B>::
+ ncname (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : base_type (s, e, f, c)
+ {
+ }
+
+
+ // language
+ //
+ template <typename C, typename B>
+ language<C, B>::
+ language (const xercesc::DOMElement& e, flags f, container* c)
+ : base_type (e, f, c)
+ {
+ }
+
+ template <typename C, typename B>
+ language<C, B>::
+ language (const xercesc::DOMAttr& a, flags f, container* c)
+ : base_type (a, f, c)
+ {
+ }
+
+ template <typename C, typename B>
+ language<C, B>::
+ language (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : base_type (s, e, f, c)
+ {
+ }
+
+
+ // id
+ //
+ template <typename C, typename B>
+ id<C, B>::
+ id (const xercesc::DOMElement& e, flags f, container* c)
+ : base_type (e, f, c), identity_ (*this)
+ {
+ register_id ();
+ }
+
+ template <typename C, typename B>
+ id<C, B>::
+ id (const xercesc::DOMAttr& a, flags f, container* c)
+ : base_type (a, f, c), identity_ (*this)
+ {
+ register_id ();
+ }
+
+ template <typename C, typename B>
+ id<C, B>::
+ id (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : base_type (s, e, f, c), identity_ (*this)
+ {
+ register_id ();
+ }
+
+
+ // idref
+ //
+ template <typename T, typename C, typename B>
+ idref<T, C, B>::
+ idref (const xercesc::DOMElement& e, flags f, container* c)
+ : base_type (e, f, c), identity_ (*this)
+ {
+ }
+
+ template <typename T, typename C, typename B>
+ idref<T, C, B>::
+ idref (const xercesc::DOMAttr& a, flags f, container* c)
+ : base_type (a, f , c), identity_ (*this)
+ {
+ }
+
+ template <typename T, typename C, typename B>
+ idref<T, C, B>::
+ idref (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : base_type (s, e, f, c), identity_ (*this)
+ {
+ }
+
+
+
+ // idrefs
+ //
+ template <typename C, typename B, typename idref>
+ idrefs<C, B, idref>::
+ idrefs (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c), base_type (e, f, c)
+ {
+ }
+
+ template <typename C, typename B, typename idref>
+ idrefs<C, B, idref>::
+ idrefs (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c), base_type (a, f, c)
+ {
+ }
+
+ template <typename C, typename B, typename idref>
+ idrefs<C, B, idref>::
+ idrefs (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c), base_type (s, e, f, c)
+ {
+ }
+
+
+ // uri
+ //
+ template <typename C, typename B>
+ uri<C, B>::
+ uri (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c),
+ base_type (trim (text_content<C> (e)))
+ {
+ }
+
+ template <typename C, typename B>
+ uri<C, B>::
+ uri (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c),
+ base_type (trim (xml::transcode<C> (a.getValue ())))
+ {
+ }
+
+ template <typename C, typename B>
+ uri<C, B>::
+ uri (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c), base_type (trim (s))
+ {
+ }
+
+
+ // qname
+ //
+ template <typename C, typename B, typename uri, typename ncname>
+ qname<C, B, uri, ncname>::
+ qname (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c)
+ {
+ std::basic_string<C> v (trim (text_content<C> (e)));
+ ns_ = resolve (v, &e);
+ name_ = xml::uq_name (v);
+ }
+
+ template <typename C, typename B, typename uri, typename ncname>
+ qname<C, B, uri, ncname>::
+ qname (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c)
+ {
+ std::basic_string<C> v (trim (xml::transcode<C> (a.getValue ())));
+ ns_ = resolve (v, a.getOwnerElement ());
+ name_ = xml::uq_name (v);
+ }
+
+ template <typename C, typename B, typename uri, typename ncname>
+ qname<C, B, uri, ncname>::
+ qname (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c)
+ {
+ std::basic_string<C> v (trim (s));
+ ns_ = resolve (v, e);
+ name_ = xml::uq_name (v);
+ }
+
+ template <typename C, typename B, typename uri, typename ncname>
+ uri qname<C, B, uri, ncname>::
+ resolve (const std::basic_string<C>& s, const xercesc::DOMElement* e)
+ {
+ std::basic_string<C> p (xml::prefix (s));
+
+ if (e)
+ {
+ // This code is copied verbatim from xml/dom/elements.hxx.
+ //
+
+ // 'xml' prefix requires special handling and Xerces folks refuse
+ // to handle this in DOM so I have to do it myself.
+ //
+ if (p == xml::bits::xml_prefix<C> ())
+ return xml::bits::xml_namespace<C> ();
+
+ const XMLCh* xns (
+ e->lookupNamespaceURI (
+ p.empty () ? 0 : xml::string (p).c_str ()));
+
+ if (xns != 0)
+ return xml::transcode<C> (xns);
+ else if (p.empty ())
+ return std::basic_string<C> ();
+ }
+
+ throw no_prefix_mapping<C> (p);
+ }
+
+
+ // base64_binary
+ //
+ // We are not doing whitespace collapsing since the decode
+ // functions can handle it like this.
+ //
+ template <typename C, typename B>
+ base64_binary<C, B>::
+ base64_binary (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c)
+ {
+ // This implementation is not optimal.
+ //
+ std::basic_string<C> str (trim (text_content<C> (e)));
+ decode (xml::string (str).c_str ());
+ }
+
+ template <typename C, typename B>
+ base64_binary<C, B>::
+ base64_binary (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c)
+ {
+ std::basic_string<C> str (trim (xml::transcode<C> (a.getValue ())));
+ decode (xml::string (str).c_str ());
+ }
+
+ template <typename C, typename B>
+ base64_binary<C, B>::
+ base64_binary (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c)
+ {
+ std::basic_string<C> str (trim (s));
+ decode (xml::string (str).c_str ());
+ }
+
+
+ // hex_binary
+ //
+ template <typename C, typename B>
+ hex_binary<C, B>::
+ hex_binary (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c)
+ {
+ // This implementation is not optimal.
+ //
+ std::basic_string<C> str (trim (text_content<C> (e)));
+ decode (xml::string (str).c_str ());
+ }
+
+ template <typename C, typename B>
+ hex_binary<C, B>::
+ hex_binary (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c)
+ {
+ std::basic_string<C> str (trim (xml::transcode<C> (a.getValue ())));
+ decode (xml::string (str).c_str ());
+ }
+
+ template <typename C, typename B>
+ hex_binary<C, B>::
+ hex_binary (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c)
+ {
+ std::basic_string<C> str (trim (s));
+ decode (xml::string (str).c_str ());
+ }
+
+ // entity
+ //
+ template <typename C, typename B>
+ entity<C, B>::
+ entity (const xercesc::DOMElement& e, flags f, container* c)
+ : base_type (e, f, c)
+ {
+ }
+
+ template <typename C, typename B>
+ entity<C, B>::
+ entity (const xercesc::DOMAttr& a, flags f, container* c)
+ : base_type (a, f, c)
+ {
+ }
+
+ template <typename C, typename B>
+ entity<C, B>::
+ entity (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : base_type (s, e, f, c)
+ {
+ }
+
+
+ // entities
+ //
+ template <typename C, typename B, typename entity>
+ entities<C, B, entity>::
+ entities (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c), base_type (e, f, c)
+ {
+ }
+
+ template <typename C, typename B, typename entity>
+ entities<C, B, entity>::
+ entities (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c), base_type (a, f, c)
+ {
+ }
+
+ template <typename C, typename B, typename entity>
+ entities<C, B, entity>::
+ entities (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c), base_type (s, e, f, c)
+ {
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/parsing/boolean.hxx b/libxsd/xsd/cxx/tree/parsing/boolean.hxx
new file mode 100644
index 0000000..28f1b11
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/boolean.hxx
@@ -0,0 +1,76 @@
+// file : xsd/cxx/tree/parsing/boolean.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_BOOLEAN_HXX
+#define XSD_CXX_TREE_PARSING_BOOLEAN_HXX
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include <xsd/cxx/tree/text.hxx> // text_content
+#include <xsd/cxx/tree/bits/literals.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct traits<bool, C, schema_type::other>
+ {
+ typedef bool type;
+
+ static type
+ create (const xercesc::DOMElement& e, flags f, container* c);
+
+ static type
+ create (const xercesc::DOMAttr& a, flags f, container* c);
+
+ static type
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*);
+ };
+
+ template <typename C>
+ bool traits<bool, C, schema_type::other>::
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return create (text_content<C> (e), 0, f, c);
+ }
+
+ template <typename C>
+ bool traits<bool, C, schema_type::other>::
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return create (xml::transcode<C> (a.getValue ()), 0, f, c);
+ }
+
+ template <typename C>
+ bool traits<bool, C, schema_type::other>::
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*)
+ {
+ // 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<C> tmp (s);
+ trim (tmp);
+
+ return tmp == bits::true_<C> () || tmp == bits::one<C> ();
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_PARSING_BOOLEAN_HXX
diff --git a/libxsd/xsd/cxx/tree/parsing/byte.hxx b/libxsd/xsd/cxx/tree/parsing/byte.hxx
new file mode 100644
index 0000000..2924ca0
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/byte.hxx
@@ -0,0 +1,80 @@
+// file : xsd/cxx/tree/parsing/byte.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_BYTE_HXX
+#define XSD_CXX_TREE_PARSING_BYTE_HXX
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include <xsd/cxx/tree/text.hxx> // text_content
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct traits<signed char, C, schema_type::other>
+ {
+ typedef signed char type;
+
+ static type
+ create (const xercesc::DOMElement& e, flags f, container* c);
+
+ static type
+ create (const xercesc::DOMAttr& a, flags f, container* c);
+
+ static type
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*);
+ };
+
+ template <typename C>
+ signed char traits<signed char, C, schema_type::other>::
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return create (text_content<C> (e), 0, f, c);
+ }
+
+ template <typename C>
+ signed char traits<signed char, C, schema_type::other>::
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return create (xml::transcode<C> (a.getValue ()), 0, f, c);
+ }
+
+ template <typename C>
+ signed char traits<signed char, C, schema_type::other>::
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*)
+ {
+ // 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<C> tmp (s);
+ trim (tmp);
+
+ zc_istream<C> is (tmp);
+
+ short t;
+ is >> t;
+
+ return static_cast<type> (t);
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_PARSING_BYTE_HXX
diff --git a/libxsd/xsd/cxx/tree/parsing/date-time.txx b/libxsd/xsd/cxx/tree/parsing/date-time.txx
new file mode 100644
index 0000000..85fb909
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/date-time.txx
@@ -0,0 +1,702 @@
+// file : xsd/cxx/tree/parsing/date-time.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include <xsd/cxx/tree/text.hxx> // text_content
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // time_zone
+ //
+ template <typename C>
+ void time_zone::
+ zone_parse (const C* s, std::size_t n)
+ {
+ // time_zone := Z|(+|-)HH:MM
+ //
+ if (n == 0)
+ {
+ return;
+ }
+ else if (s[0] == C ('Z'))
+ {
+ hours_ = 0;
+ minutes_ = 0;
+ present_ = true;
+ }
+ else if (n == 6)
+ {
+ // Parse hours.
+ //
+ hours_ = 10 * (s[1] - C ('0')) + (s[2] - C ('0'));
+
+ // Parse minutes.
+ //
+ minutes_ = 10 * (s[4] - C ('0')) + (s[5] - C ('0'));
+
+ if (s[0] == C ('-'))
+ {
+ hours_ = -hours_;
+ minutes_ = -minutes_;
+ }
+ present_ = true;
+ }
+ }
+
+ // gday
+ //
+ template <typename C, typename B>
+ gday<C, B>::
+ gday (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c)
+ {
+ parse (text_content<C> (e));
+ }
+
+ template <typename C, typename B>
+ gday<C, B>::
+ gday (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c)
+ {
+ parse (xml::transcode<C> (a.getValue ()));
+ }
+
+ template <typename C, typename B>
+ gday<C, B>::
+ gday (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c)
+ {
+ parse (s);
+ }
+
+ template <typename C, typename B>
+ void gday<C, B>::
+ parse (const std::basic_string<C>& str)
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str);
+ size_type n (trim (tmp));
+ const C* s (tmp.data ());
+
+ // gday := ---DD[Z|(+|-)HH:MM]
+ //
+ if (n >= 5)
+ {
+ day_ = 10 * (s[3] - C ('0')) + (s[4] - C ('0'));
+
+ if (n > 5)
+ zone_parse (s + 5, n - 5);
+ }
+ }
+
+ // gmonth
+ //
+ template <typename C, typename B>
+ gmonth<C, B>::
+ gmonth (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c)
+ {
+ parse (text_content<C> (e));
+ }
+
+ template <typename C, typename B>
+ gmonth<C, B>::
+ gmonth (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c)
+ {
+ parse (xml::transcode<C> (a.getValue ()));
+ }
+
+ template <typename C, typename B>
+ gmonth<C, B>::
+ gmonth (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c)
+ {
+ parse (s);
+ }
+
+ template <typename C, typename B>
+ void gmonth<C, B>::
+ parse (const std::basic_string<C>& str)
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str);
+ size_type n (trim (tmp));
+ const C* s (tmp.data ());
+
+ // gmonth := --MM[Z|(+|-)HH:MM]
+ //
+ if (n >= 4)
+ {
+ month_ = 10 * (s[2] - C ('0')) + (s[3] - C ('0'));
+
+ if (n > 4)
+ zone_parse (s + 4, n - 4);
+ }
+ }
+
+ // gyear
+ //
+ template <typename C, typename B>
+ gyear<C, B>::
+ gyear (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c)
+ {
+ parse (text_content<C> (e));
+ }
+
+ template <typename C, typename B>
+ gyear<C, B>::
+ gyear (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c)
+ {
+ parse (xml::transcode<C> (a.getValue ()));
+ }
+
+ template <typename C, typename B>
+ gyear<C, B>::
+ gyear (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c)
+ {
+ parse (s);
+ }
+
+ template <typename C, typename B>
+ void gyear<C, B>::
+ parse (const std::basic_string<C>& str)
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str);
+ size_type n (trim (tmp));
+ const C* s (tmp.data ());
+
+ // gyear := [-]CCYY[N]*[Z|(+|-)HH:MM]
+ //
+ if (n >= 4)
+ {
+ // Find the end of the year token.
+ //
+ size_type pos (4);
+ for (; pos < n; ++pos)
+ {
+ C c (s[pos]);
+
+ if (c == C ('Z') || c == C ('+') || c == C ('-'))
+ break;
+ }
+
+ ro_string<C> year_fragment (s, pos);
+ zc_istream<C> is (year_fragment);
+ is >> year_;
+
+ if (pos < n)
+ zone_parse (s + pos, n - pos);
+ }
+ }
+
+ // gmonth_day
+ //
+ template <typename C, typename B>
+ gmonth_day<C, B>::
+ gmonth_day (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c)
+ {
+ parse (text_content<C> (e));
+ }
+
+ template <typename C, typename B>
+ gmonth_day<C, B>::
+ gmonth_day (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c)
+ {
+ parse (xml::transcode<C> (a.getValue ()));
+ }
+
+ template <typename C, typename B>
+ gmonth_day<C, B>::
+ gmonth_day (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c)
+ {
+ parse (s);
+ }
+
+ template <typename C, typename B>
+ void gmonth_day<C, B>::
+ parse (const std::basic_string<C>& str)
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str);
+ size_type n (trim (tmp));
+ const C* s (tmp.data ());
+
+ // gmonth_day := --MM-DD[Z|(+|-)HH:MM]
+ //
+ if (n >= 7)
+ {
+ month_ = 10 * (s[2] - C ('0')) + (s[3] - C ('0'));
+ day_ = 10 * (s[5] - C ('0')) + (s[6] - C ('0'));
+
+ if (n > 7)
+ zone_parse (s + 7, n - 7);
+ }
+ }
+
+ // gyear_month
+ //
+ template <typename C, typename B>
+ gyear_month<C, B>::
+ gyear_month (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c)
+ {
+ parse (text_content<C> (e));
+ }
+
+ template <typename C, typename B>
+ gyear_month<C, B>::
+ gyear_month (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c)
+ {
+ parse (xml::transcode<C> (a.getValue ()));
+ }
+
+ template <typename C, typename B>
+ gyear_month<C, B>::
+ gyear_month (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c)
+ {
+ parse (s);
+ }
+
+ template <typename C, typename B>
+ void gyear_month<C, B>::
+ parse (const std::basic_string<C>& str)
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str);
+ size_type n (trim (tmp));
+ const C* s (tmp.data ());
+
+ // gyear_month := [-]CCYY[N]*-MM[Z|(+|-)HH:MM]
+ //
+
+ if (n >= 7)
+ {
+ // Find the end of the year token.
+ //
+ size_type pos (tmp.find (C ('-'), 4));
+
+ if (pos != ro_string<C>::npos && (n - pos - 1) >= 2)
+ {
+ ro_string<C> year_fragment (s, pos);
+ zc_istream<C> is (year_fragment);
+ is >> year_;
+
+ month_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0'));
+
+ pos += 3;
+
+ if (pos < n)
+ zone_parse (s + pos, n - pos);
+ }
+ }
+ }
+
+ // date
+ //
+ template <typename C, typename B>
+ date<C, B>::
+ date (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c)
+ {
+ parse (text_content<C> (e));
+ }
+
+ template <typename C, typename B>
+ date<C, B>::
+ date (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c)
+ {
+ parse (xml::transcode<C> (a.getValue ()));
+ }
+
+ template <typename C, typename B>
+ date<C, B>::
+ date (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c)
+ {
+ parse (s);
+ }
+
+ template <typename C, typename B>
+ void date<C, B>::
+ parse (const std::basic_string<C>& str)
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str);
+ size_type n (trim (tmp));
+ const C* s (tmp.data ());
+
+ // date := [-]CCYY[N]*-MM-DD[Z|(+|-)HH:MM]
+ //
+
+ if (n >= 10)
+ {
+ // Find the end of the year token.
+ //
+ size_type pos (tmp.find (C ('-'), 4));
+
+ if (pos != ro_string<C>::npos && (n - pos - 1) >= 5)
+ {
+ ro_string<C> year_fragment (s, pos);
+ zc_istream<C> is (year_fragment);
+ is >> year_;
+
+ month_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0'));
+ day_ = 10 * (s[pos + 4] - C ('0')) + (s[pos + 5] - C ('0'));
+
+ pos += 6;
+
+ if (pos < n)
+ zone_parse (s + pos, n - pos);
+ }
+ }
+ }
+
+ // time
+ //
+ template <typename C, typename B>
+ time<C, B>::
+ time (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c)
+ {
+ parse (text_content<C> (e));
+ }
+
+ template <typename C, typename B>
+ time<C, B>::
+ time (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c)
+ {
+ parse (xml::transcode<C> (a.getValue ()));
+ }
+
+ template <typename C, typename B>
+ time<C, B>::
+ time (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c)
+ {
+ parse (s);
+ }
+
+ template <typename C, typename B>
+ void time<C, B>::
+ parse (const std::basic_string<C>& str)
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str);
+ size_type n (trim (tmp));
+ const C* s (tmp.data ());
+
+ // time := HH:MM:SS[.S+][Z|(+|-)HH:MM]
+ //
+
+ if (n >= 8)
+ {
+ hours_ = 10 * (s[0] - '0') + (s[1] - '0');
+ minutes_ = 10 * (s[3] - '0') + (s[4] - '0');
+
+ // Find the end of the seconds fragment.
+ //
+ size_type pos (8);
+ for (; pos < n; ++pos)
+ {
+ C c (s[pos]);
+
+ if (c == C ('Z') || c == C ('+') || c == C ('-'))
+ break;
+ }
+
+ ro_string<C> seconds_fragment (s + 6, pos - 6);
+ zc_istream<C> is (seconds_fragment);
+ is >> seconds_;
+
+ if (pos < n)
+ zone_parse (s + pos, n - pos);
+ }
+ }
+
+ // date_time
+ //
+ template <typename C, typename B>
+ date_time<C, B>::
+ date_time (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c)
+ {
+ parse (text_content<C> (e));
+ }
+
+ template <typename C, typename B>
+ date_time<C, B>::
+ date_time (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c)
+ {
+ parse (xml::transcode<C> (a.getValue ()));
+ }
+
+ template <typename C, typename B>
+ date_time<C, B>::
+ date_time (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c)
+ {
+ parse (s);
+ }
+
+ template <typename C, typename B>
+ void date_time<C, B>::
+ parse (const std::basic_string<C>& str)
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str);
+ size_type n (trim (tmp));
+ const C* s (tmp.data ());
+
+ // date_time := [-]CCYY[N]*-MM-DDTHH:MM:SS[.S+][Z|(+|-)HH:MM]
+ //
+
+ if (n >= 19)
+ {
+ // Find the end of the year token.
+ //
+ size_type pos (tmp.find (C ('-'), 4));
+
+ if (pos != ro_string<C>::npos && (n - pos - 1) >= 14)
+ {
+ ro_string<C> year_fragment (s, pos);
+ zc_istream<C> yis (year_fragment);
+ yis >> year_;
+
+ month_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0'));
+ pos += 3;
+
+ day_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0'));
+ pos += 3;
+
+ hours_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0'));
+ pos += 3;
+
+ minutes_ = 10 * (s[pos + 1] - C ('0')) + (s[pos + 2] - C ('0'));
+ pos += 4; // Point to the first S.
+
+ // Find the end of the seconds fragment.
+ //
+ size_type sec_end (pos + 2);
+ for (; sec_end < n; ++sec_end)
+ {
+ C c (s[sec_end]);
+
+ if (c == C ('Z') || c == C ('+') || c == C ('-'))
+ break;
+ }
+
+ ro_string<C> seconds_fragment (s + pos, sec_end - pos);
+ zc_istream<C> sis (seconds_fragment);
+ sis >> seconds_;
+
+ if (sec_end < n)
+ zone_parse (s + sec_end, n - sec_end);
+ }
+ }
+ }
+
+ // duration
+ //
+ template <typename C, typename B>
+ duration<C, B>::
+ duration (const xercesc::DOMElement& e, flags f, container* c)
+ : B (e, f, c)
+ {
+ parse (text_content<C> (e));
+ }
+
+ template <typename C, typename B>
+ duration<C, B>::
+ duration (const xercesc::DOMAttr& a, flags f, container* c)
+ : B (a, f, c)
+ {
+ parse (xml::transcode<C> (a.getValue ()));
+ }
+
+ template <typename C, typename B>
+ duration<C, B>::
+ duration (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f,
+ container* c)
+ : B (s, e, f, c)
+ {
+ parse (s);
+ }
+
+ namespace bits
+ {
+ template <typename C>
+ inline typename ro_string<C>::size_type
+ duration_delim (const C* s,
+ typename ro_string<C>::size_type pos,
+ typename ro_string<C>::size_type size)
+ {
+ const C* p (s + pos);
+ for (; p < (s + size); ++p)
+ {
+ if (*p == C ('Y') || *p == C ('D') || *p == C ('M') ||
+ *p == C ('H') || *p == C ('M') || *p == C ('S') ||
+ *p == C ('T'))
+ break;
+ }
+
+ return p - s;
+ }
+ }
+
+ template <typename C, typename B>
+ void duration<C, B>::
+ parse (const std::basic_string<C>& str)
+ {
+ typedef typename ro_string<C>::size_type size_type;
+
+ ro_string<C> tmp (str);
+ size_type n (trim (tmp));
+ const C* s (tmp.data ());
+
+ // Set all the fields since some of them may not be specified.
+ //
+ years_ = months_ = days_ = hours_ = minutes_ = 0;
+ seconds_ = 0.0;
+
+ // duration := [-]P[nY][nM][nD][TnHnMn[.n+]S]
+ //
+ if (n >= 3)
+ {
+ size_type pos (0);
+
+ if (s[0] == C ('-'))
+ {
+ negative_ = true;
+ pos++;
+ }
+ else
+ negative_ = false;
+
+ pos++; // Skip 'P'.
+
+ size_type del (bits::duration_delim (s, pos, n));
+
+ if (del != n && s[del] == C ('Y'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+ is >> years_;
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, n);
+ }
+
+ if (del != n && s[del] == C ('M'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+ is >> months_;
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, n);
+ }
+
+ if (del != n && s[del] == C ('D'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+ is >> days_;
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, n);
+ }
+
+ if (del != n && s[del] == C ('T'))
+ {
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, n);
+
+ if (del != n && s[del] == C ('H'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+ is >> hours_;
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, n);
+ }
+
+ if (del != n && s[del] == C ('M'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+ is >> minutes_;
+
+ pos = del + 1;
+ del = bits::duration_delim (s, pos, n);
+ }
+
+ if (del != n && s[del] == C ('S'))
+ {
+ ro_string<C> fragment (s + pos, del - pos);
+ zc_istream<C> is (fragment);
+ is >> seconds_;
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/parsing/decimal.hxx b/libxsd/xsd/cxx/tree/parsing/decimal.hxx
new file mode 100644
index 0000000..d24e7c6
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/decimal.hxx
@@ -0,0 +1,85 @@
+// file : xsd/cxx/tree/parsing/decimal.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_DECIMAL_HXX
+#define XSD_CXX_TREE_PARSING_DECIMAL_HXX
+
+#include <limits>
+#include <locale>
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include <xsd/cxx/tree/text.hxx> // text_content
+#include <xsd/cxx/tree/bits/literals.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct traits<double, C, schema_type::decimal>
+ {
+ typedef double type;
+
+ static type
+ create (const xercesc::DOMElement& e, flags f, container* c);
+
+ static type
+ create (const xercesc::DOMAttr& a, flags f, container* c);
+
+ static type
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*);
+ };
+
+ template <typename C>
+ double traits<double, C, schema_type::decimal>::
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return create (text_content<C> (e), 0, f, c);
+ }
+
+ template <typename C>
+ double traits<double, C, schema_type::decimal>::
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return create (xml::transcode<C> (a.getValue ()), 0, f, c);
+ }
+
+ template <typename C>
+ double traits<double, C, schema_type::decimal>::
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*)
+ {
+ // 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<C> tmp (s);
+ trim (tmp);
+
+ zc_istream<C> is (tmp);
+ is.imbue (std::locale::classic ());
+
+ type t;
+ is >> t;
+
+ return t;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_PARSING_DECIMAL_HXX
diff --git a/libxsd/xsd/cxx/tree/parsing/double.hxx b/libxsd/xsd/cxx/tree/parsing/double.hxx
new file mode 100644
index 0000000..aa83ad5
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/double.hxx
@@ -0,0 +1,94 @@
+// file : xsd/cxx/tree/parsing/double.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_DOUBLE_HXX
+#define XSD_CXX_TREE_PARSING_DOUBLE_HXX
+
+#include <limits>
+#include <locale>
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include <xsd/cxx/tree/text.hxx> // text_content
+#include <xsd/cxx/tree/bits/literals.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct traits<double, C, schema_type::double_>
+ {
+ typedef double type;
+
+ static type
+ create (const xercesc::DOMElement& e, flags f, container* c);
+
+ static type
+ create (const xercesc::DOMAttr& a, flags f, container* c);
+
+ static type
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*);
+ };
+
+ template <typename C>
+ double traits<double, C, schema_type::double_>::
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return create (text_content<C> (e), 0, f, c);
+ }
+
+ template <typename C>
+ double traits<double, C, schema_type::double_>::
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return create (xml::transcode<C> (a.getValue ()), 0, f, c);
+ }
+
+ template <typename C>
+ double traits<double, C, schema_type::double_>::
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*)
+ {
+ // 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<C> tmp (s);
+ trim (tmp);
+
+ if (tmp == bits::positive_inf<C> ())
+ return std::numeric_limits<double>::infinity ();
+
+ if (tmp == bits::negative_inf<C> ())
+ return -std::numeric_limits<double>::infinity ();
+
+ if (tmp == bits::nan<C> ())
+ return std::numeric_limits<double>::quiet_NaN ();
+
+ zc_istream<C> is (tmp);
+ is.imbue (std::locale::classic ());
+
+ type t;
+ is >> t;
+
+ return t;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_PARSING_DOUBLE_HXX
diff --git a/libxsd/xsd/cxx/tree/parsing/element-map.txx b/libxsd/xsd/cxx/tree/parsing/element-map.txx
new file mode 100644
index 0000000..88ac26b
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/element-map.txx
@@ -0,0 +1,42 @@
+// file : xsd/cxx/tree/parsing/element-map.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_ELEMENT_MAP_TXX
+#define XSD_CXX_TREE_PARSING_ELEMENT_MAP_TXX
+
+#include <xsd/cxx/xml/dom/elements.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C, typename T>
+ std::auto_ptr<element_type<C, T> > element_map<C, T>::
+ parse (const xercesc::DOMElement& e, flags f)
+ {
+ const qualified_name n (xml::dom::name<C> (e));
+ typename map::const_iterator i (map_->find (n));
+
+ if (i != map_->end () && i->second.parser_ != 0)
+ return (i->second.parser_) (e, f);
+ else
+ throw no_element_info<C> (n.name (), n.namespace_ ());
+ }
+
+ template<typename T, typename C, typename B>
+ std::auto_ptr<element_type<C, B> >
+ parser_impl (const xercesc::DOMElement& e, flags f)
+ {
+ return std::auto_ptr<element_type<C, B> > (new T (e, f));
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_PARSING_ELEMENT_MAP_TXX
diff --git a/libxsd/xsd/cxx/tree/parsing/float.hxx b/libxsd/xsd/cxx/tree/parsing/float.hxx
new file mode 100644
index 0000000..294484c
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/float.hxx
@@ -0,0 +1,94 @@
+// file : xsd/cxx/tree/parsing/float.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_FLOAT_HXX
+#define XSD_CXX_TREE_PARSING_FLOAT_HXX
+
+#include <limits>
+#include <locale>
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include <xsd/cxx/tree/text.hxx> // text_content
+#include <xsd/cxx/tree/bits/literals.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct traits<float, C, schema_type::other>
+ {
+ typedef float type;
+
+ static type
+ create (const xercesc::DOMElement& e, flags f, container* c);
+
+ static type
+ create (const xercesc::DOMAttr& a, flags f, container* c);
+
+ static type
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*);
+ };
+
+ template <typename C>
+ float traits<float, C, schema_type::other>::
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return create (text_content<C> (e), 0, f, c);
+ }
+
+ template <typename C>
+ float traits<float, C, schema_type::other>::
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return create (xml::transcode<C> (a.getValue ()), 0, f, c);
+ }
+
+ template <typename C>
+ float traits<float, C, schema_type::other>::
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*)
+ {
+ // 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<C> tmp (s);
+ trim (tmp);
+
+ if (tmp == bits::positive_inf<C> ())
+ return std::numeric_limits<float>::infinity ();
+
+ if (tmp == bits::negative_inf<C> ())
+ return -std::numeric_limits<float>::infinity ();
+
+ if (tmp == bits::nan<C> ())
+ return std::numeric_limits<float>::quiet_NaN ();
+
+ zc_istream<C> is (tmp);
+ is.imbue (std::locale::classic ());
+
+ type t;
+ is >> t;
+
+ return t;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_PARSING_FLOAT_HXX
diff --git a/libxsd/xsd/cxx/tree/parsing/int.hxx b/libxsd/xsd/cxx/tree/parsing/int.hxx
new file mode 100644
index 0000000..85b7f3a
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/int.hxx
@@ -0,0 +1,80 @@
+// file : xsd/cxx/tree/parsing/int.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_INT_HXX
+#define XSD_CXX_TREE_PARSING_INT_HXX
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include <xsd/cxx/tree/text.hxx> // text_content
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct traits<int, C, schema_type::other>
+ {
+ typedef int type;
+
+ static type
+ create (const xercesc::DOMElement& e, flags f, container* c);
+
+ static type
+ create (const xercesc::DOMAttr& a, flags f, container* c);
+
+ static type
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*);
+ };
+
+ template <typename C>
+ int traits<int, C, schema_type::other>::
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return create (text_content<C> (e), 0, f, c);
+ }
+
+ template <typename C>
+ int traits<int, C, schema_type::other>::
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return create (xml::transcode<C> (a.getValue ()), 0, f, c);
+ }
+
+ template <typename C>
+ int traits<int, C, schema_type::other>::
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*)
+ {
+ // 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<C> tmp (s);
+ trim (tmp);
+
+ zc_istream<C> is (tmp);
+
+ type t;
+ is >> t;
+
+ return t;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_PARSING_INT_HXX
diff --git a/libxsd/xsd/cxx/tree/parsing/long.hxx b/libxsd/xsd/cxx/tree/parsing/long.hxx
new file mode 100644
index 0000000..e4ba3ac
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/long.hxx
@@ -0,0 +1,80 @@
+// file : xsd/cxx/tree/parsing/long.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_LONG_HXX
+#define XSD_CXX_TREE_PARSING_LONG_HXX
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include <xsd/cxx/tree/text.hxx> // text_content
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct traits<long long, C, schema_type::other>
+ {
+ typedef long long type;
+
+ static type
+ create (const xercesc::DOMElement& e, flags f, container* c);
+
+ static type
+ create (const xercesc::DOMAttr& a, flags f, container* c);
+
+ static type
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*);
+ };
+
+ template <typename C>
+ long long traits<long long, C, schema_type::other>::
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return create (text_content<C> (e), 0, f, c);
+ }
+
+ template <typename C>
+ long long traits<long long, C, schema_type::other>::
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return create (xml::transcode<C> (a.getValue ()), 0, f, c);
+ }
+
+ template <typename C>
+ long long traits<long long, C, schema_type::other>::
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*)
+ {
+ // 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<C> tmp (s);
+ trim (tmp);
+
+ zc_istream<C> is (tmp);
+
+ type t;
+ is >> t;
+
+ return t;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_PARSING_LONG_HXX
diff --git a/libxsd/xsd/cxx/tree/parsing/short.hxx b/libxsd/xsd/cxx/tree/parsing/short.hxx
new file mode 100644
index 0000000..dd023cf
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/short.hxx
@@ -0,0 +1,80 @@
+// file : xsd/cxx/tree/parsing/short.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_SHORT_HXX
+#define XSD_CXX_TREE_PARSING_SHORT_HXX
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include <xsd/cxx/tree/text.hxx> // text_content
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct traits<short, C, schema_type::other>
+ {
+ typedef short type;
+
+ static type
+ create (const xercesc::DOMElement& e, flags f, container* c);
+
+ static type
+ create (const xercesc::DOMAttr& a, flags f, container* c);
+
+ static type
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*);
+ };
+
+ template <typename C>
+ short traits<short, C, schema_type::other>::
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return create (text_content<C> (e), 0, f, c);
+ }
+
+ template <typename C>
+ short traits<short, C, schema_type::other>::
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return create (xml::transcode<C> (a.getValue ()), 0, f, c);
+ }
+
+ template <typename C>
+ short traits<short, C, schema_type::other>::
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*)
+ {
+ // 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<C> tmp (s);
+ trim (tmp);
+
+ zc_istream<C> is (tmp);
+
+ type t;
+ is >> t;
+
+ return t;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_PARSING_SHORT_HXX
diff --git a/libxsd/xsd/cxx/tree/parsing/unsigned-byte.hxx b/libxsd/xsd/cxx/tree/parsing/unsigned-byte.hxx
new file mode 100644
index 0000000..b14b815
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/unsigned-byte.hxx
@@ -0,0 +1,80 @@
+// file : xsd/cxx/tree/parsing/unsigned-byte.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_UNSIGNED_BYTE_HXX
+#define XSD_CXX_TREE_PARSING_UNSIGNED_BYTE_HXX
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include <xsd/cxx/tree/text.hxx> // text_content
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct traits<unsigned char, C, schema_type::other>
+ {
+ typedef unsigned char type;
+
+ static type
+ create (const xercesc::DOMElement& e, flags f, container* c);
+
+ static type
+ create (const xercesc::DOMAttr& a, flags f, container* c);
+
+ static type
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*);
+ };
+
+ template <typename C>
+ unsigned char traits<unsigned char, C, schema_type::other>::
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return create (text_content<C> (e), 0, f, c);
+ }
+
+ template <typename C>
+ unsigned char traits<unsigned char, C, schema_type::other>::
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return create (xml::transcode<C> (a.getValue ()), 0, f, c);
+ }
+
+ template <typename C>
+ unsigned char traits<unsigned char, C, schema_type::other>::
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*)
+ {
+ // 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<C> tmp (s);
+ trim (tmp);
+
+ zc_istream<C> is (tmp);
+
+ unsigned short t;
+ is >> t;
+
+ return static_cast<type> (t);
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_PARSING_UNSIGNED_BYTE_HXX
diff --git a/libxsd/xsd/cxx/tree/parsing/unsigned-int.hxx b/libxsd/xsd/cxx/tree/parsing/unsigned-int.hxx
new file mode 100644
index 0000000..d32631a
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/unsigned-int.hxx
@@ -0,0 +1,80 @@
+// file : xsd/cxx/tree/parsing/unsigned-int.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_UNSIGNED_INT_HXX
+#define XSD_CXX_TREE_PARSING_UNSIGNED_INT_HXX
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include <xsd/cxx/tree/text.hxx> // text_content
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct traits<unsigned int, C, schema_type::other>
+ {
+ typedef unsigned int type;
+
+ static type
+ create (const xercesc::DOMElement& e, flags f, container* c);
+
+ static type
+ create (const xercesc::DOMAttr& a, flags f, container* c);
+
+ static type
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*);
+ };
+
+ template <typename C>
+ unsigned int traits<unsigned int, C, schema_type::other>::
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return create (text_content<C> (e), 0, f, c);
+ }
+
+ template <typename C>
+ unsigned int traits<unsigned int, C, schema_type::other>::
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return create (xml::transcode<C> (a.getValue ()), 0, f, c);
+ }
+
+ template <typename C>
+ unsigned int traits<unsigned int, C, schema_type::other>::
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*)
+ {
+ // 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<C> tmp (s);
+ trim (tmp);
+
+ zc_istream<C> is (tmp);
+
+ type t;
+ is >> t;
+
+ return t;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_PARSING_UNSIGNED_INT_HXX
diff --git a/libxsd/xsd/cxx/tree/parsing/unsigned-long.hxx b/libxsd/xsd/cxx/tree/parsing/unsigned-long.hxx
new file mode 100644
index 0000000..bee2eb7
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/unsigned-long.hxx
@@ -0,0 +1,80 @@
+// file : xsd/cxx/tree/parsing/unsigned-long.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_UNSIGNED_LONG_HXX
+#define XSD_CXX_TREE_PARSING_UNSIGNED_LONG_HXX
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include <xsd/cxx/tree/text.hxx> // text_content
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct traits<unsigned long long, C, schema_type::other>
+ {
+ typedef unsigned long long type;
+
+ static type
+ create (const xercesc::DOMElement& e, flags f, container* c);
+
+ static type
+ create (const xercesc::DOMAttr& a, flags f, container* c);
+
+ static type
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*);
+ };
+
+ template <typename C>
+ unsigned long long traits<unsigned long long, C, schema_type::other>::
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return create (text_content<C> (e), 0, f, c);
+ }
+
+ template <typename C>
+ unsigned long long traits<unsigned long long, C, schema_type::other>::
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return create (xml::transcode<C> (a.getValue ()), 0, f, c);
+ }
+
+ template <typename C>
+ unsigned long long traits<unsigned long long, C, schema_type::other>::
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*)
+ {
+ // 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<C> tmp (s);
+ trim (tmp);
+
+ zc_istream<C> is (tmp);
+
+ type t;
+ is >> t;
+
+ return t;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_PARSING_UNSIGNED_LONG_HXX
diff --git a/libxsd/xsd/cxx/tree/parsing/unsigned-short.hxx b/libxsd/xsd/cxx/tree/parsing/unsigned-short.hxx
new file mode 100644
index 0000000..7896f9e
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/parsing/unsigned-short.hxx
@@ -0,0 +1,80 @@
+// file : xsd/cxx/tree/parsing/unsigned-short.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_PARSING_UNSIGNED_SHORT_HXX
+#define XSD_CXX_TREE_PARSING_UNSIGNED_SHORT_HXX
+
+#include <xsd/cxx/ro-string.hxx>
+#include <xsd/cxx/zc-istream.hxx>
+
+#include <xsd/cxx/xml/string.hxx> // xml::transcode
+
+#include <xsd/cxx/tree/text.hxx> // text_content
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct traits<unsigned short, C, schema_type::other>
+ {
+ typedef unsigned short type;
+
+ static type
+ create (const xercesc::DOMElement& e, flags f, container* c);
+
+ static type
+ create (const xercesc::DOMAttr& a, flags f, container* c);
+
+ static type
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*);
+ };
+
+ template <typename C>
+ unsigned short traits<unsigned short, C, schema_type::other>::
+ create (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return create (text_content<C> (e), 0, f, c);
+ }
+
+ template <typename C>
+ unsigned short traits<unsigned short, C, schema_type::other>::
+ create (const xercesc::DOMAttr& a, flags f, container* c)
+ {
+ return create (xml::transcode<C> (a.getValue ()), 0, f, c);
+ }
+
+ template <typename C>
+ unsigned short traits<unsigned short, C, schema_type::other>::
+ create (const std::basic_string<C>& s,
+ const xercesc::DOMElement*,
+ flags,
+ container*)
+ {
+ // 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<C> tmp (s);
+ trim (tmp);
+
+ zc_istream<C> is (tmp);
+
+ type t;
+ is >> t;
+
+ return t;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_PARSING_UNSIGNED_SHORT_HXX
diff --git a/libxsd/xsd/cxx/tree/serialization.hxx b/libxsd/xsd/cxx/tree/serialization.hxx
new file mode 100644
index 0000000..42d557a
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization.hxx
@@ -0,0 +1,66 @@
+// file : xsd/cxx/tree/serialization.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_HXX
+#define XSD_CXX_TREE_SERIALIZATION_HXX
+
+#include <sstream>
+
+#include <xercesc/dom/DOMElement.hpp>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ //
+ //
+ template <typename C>
+ class list_stream
+ {
+ public:
+ list_stream (std::basic_ostringstream<C>& os,
+ xercesc::DOMElement& parent)
+ : os_ (os), parent_ (parent)
+ {
+ }
+
+ std::basic_ostringstream<C>& os_;
+ xercesc::DOMElement& parent_;
+ };
+
+ template <typename T>
+ class as_double
+ {
+ public:
+ as_double (const T& v)
+ : x (v)
+ {
+ }
+
+ const T& x;
+ };
+
+ template <typename T>
+ class as_decimal
+ {
+ public:
+ as_decimal (const T& v, const facet* f = 0)
+ : x (v), facets (f)
+ {
+ }
+
+ const T& x;
+ const facet* facets;
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/tree/serialization.txx>
+#include <xsd/cxx/tree/serialization/date-time.txx>
+
+#endif // XSD_CXX_TREE_SERIALIZATION_HXX
diff --git a/libxsd/xsd/cxx/tree/serialization.txx b/libxsd/xsd/cxx/tree/serialization.txx
new file mode 100644
index 0000000..b8c8631
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization.txx
@@ -0,0 +1,762 @@
+// file : xsd/cxx/tree/serialization.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <string>
+#include <sstream>
+
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMElement.hpp>
+
+#include <xsd/cxx/xml/string.hxx> // xml::{string, transcode}
+#include <xsd/cxx/xml/dom/serialization-header.hxx> // dom::{prefix, clear}
+
+#include <xsd/cxx/tree/elements.hxx>
+#include <xsd/cxx/tree/types.hxx>
+#include <xsd/cxx/tree/list.hxx>
+
+// The only way to make the following serialization operators
+// for fundamental types work is to defined them in the xercesc
+// namespace so that they can be found by ADL. Placing them into
+// the global namespace does not work.
+//
+
+namespace XERCES_CPP_NAMESPACE
+{
+ // Serialization of std::basic_string and C string. Used in other
+ // serializers. Also used to serialize enumerators.
+ //
+ template <typename C>
+ void
+ operator<< (xercesc::DOMElement& e, const C* s)
+ {
+ xsd::cxx::xml::dom::clear<char> (e);
+ e.setTextContent (xsd::cxx::xml::string (s).c_str ());
+ }
+
+ template <typename C>
+ void
+ operator<< (xercesc::DOMAttr& a, const C* s)
+ {
+ a.setValue (xsd::cxx::xml::string (s).c_str ());
+ }
+
+ // We duplicate the code above instead of delegating in order to
+ // allow the xml::string type to take advantage of cached string
+ // sizes.
+ //
+ template <typename C>
+ void
+ operator<< (xercesc::DOMElement& e, const std::basic_string<C>& s)
+ {
+ xsd::cxx::xml::dom::clear<char> (e);
+ e.setTextContent (xsd::cxx::xml::string (s).c_str ());
+ }
+
+ template <typename C>
+ void
+ operator<< (xercesc::DOMAttr& a, const std::basic_string<C>& s)
+ {
+ a.setValue (xsd::cxx::xml::string (s).c_str ());
+ }
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // List serialization operators for std::basic_string and C string.
+ //
+
+ template <typename C>
+ void
+ operator<< (list_stream<C>& ls, const C* s)
+ {
+ ls.os_ << s;
+ }
+
+ template <typename C>
+ void
+ operator<< (list_stream<C>& ls, const std::basic_string<C>& s)
+ {
+ ls.os_ << s;
+ }
+
+ // Insertion operators for type.
+ //
+ inline void
+ operator<< (xercesc::DOMElement& e, const type&)
+ {
+ xml::dom::clear<char> (e);
+ }
+
+ inline void
+ operator<< (xercesc::DOMAttr&, const type&)
+ {
+ }
+
+ template <typename C>
+ inline void
+ operator<< (list_stream<C>&, const type&)
+ {
+ }
+
+ // Insertion operators for simple_type.
+ //
+ template <typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const simple_type<B>&)
+ {
+ xml::dom::clear<char> (e);
+ }
+
+ template <typename B>
+ inline void
+ operator<< (xercesc::DOMAttr&, const simple_type<B>&)
+ {
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>&, const simple_type<B>&)
+ {
+ }
+
+ // Insertion operators for list.
+ //
+ template <typename C, typename T, schema_type::value ST, bool fund>
+ void
+ operator<< (xercesc::DOMElement& e, const list<T, C, ST, fund>& v)
+ {
+ xml::dom::clear<char> (e);
+
+ std::basic_ostringstream<C> os;
+ list_stream<C> ls (os, e);
+
+ ls << v;
+
+ e << os.str ();
+ }
+
+ template <typename C, typename T, schema_type::value ST, bool fund>
+ void
+ operator<< (xercesc::DOMAttr& a, const list<T, C, ST, fund>& v)
+ {
+ std::basic_ostringstream<C> os;
+ list_stream<C> ls (os, *a.getOwnerElement ());
+
+ ls << v;
+
+ a << os.str ();
+ }
+
+ template <typename C, typename T, schema_type::value ST, bool fund>
+ void
+ operator<< (list_stream<C>& ls, const list<T, C, ST, fund>& v)
+ {
+ for (typename list<T, C, ST, fund>::const_iterator
+ b (v.begin ()), e (v.end ()), i (b); i != e; ++i)
+ {
+ if (i != b)
+ ls.os_ << C (' ');
+
+ ls << *i;
+ }
+ }
+
+ // Specializations for double and decimal.
+ //
+ template <typename C, typename T, bool fund>
+ void
+ operator<< (list_stream<C>& ls,
+ const list<T, C, schema_type::double_, fund>& v)
+ {
+ for (typename list<T, C, schema_type::double_, fund>::const_iterator
+ b (v.begin ()), e (v.end ()), i (b); i != e; ++i)
+ {
+ if (i != b)
+ ls.os_ << C (' ');
+
+ ls << as_double<T> (*i);
+ }
+ }
+
+ template <typename C, typename T, bool fund>
+ void
+ operator<< (list_stream<C>& ls,
+ const list<T, C, schema_type::decimal, fund>& v)
+ {
+ for (typename list<T, C, schema_type::decimal, fund>::const_iterator
+ b (v.begin ()), e (v.end ()), i (b); i != e; ++i)
+ {
+ if (i != b)
+ ls.os_ << C (' ');
+
+ ls << as_decimal<T> (*i);
+ }
+ }
+
+
+ // Insertion operators for fundamental_base.
+ //
+ template <typename T, typename C, typename B, schema_type::value ST>
+ void
+ operator<< (xercesc::DOMElement& e,
+ const fundamental_base<T, C, B, ST>& x)
+ {
+ const T& r (x);
+ e << r;
+ }
+
+ template <typename T, typename C, typename B, schema_type::value ST>
+ void
+ operator<< (xercesc::DOMAttr& a, const fundamental_base<T, C, B, ST>& x)
+ {
+ const T& r (x);
+ a << r;
+ }
+
+ template <typename T, typename C, typename B, schema_type::value ST>
+ void
+ operator<< (list_stream<C>& ls, const fundamental_base<T, C, B, ST>& x)
+ {
+ const T& r (x);
+ ls << r;
+ }
+
+ // Specializations for double.
+ //
+ template <typename T, typename C, typename B>
+ void
+ operator<< (
+ xercesc::DOMElement& e,
+ const fundamental_base<T, C, B, schema_type::double_>& x)
+ {
+ e << as_double<T> (x);
+ }
+
+ template <typename T, typename C, typename B>
+ void
+ operator<< (
+ xercesc::DOMAttr& a,
+ const fundamental_base<T, C, B, schema_type::double_>& x)
+ {
+ a << as_double<T> (x);
+ }
+
+ template <typename T, typename C, typename B>
+ void
+ operator<< (
+ list_stream<C>& ls,
+ const fundamental_base<T, C, B, schema_type::double_>& x)
+ {
+ ls << as_double<T> (x);
+ }
+
+ // Specializations for decimal.
+ //
+ template <typename T, typename C, typename B>
+ void
+ operator<< (
+ xercesc::DOMElement& e,
+ const fundamental_base<T, C, B, schema_type::decimal>& x)
+ {
+ e << as_decimal<T> (x, x._facet_table ());
+ }
+
+ template <typename T, typename C, typename B>
+ void
+ operator<< (
+ xercesc::DOMAttr& a,
+ const fundamental_base<T, C, B, schema_type::decimal>& x)
+ {
+ a << as_decimal<T> (x, x._facet_table ());
+ }
+
+ template <typename T, typename C, typename B>
+ void
+ operator<< (
+ list_stream<C>& ls,
+ const fundamental_base<T, C, B, schema_type::decimal>& x)
+ {
+ ls << as_decimal<T> (x, x._facet_table ());
+ }
+
+ // Insertion operators for built-in types.
+ //
+
+ namespace bits
+ {
+ template <typename C, typename T>
+ void
+ insert (xercesc::DOMElement& e, const T& x)
+ {
+ std::basic_ostringstream<C> os;
+ os << x;
+ e << os.str ();
+ }
+
+ template <typename C, typename T>
+ void
+ insert (xercesc::DOMAttr& a, const T& x)
+ {
+ std::basic_ostringstream<C> os;
+ os << x;
+ a << os.str ();
+ }
+ }
+
+
+ // string
+ //
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const string<C, B>& x)
+ {
+ bits::insert<C> (e, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const string<C, B>& x)
+ {
+ bits::insert<C> (a, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const string<C, B>& x)
+ {
+ ls.os_ << x;
+ }
+
+
+ // normalized_string
+ //
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const normalized_string<C, B>& x)
+ {
+ bits::insert<C> (e, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const normalized_string<C, B>& x)
+ {
+ bits::insert<C> (a, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const normalized_string<C, B>& x)
+ {
+ ls.os_ << x;
+ }
+
+
+ // token
+ //
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const token<C, B>& x)
+ {
+ bits::insert<C> (e, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const token<C, B>& x)
+ {
+ bits::insert<C> (a, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const token<C, B>& x)
+ {
+ ls.os_ << x;
+ }
+
+
+ // nmtoken
+ //
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const nmtoken<C, B>& x)
+ {
+ bits::insert<C> (e, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const nmtoken<C, B>& x)
+ {
+ bits::insert<C> (a, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const nmtoken<C, B>& x)
+ {
+ ls.os_ << x;
+ }
+
+
+ // nmtokens
+ //
+ template <typename C, typename B, typename nmtoken>
+ inline void
+ operator<< (xercesc::DOMElement& e, const nmtokens<C, B, nmtoken>& v)
+ {
+ const list<nmtoken, C>& r (v);
+ e << r;
+ }
+
+ template <typename C, typename B, typename nmtoken>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const nmtokens<C, B, nmtoken>& v)
+ {
+ const list<nmtoken, C>& r (v);
+ a << r;
+ }
+
+ template <typename C, typename B, typename nmtoken>
+ inline void
+ operator<< (list_stream<C>& ls, const nmtokens<C, B, nmtoken>& v)
+ {
+ const list<nmtoken, C>& r (v);
+ ls << r;
+ }
+
+
+ // name
+ //
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const name<C, B>& x)
+ {
+ bits::insert<C> (e, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const name<C, B>& x)
+ {
+ bits::insert<C> (a, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const name<C, B>& x)
+ {
+ ls.os_ << x;
+ }
+
+
+ // ncname
+ //
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const ncname<C, B>& x)
+ {
+ bits::insert<C> (e, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const ncname<C, B>& x)
+ {
+ bits::insert<C> (a, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const ncname<C, B>& x)
+ {
+ ls.os_ << x;
+ }
+
+
+ // language
+ //
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const language<C, B>& x)
+ {
+ bits::insert<C> (e, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const language<C, B>& x)
+ {
+ bits::insert<C> (a, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const language<C, B>& x)
+ {
+ ls.os_ << x;
+ }
+
+
+ // id
+ //
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const id<C, B>& x)
+ {
+ bits::insert<C> (e, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const id<C, B>& x)
+ {
+ bits::insert<C> (a, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const id<C, B>& x)
+ {
+ ls.os_ << x;
+ }
+
+
+ // idref
+ //
+ template <typename T, typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const idref<T, C, B>& x)
+ {
+ bits::insert<C> (e, x);
+ }
+
+ template <typename T, typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const idref<T, C, B>& x)
+ {
+ bits::insert<C> (a, x);
+ }
+
+ template <typename T, typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const idref<T, C, B>& x)
+ {
+ ls.os_ << x;
+ }
+
+
+ // idrefs
+ //
+ template <typename C, typename B, typename idref>
+ inline void
+ operator<< (xercesc::DOMElement& e, const idrefs<C, B, idref>& v)
+ {
+ const list<idref, C>& r (v);
+ e << r;
+ }
+
+ template <typename C, typename B, typename idref>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const idrefs<C, B, idref>& v)
+ {
+ const list<idref, C>& r (v);
+ a << r;
+ }
+
+ template <typename C, typename B, typename idref>
+ inline void
+ operator<< (list_stream<C>& ls, const idrefs<C, B, idref>& v)
+ {
+ const list<idref, C>& r (v);
+ ls << r;
+ }
+
+
+ // uri
+ //
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const uri<C, B>& x)
+ {
+ bits::insert<C> (e, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const uri<C, B>& x)
+ {
+ bits::insert<C> (a, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const uri<C, B>& x)
+ {
+ ls.os_ << x;
+ }
+
+
+ // qname
+ //
+ template <typename C, typename B, typename uri, typename ncname>
+ void
+ operator<< (xercesc::DOMElement& e, const qname<C, B, uri, ncname>& x)
+ {
+ std::basic_ostringstream<C> os;
+
+ if (x.qualified ())
+ {
+ std::basic_string<C> p (xml::dom::prefix (x.namespace_ (), e));
+
+ if (!p.empty ())
+ os << p << C (':');
+ }
+
+ os << x.name ();
+ e << os.str ();
+ }
+
+ template <typename C, typename B, typename uri, typename ncname>
+ void
+ operator<< (xercesc::DOMAttr& a, const qname<C, B, uri, ncname>& x)
+ {
+ std::basic_ostringstream<C> os;
+
+ if (x.qualified ())
+ {
+ std::basic_string<C> p (
+ xml::dom::prefix (x.namespace_ (), *a.getOwnerElement ()));
+
+ if (!p.empty ())
+ os << p << C (':');
+ }
+
+ os << x.name ();
+ a << os.str ();
+ }
+
+ template <typename C, typename B, typename uri, typename ncname>
+ void
+ operator<< (list_stream<C>& ls, const qname<C, B, uri, ncname>& x)
+ {
+ if (x.qualified ())
+ {
+ std::basic_string<C> p (
+ xml::dom::prefix (x.namespace_ (), ls.parent_));
+
+ if (!p.empty ())
+ ls.os_ << p << C (':');
+ }
+
+ ls.os_ << x.name ();
+ }
+
+
+ // base64_binary
+ //
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const base64_binary<C, B>& x)
+ {
+ e << x.encode ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const base64_binary<C, B>& x)
+ {
+ a << x.encode ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const base64_binary<C, B>& x)
+ {
+ ls.os_ << x.encode ();
+ }
+
+
+ // hex_binary
+ //
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const hex_binary<C, B>& x)
+ {
+ e << x.encode ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const hex_binary<C, B>& x)
+ {
+ a << x.encode ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const hex_binary<C, B>& x)
+ {
+ ls.os_ << x.encode ();
+ }
+
+
+ // entity
+ //
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const entity<C, B>& x)
+ {
+ bits::insert<C> (e, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const entity<C, B>& x)
+ {
+ bits::insert<C> (a, x);
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const entity<C, B>& x)
+ {
+ ls.os_ << x;
+ }
+
+
+ // entities
+ //
+ template <typename C, typename B, typename entity>
+ inline void
+ operator<< (xercesc::DOMElement& e, const entities<C, B, entity>& v)
+ {
+ const list<entity, C>& r (v);
+ e << r;
+ }
+
+ template <typename C, typename B, typename entity>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const entities<C, B, entity>& v)
+ {
+ const list<entity, C>& r (v);
+ a << r;
+ }
+
+ template <typename C, typename B, typename entity>
+ inline void
+ operator<< (list_stream<C>& ls, const entities<C, B, entity>& v)
+ {
+ const list<entity, C>& r (v);
+ ls << r;
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/serialization/boolean.hxx b/libxsd/xsd/cxx/tree/serialization/boolean.hxx
new file mode 100644
index 0000000..78dab11
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/boolean.hxx
@@ -0,0 +1,52 @@
+// file : xsd/cxx/tree/serialization/boolean.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_BOOLEAN_HXX
+#define XSD_CXX_TREE_SERIALIZATION_BOOLEAN_HXX
+
+#include <sstream>
+
+namespace XERCES_CPP_NAMESPACE
+{
+ inline void
+ operator<< (xercesc::DOMElement& e, bool b)
+ {
+ std::basic_ostringstream<char> os;
+ os.setf (std::ios_base::boolalpha);
+ os << b;
+ e << os.str ();
+ }
+
+ inline void
+ operator<< (xercesc::DOMAttr& a, bool b)
+ {
+ std::basic_ostringstream<char> os;
+ os.setf (std::ios_base::boolalpha);
+ os << b;
+ a << os.str ();
+ }
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ inline void
+ operator<< (list_stream<C>& ls, bool b)
+ {
+ // We don't need to restore the original bool format flag
+ // since items in the list are all of the same type.
+ //
+ ls.os_.setf (std::ios_base::boolalpha);
+ ls.os_ << b;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_SERIALIZATION_BOOLEAN_HXX
diff --git a/libxsd/xsd/cxx/tree/serialization/byte.hxx b/libxsd/xsd/cxx/tree/serialization/byte.hxx
new file mode 100644
index 0000000..60a117f
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/byte.hxx
@@ -0,0 +1,46 @@
+// file : xsd/cxx/tree/serialization/byte.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_BYTE_HXX
+#define XSD_CXX_TREE_SERIALIZATION_BYTE_HXX
+
+#include <sstream>
+
+namespace XERCES_CPP_NAMESPACE
+{
+ inline void
+ operator<< (xercesc::DOMElement& e, signed char c)
+ {
+ std::basic_ostringstream<char> os;
+ os << static_cast<short> (c);
+ e << os.str ();
+ }
+
+ inline void
+ operator<< (xercesc::DOMAttr& a, signed char c)
+ {
+ std::basic_ostringstream<char> os;
+ os << static_cast<short> (c);
+ a << os.str ();
+ }
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ inline void
+ operator<< (list_stream<C>& ls, signed char c)
+ {
+ ls.os_ << static_cast<short> (c);
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_SERIALIZATION_BYTE_HXX
diff --git a/libxsd/xsd/cxx/tree/serialization/date-time.txx b/libxsd/xsd/cxx/tree/serialization/date-time.txx
new file mode 100644
index 0000000..8fde761
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/date-time.txx
@@ -0,0 +1,620 @@
+// file : xsd/cxx/tree/serialization/date-time.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <locale>
+#include <string>
+#include <ostream>
+#include <sstream>
+
+#include <xsd/cxx/tree/bits/literals.hxx> // bits::{gday_prefix,gmonth_prefix}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // time_zone
+ //
+ namespace bits
+ {
+ // Assumes the fill character is set to '0'.
+ //
+ template <typename C>
+ void
+ zone_insert (std::basic_ostream<C>& os, const time_zone& z)
+ {
+ // time-zone := Z|(+|-)HH:MM
+ //
+ short h = z.zone_hours ();
+ short m = z.zone_minutes ();
+
+ if (h == 0 && m == 0)
+ {
+ os << C ('Z');
+ }
+ else
+ {
+ if (h < 0 || m < 0)
+ {
+ h = -h;
+ m = -m;
+ os << C ('-');
+ }
+ else
+ os << C ('+');
+
+ if (h >= 0 && h <= 14 && m >= 0 && m <= 59)
+ {
+ os.width (2);
+ os << h << C (':');
+ os.width (2);
+ os << m;
+ }
+ }
+ }
+ }
+
+ // gday
+ //
+ namespace bits
+ {
+ template <typename C, typename B>
+ void
+ insert (std::basic_ostream<C>& os, const tree::gday<C, B>& x)
+ {
+ if (x.day () < 32)
+ {
+ // Save some time and space by not restoring the fill character
+ // since it is the same in case of a list.
+ //
+ os.fill (C ('0'));
+ os << bits::gday_prefix<C> ();
+ os.width (2);
+ os << x.day ();
+
+ if (x.zone_present ())
+ zone_insert (os, x);
+ }
+ }
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const gday<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ e << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const gday<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ a << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const gday<C, B>& x)
+ {
+ bits::insert (ls.os_, x);
+ }
+
+ // gmonth
+ //
+ namespace bits
+ {
+ template <typename C, typename B>
+ void
+ insert (std::basic_ostream<C>& os, const tree::gmonth<C, B>& x)
+ {
+ if (x.month () < 13)
+ {
+ os.fill (C ('0'));
+ os << bits::gmonth_prefix<C> ();
+ os.width (2);
+ os << x.month ();
+
+ if (x.zone_present ())
+ zone_insert (os, x);
+ }
+ }
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const gmonth<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ e << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const gmonth<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ a << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const gmonth<C, B>& x)
+ {
+ bits::insert (ls.os_, x);
+ }
+
+ // gyear
+ //
+ namespace bits
+ {
+ template <typename C, typename B>
+ void
+ insert (std::basic_ostream<C>& os, const tree::gyear<C, B>& x)
+ {
+ os.fill (C ('0'));
+ os.width (4);
+ os << x.year ();
+
+ if (x.zone_present ())
+ zone_insert (os, x);
+ }
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const gyear<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ e << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const gyear<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ a << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const gyear<C, B>& x)
+ {
+ bits::insert (ls.os_, x);
+ }
+
+ // gmonth_day
+ //
+ namespace bits
+ {
+ template <typename C, typename B>
+ void
+ insert (std::basic_ostream<C>& os, const tree::gmonth_day<C, B>& x)
+ {
+ if (x.month () < 13 && x.day () < 32)
+ {
+ os.fill (C ('0'));
+ os << bits::gmonth_prefix<C> ();
+ os.width (2);
+ os << x.month () << C ('-');
+ os.width (2);
+ os << x.day ();
+
+ if (x.zone_present ())
+ zone_insert (os, x);
+ }
+ }
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const gmonth_day<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ e << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const gmonth_day<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ a << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const gmonth_day<C, B>& x)
+ {
+ bits::insert (ls.os_, x);
+ }
+
+ // gyear_month
+ //
+ namespace bits
+ {
+ template <typename C, typename B>
+ void
+ insert (std::basic_ostream<C>& os, const tree::gyear_month<C, B>& x)
+ {
+ if (x.month () < 13)
+ {
+ os.fill (C ('0'));
+ os.width (4);
+ os << x.year () << C ('-');
+ os.width (2);
+ os << x.month ();
+
+ if (x.zone_present ())
+ zone_insert (os, x);
+ }
+ }
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const gyear_month<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ e << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const gyear_month<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ a << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const gyear_month<C, B>& x)
+ {
+ bits::insert (ls.os_, x);
+ }
+
+ // date
+ //
+ namespace bits
+ {
+ template <typename C, typename B>
+ void
+ insert (std::basic_ostream<C>& os, const tree::date<C, B>& x)
+ {
+ if (x.month () < 13 && x.day () < 32)
+ {
+ os.fill (C ('0'));
+ os.width (4);
+ os << x.year () << C ('-');
+ os.width (2);
+ os << x.month () << C ('-');
+ os.width (2);
+ os << x.day ();
+
+ if (x.zone_present ())
+ zone_insert (os, x);
+ }
+ }
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const date<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ e << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const date<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ a << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const date<C, B>& x)
+ {
+ bits::insert (ls.os_, x);
+ }
+
+ // time
+ //
+ namespace bits
+ {
+ template <typename C, typename B>
+ void
+ insert (std::basic_ostream<C>& os, const tree::time<C, B>& x)
+ {
+ if (x.hours () <= 24 &&
+ x.minutes () <= 59 &&
+ x.seconds () >= 0.0 &&
+ x.seconds () < 60.0)
+ {
+ os.fill (C ('0'));
+ os.width (2);
+ os << x.hours () << C (':');
+
+ os.width (2);
+ os << x.minutes () << C (':');
+
+ std::basic_ostringstream<C> ostr;
+ ostr.imbue (std::locale::classic ());
+ ostr.width (9);
+ ostr.fill (C ('0'));
+ ostr << std::fixed << x.seconds ();
+
+ std::basic_string<C> s (ostr.str ());
+
+ // Remove the trailing zeros and the decimal point if necessary.
+ //
+ typedef typename std::basic_string<C>::size_type size_type;
+
+ size_type size (s.size ()), n (size);
+
+ for (; n > 0 && s[n - 1] == C ('0'); --n)/*noop*/;
+
+ if (n > 0 && s[n - 1] == C ('.'))
+ --n;
+
+ if (n != size)
+ s.resize (n);
+
+ os << s;
+
+ if (x.zone_present ())
+ zone_insert (os, x);
+ }
+ }
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const time<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ e << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const time<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ a << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const time<C, B>& x)
+ {
+ bits::insert (ls.os_, x);
+ }
+
+ // date_time
+ //
+ namespace bits
+ {
+ template <typename C, typename B>
+ void
+ insert (std::basic_ostream<C>& os, const tree::date_time<C, B>& x)
+ {
+ if (x.month () <= 12 &&
+ x.day () <= 31 &&
+ x.hours () <= 24 &&
+ x.minutes () <= 59 &&
+ x.seconds () >= 0.0 &&
+ x.seconds () < 60.0)
+ {
+ os.fill (C ('0'));
+ os.width (4);
+ os << x.year () << C ('-');
+
+ os.width (2);
+ os << x.month () << C ('-');
+
+ os.width (2);
+ os << x.day () << C ('T');
+
+ os.width (2);
+ os << x.hours () << C (':');
+
+ os.width (2);
+ os << x.minutes () << C (':');
+
+ std::basic_ostringstream<C> ostr;
+ ostr.imbue (std::locale::classic ());
+ ostr.width (9);
+ ostr.fill (C ('0'));
+ ostr << std::fixed << x.seconds ();
+
+ std::basic_string<C> s (ostr.str ());
+
+ // Remove the trailing zeros and the decimal point if necessary.
+ //
+ typedef typename std::basic_string<C>::size_type size_type;
+
+ size_type size (s.size ()), n (size);
+
+ for (; n > 0 && s[n - 1] == C ('0'); --n)/*noop*/;
+
+ if (n > 0 && s[n - 1] == C ('.'))
+ --n;
+
+ if (n != size)
+ s.resize (n);
+
+ os << s;
+
+ if (x.zone_present ())
+ zone_insert (os, x);
+ }
+ }
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const date_time<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ e << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const date_time<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ a << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const date_time<C, B>& x)
+ {
+ bits::insert (ls.os_, x);
+ }
+
+ // duration
+ //
+ namespace bits
+ {
+ template <typename C, typename B>
+ void
+ insert (std::basic_ostream<C>& os, const tree::duration<C, B>& x)
+ {
+ if (x.negative ())
+ os << C ('-');
+
+ os << C ('P');
+
+ // years
+ //
+ // In case it is 0-duration, use the years field to handle
+ // this case.
+ //
+ if (x.years () != 0 ||
+ (x.months () == 0 &&
+ x.days () == 0 &&
+ x.hours () == 0 &&
+ x.minutes () == 0 &&
+ x.seconds () == 0.0))
+ {
+ os << x.years () << C ('Y');
+ }
+
+ // months
+ //
+ if (x.months () != 0)
+ {
+ os << x.months () << C ('M');
+ }
+
+ // days
+ //
+ if (x.days () != 0)
+ {
+ os << x.days () << C ('D');
+ }
+
+ // Figure out if we need the 'T' delimiter.
+ //
+ if (x.hours () != 0 ||
+ x.minutes () != 0 ||
+ x.seconds () != 0.0)
+ os << C ('T');
+
+ // hours
+ //
+ if (x.hours () != 0)
+ {
+ os << x.hours () << C ('H');
+ }
+
+ // minutes
+ //
+ if (x.minutes () != 0)
+ {
+ os << x.minutes () << C ('M');
+ }
+
+ // seconds
+ //
+ if (x.seconds () > 0.0)
+ {
+ std::basic_ostringstream<C> ostr;
+ ostr.imbue (std::locale::classic ());
+ ostr << std::fixed << x.seconds ();
+
+ std::basic_string<C> s (ostr.str ());
+
+ // Remove the trailing zeros and the decimal point if necessary.
+ //
+ typedef typename std::basic_string<C>::size_type size_type;
+
+ size_type size (s.size ()), n (size);
+
+ for (; n > 0 && s[n - 1] == C ('0'); --n)/*noop*/;
+
+ if (n > 0 && s[n - 1] == C ('.'))
+ --n;
+
+ if (n != size)
+ s.resize (n);
+
+ os << s << C ('S');
+ }
+ }
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMElement& e, const duration<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ e << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (xercesc::DOMAttr& a, const duration<C, B>& x)
+ {
+ std::basic_ostringstream<C> os;
+ bits::insert (os, x);
+ a << os.str ();
+ }
+
+ template <typename C, typename B>
+ inline void
+ operator<< (list_stream<C>& ls, const duration<C, B>& x)
+ {
+ bits::insert (ls.os_, x);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/serialization/decimal.hxx b/libxsd/xsd/cxx/tree/serialization/decimal.hxx
new file mode 100644
index 0000000..3fa2297
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/decimal.hxx
@@ -0,0 +1,126 @@
+// file : xsd/cxx/tree/serialization/decimal.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_DECIMAL_HXX
+#define XSD_CXX_TREE_SERIALIZATION_DECIMAL_HXX
+
+#include <limits> // std::numeric_limits
+#include <locale>
+#include <sstream>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ namespace bits
+ {
+ // The formula for the number of decimla digits required is given in:
+ //
+ // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf
+ //
+ template <typename C>
+ std::basic_string<C>
+ insert (const as_decimal<double>& d)
+ {
+ std::basic_ostringstream<C> os;
+ os.imbue (std::locale::classic ());
+ std::streamsize prec;
+
+ const facet* f = d.facets ?
+ facet::find (d.facets, facet::fraction_digits) : 0;
+
+ if (f)
+ prec = static_cast<std::streamsize> (f->value);
+ else
+ {
+ // Precision.
+ //
+#if defined (XSD_CXX_TREE_DECIMAL_PRECISION_MAX)
+ prec = 2 + std::numeric_limits<double>::digits * 301/1000;
+#elif defined (XSD_CXX_TREE_DECIMAL_PRECISION)
+ prec = XSD_CXX_TREE_DECIMAL_PRECISION;
+#else
+ prec = std::numeric_limits<double>::digits10;
+#endif
+ }
+
+ os.precision (prec);
+ os << std::fixed << d.x;
+ std::basic_string<C> r (os.str ());
+ const C* cr (r.c_str ());
+
+ // Remove the trailing zeros and the decimal point if necessary.
+ //
+ typename std::basic_string<C>::size_type size (r.size ()), n (size);
+
+ if (prec != 0)
+ {
+ for (; n > 0 && cr[n - 1] == '0'; --n)/*noop*/;
+
+ if (n > 0 && cr[n - 1] == '.')
+ --n;
+ }
+
+ // See if we have a restriction on total digits.
+ //
+ f = d.facets ? facet::find (d.facets, facet::total_digits) : 0;
+
+ if (f && n > f->value)
+ {
+ // Point and sign do not count so figure out if we have them.
+ //
+ typename std::basic_string<C>::size_type extra (
+ cr[0] == '-' ? 1 : 0);
+
+ if (r.find ('.') < n)
+ extra++;
+
+ // Unless we have a point and the size difference is one,
+ // remove some digits.
+ //
+ if ((n - extra) > f->value)
+ n -= (n - extra - f->value);
+
+ if (n > 0 && cr[n - 1] == '.')
+ --n;
+ }
+
+ if (n != size)
+ r.resize (n);
+
+ return r;
+ }
+ }
+
+ template <typename C>
+ inline void
+ operator<< (list_stream<C>& ls, const as_decimal<double>& d)
+ {
+ ls.os_ << bits::insert<C> (d);
+ }
+ }
+ }
+}
+
+namespace XERCES_CPP_NAMESPACE
+{
+ inline void
+ operator<< (xercesc::DOMElement& e,
+ const xsd::cxx::tree::as_decimal<double>& d)
+ {
+ e << xsd::cxx::tree::bits::insert<char> (d);
+ }
+
+ inline void
+ operator<< (xercesc::DOMAttr& a,
+ const xsd::cxx::tree::as_decimal<double>& d)
+ {
+ a << xsd::cxx::tree::bits::insert<char> (d);
+ }
+}
+
+#endif // XSD_CXX_TREE_SERIALIZATION_DECIMAL_HXX
diff --git a/libxsd/xsd/cxx/tree/serialization/double.hxx b/libxsd/xsd/cxx/tree/serialization/double.hxx
new file mode 100644
index 0000000..9cd77e1
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/double.hxx
@@ -0,0 +1,96 @@
+// file : xsd/cxx/tree/serialization/double.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_DOUBLE_HXX
+#define XSD_CXX_TREE_SERIALIZATION_DOUBLE_HXX
+
+#include <limits> // std::numeric_limits
+#include <locale>
+#include <sstream>
+
+#include <xsd/cxx/tree/bits/literals.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ namespace bits
+ {
+ // The formula for the number of decimla digits required is given in:
+ //
+ // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf
+ //
+ template <typename C>
+ std::basic_string<C>
+ insert (const as_double<double>& d)
+ {
+ std::basic_string<C> r;
+
+ if (d.x == std::numeric_limits<double>::infinity ())
+ r = bits::positive_inf<C> ();
+ else if (d.x == -std::numeric_limits<double>::infinity ())
+ r = bits::negative_inf<C> ();
+ else if (!(d.x == d.x))
+ r = bits::nan<C> ();
+ else
+ {
+ std::basic_ostringstream<C> os;
+ os.imbue (std::locale::classic ());
+
+ // Precision.
+ //
+#if defined (XSD_CXX_TREE_DOUBLE_PRECISION_MAX)
+ os.precision (2 + std::numeric_limits<double>::digits * 301/1000);
+#elif defined (XSD_CXX_TREE_DOUBLE_PRECISION)
+ os.precision (XSD_CXX_TREE_DOUBLE_PRECISION);
+#else
+ os.precision (std::numeric_limits<double>::digits10);
+#endif
+ // Format.
+ //
+#if defined (XSD_CXX_TREE_DOUBLE_FIXED)
+ os << std::fixed << d.x;
+#elif defined (XSD_CXX_TREE_DOUBLE_SCIENTIFIC)
+ os << std::scientific << d.x;
+#else
+ os << d.x;
+#endif
+ r = os.str ();
+ }
+
+ return r;
+ }
+ }
+
+ template <typename C>
+ inline void
+ operator<< (list_stream<C>& ls, const as_double<double>& d)
+ {
+ ls.os_ << bits::insert<C> (d);
+ }
+ }
+ }
+}
+
+namespace XERCES_CPP_NAMESPACE
+{
+ inline void
+ operator<< (xercesc::DOMElement& e,
+ const xsd::cxx::tree::as_double<double>& d)
+ {
+ e << xsd::cxx::tree::bits::insert<char> (d);
+ }
+
+ inline void
+ operator<< (xercesc::DOMAttr& a,
+ const xsd::cxx::tree::as_double<double>& d)
+ {
+ a << xsd::cxx::tree::bits::insert<char> (d);
+ }
+}
+
+#endif // XSD_CXX_TREE_SERIALIZATION_DOUBLE_HXX
diff --git a/libxsd/xsd/cxx/tree/serialization/element-map.txx b/libxsd/xsd/cxx/tree/serialization/element-map.txx
new file mode 100644
index 0000000..751f07f
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/element-map.txx
@@ -0,0 +1,40 @@
+// file : xsd/cxx/tree/serialization/element-map.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_ELEMENT_MAP_TXX
+#define XSD_CXX_TREE_SERIALIZATION_ELEMENT_MAP_TXX
+
+#include <xsd/cxx/tree/exceptions.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C, typename T>
+ void element_map<C, T>::
+ serialize (xercesc::DOMElement& e, const element_type& x)
+ {
+ const qualified_name n (x._name (), x._namespace ());
+ typename map::const_iterator i (map_->find (n));
+
+ if (i != map_->end () && i->second.serializer_ != 0)
+ return (i->second.serializer_) (e, x);
+ else
+ throw no_element_info<C> (n.name (), n.namespace_ ());
+ }
+
+ template<typename T, typename C, typename B>
+ void
+ serializer_impl (xercesc::DOMElement& e, const element_type<C, B>& x)
+ {
+ e << static_cast<const T&> (x);
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_SERIALIZATION_ELEMENT_MAP_TXX
diff --git a/libxsd/xsd/cxx/tree/serialization/float.hxx b/libxsd/xsd/cxx/tree/serialization/float.hxx
new file mode 100644
index 0000000..f5d8a1f
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/float.hxx
@@ -0,0 +1,94 @@
+// file : xsd/cxx/tree/serialization/float.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_FLOAT_HXX
+#define XSD_CXX_TREE_SERIALIZATION_FLOAT_HXX
+
+#include <limits> // std::numeric_limits
+#include <locale>
+#include <sstream>
+
+#include <xsd/cxx/tree/bits/literals.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ namespace bits
+ {
+ // The formula for the number of decimla digits required is given in:
+ //
+ // http://www.open-std.org/JTC1/SC22/WG21/docs/papers/2005/n1822.pdf
+ //
+ template <typename C>
+ std::basic_string<C>
+ insert (float f)
+ {
+ std::basic_string<C> r;
+
+ if (f == std::numeric_limits<float>::infinity ())
+ r = bits::positive_inf<C> ();
+ else if (f == -std::numeric_limits<float>::infinity ())
+ r = bits::negative_inf<C> ();
+ else if (!(f == f))
+ r = bits::nan<C> ();
+ else
+ {
+ std::basic_ostringstream<C> os;
+ os.imbue (std::locale::classic ());
+
+ // Precision.
+ //
+#if defined (XSD_CXX_TREE_FLOAT_PRECISION_MAX)
+ os.precision (2 + std::numeric_limits<float>::digits * 301/1000);
+#elif defined (XSD_CXX_TREE_FLOAT_PRECISION)
+ os.precision (XSD_CXX_TREE_FLOAT_PRECISION);
+#else
+ os.precision (std::numeric_limits<float>::digits10);
+#endif
+ // Format.
+ //
+#if defined (XSD_CXX_TREE_FLOAT_FIXED)
+ os << std::fixed << f;
+#elif defined (XSD_CXX_TREE_FLOAT_SCIENTIFIC)
+ os << std::scientific << f;
+#else
+ os << f;
+#endif
+ r = os.str ();
+ }
+
+ return r;
+ }
+ }
+
+ template <typename C>
+ inline void
+ operator<< (list_stream<C>& ls, float f)
+ {
+ ls.os_ << bits::insert<C> (f);
+ }
+ }
+ }
+}
+
+namespace XERCES_CPP_NAMESPACE
+{
+ inline void
+ operator<< (xercesc::DOMElement& e, float f)
+ {
+ e << xsd::cxx::tree::bits::insert<char> (f);
+ }
+
+ inline void
+ operator<< (xercesc::DOMAttr& a, float f)
+ {
+ a << xsd::cxx::tree::bits::insert<char> (f);
+ }
+}
+
+#endif // XSD_CXX_TREE_SERIALIZATION_FLOAT_HXX
diff --git a/libxsd/xsd/cxx/tree/serialization/int.hxx b/libxsd/xsd/cxx/tree/serialization/int.hxx
new file mode 100644
index 0000000..5785a3a
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/int.hxx
@@ -0,0 +1,46 @@
+// file : xsd/cxx/tree/serialization/int.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_INT_HXX
+#define XSD_CXX_TREE_SERIALIZATION_INT_HXX
+
+#include <sstream>
+
+namespace XERCES_CPP_NAMESPACE
+{
+ inline void
+ operator<< (xercesc::DOMElement& e, int i)
+ {
+ std::basic_ostringstream<char> os;
+ os << i;
+ e << os.str ();
+ }
+
+ inline void
+ operator<< (xercesc::DOMAttr& a, int i)
+ {
+ std::basic_ostringstream<char> os;
+ os << i;
+ a << os.str ();
+ }
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ inline void
+ operator<< (list_stream<C>& ls, int i)
+ {
+ ls.os_ << i;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_SERIALIZATION_INT_HXX
diff --git a/libxsd/xsd/cxx/tree/serialization/long.hxx b/libxsd/xsd/cxx/tree/serialization/long.hxx
new file mode 100644
index 0000000..e4896ae
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/long.hxx
@@ -0,0 +1,46 @@
+// file : xsd/cxx/tree/serialization/long.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_LONG_HXX
+#define XSD_CXX_TREE_SERIALIZATION_LONG_HXX
+
+#include <sstream>
+
+namespace XERCES_CPP_NAMESPACE
+{
+ inline void
+ operator<< (xercesc::DOMElement& e, long long l)
+ {
+ std::basic_ostringstream<char> os;
+ os << l;
+ e << os.str ();
+ }
+
+ inline void
+ operator<< (xercesc::DOMAttr& a, long long l)
+ {
+ std::basic_ostringstream<char> os;
+ os << l;
+ a << os.str ();
+ }
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ inline void
+ operator<< (list_stream<C>& ls, long long l)
+ {
+ ls.os_ << l;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_SERIALIZATION_LONG_HXX
diff --git a/libxsd/xsd/cxx/tree/serialization/short.hxx b/libxsd/xsd/cxx/tree/serialization/short.hxx
new file mode 100644
index 0000000..a935b7c
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/short.hxx
@@ -0,0 +1,46 @@
+// file : xsd/cxx/tree/serialization/short.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_SHORT_HXX
+#define XSD_CXX_TREE_SERIALIZATION_SHORT_HXX
+
+#include <sstream>
+
+namespace XERCES_CPP_NAMESPACE
+{
+ inline void
+ operator<< (xercesc::DOMElement& e, short s)
+ {
+ std::basic_ostringstream<char> os;
+ os << s;
+ e << os.str ();
+ }
+
+ inline void
+ operator<< (xercesc::DOMAttr& a, short s)
+ {
+ std::basic_ostringstream<char> os;
+ os << s;
+ a << os.str ();
+ }
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ inline void
+ operator<< (list_stream<C>& ls, short s)
+ {
+ ls.os_ << s;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_SERIALIZATION_SHORT_HXX
diff --git a/libxsd/xsd/cxx/tree/serialization/unsigned-byte.hxx b/libxsd/xsd/cxx/tree/serialization/unsigned-byte.hxx
new file mode 100644
index 0000000..4e52a9d
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/unsigned-byte.hxx
@@ -0,0 +1,46 @@
+// file : xsd/cxx/tree/serialization/unsigned-byte.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_UNSIGNED_BYTE_HXX
+#define XSD_CXX_TREE_SERIALIZATION_UNSIGNED_BYTE_HXX
+
+#include <sstream>
+
+namespace XERCES_CPP_NAMESPACE
+{
+ inline void
+ operator<< (xercesc::DOMElement& e, unsigned char c)
+ {
+ std::basic_ostringstream<char> os;
+ os << static_cast<unsigned short> (c);
+ e << os.str ();
+ }
+
+ inline void
+ operator<< (xercesc::DOMAttr& a, unsigned char c)
+ {
+ std::basic_ostringstream<char> os;
+ os << static_cast<unsigned short> (c);
+ a << os.str ();
+ }
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ inline void
+ operator<< (list_stream<C>& ls, unsigned char c)
+ {
+ ls.os_ << static_cast<unsigned short> (c);
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_SERIALIZATION_UNSIGNED_BYTE_HXX
diff --git a/libxsd/xsd/cxx/tree/serialization/unsigned-int.hxx b/libxsd/xsd/cxx/tree/serialization/unsigned-int.hxx
new file mode 100644
index 0000000..e5514d5
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/unsigned-int.hxx
@@ -0,0 +1,46 @@
+// file : xsd/cxx/tree/serialization/unsigned-int.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_UNSIGNED_INT_HXX
+#define XSD_CXX_TREE_SERIALIZATION_UNSIGNED_INT_HXX
+
+#include <sstream>
+
+namespace XERCES_CPP_NAMESPACE
+{
+ inline void
+ operator<< (xercesc::DOMElement& e, unsigned int i)
+ {
+ std::basic_ostringstream<char> os;
+ os << i;
+ e << os.str ();
+ }
+
+ inline void
+ operator<< (xercesc::DOMAttr& a, unsigned int i)
+ {
+ std::basic_ostringstream<char> os;
+ os << i;
+ a << os.str ();
+ }
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ inline void
+ operator<< (list_stream<C>& ls, unsigned int i)
+ {
+ ls.os_ << i;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_SERIALIZATION_UNSIGNED_INT_HXX
diff --git a/libxsd/xsd/cxx/tree/serialization/unsigned-long.hxx b/libxsd/xsd/cxx/tree/serialization/unsigned-long.hxx
new file mode 100644
index 0000000..aebf7ba
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/unsigned-long.hxx
@@ -0,0 +1,46 @@
+// file : xsd/cxx/tree/serialization/unsigned-long.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_UNSIGNED_LONG_HXX
+#define XSD_CXX_TREE_SERIALIZATION_UNSIGNED_LONG_HXX
+
+#include <sstream>
+
+namespace XERCES_CPP_NAMESPACE
+{
+ inline void
+ operator<< (xercesc::DOMElement& e, unsigned long long l)
+ {
+ std::basic_ostringstream<char> os;
+ os << l;
+ e << os.str ();
+ }
+
+ inline void
+ operator<< (xercesc::DOMAttr& a, unsigned long long l)
+ {
+ std::basic_ostringstream<char> os;
+ os << l;
+ a << os.str ();
+ }
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ inline void
+ operator<< (list_stream<C>& ls, unsigned long long l)
+ {
+ ls.os_ << l;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_SERIALIZATION_UNSIGNED_LONG_HXX
diff --git a/libxsd/xsd/cxx/tree/serialization/unsigned-short.hxx b/libxsd/xsd/cxx/tree/serialization/unsigned-short.hxx
new file mode 100644
index 0000000..df8ea97
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/serialization/unsigned-short.hxx
@@ -0,0 +1,46 @@
+// file : xsd/cxx/tree/serialization/unsigned-short.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_SERIALIZATION_UNSIGNED_SHORT_HXX
+#define XSD_CXX_TREE_SERIALIZATION_UNSIGNED_SHORT_HXX
+
+#include <sstream>
+
+namespace XERCES_CPP_NAMESPACE
+{
+ inline void
+ operator<< (xercesc::DOMElement& e, unsigned short s)
+ {
+ std::basic_ostringstream<char> os;
+ os << s;
+ e << os.str ();
+ }
+
+ inline void
+ operator<< (xercesc::DOMAttr& a, unsigned short s)
+ {
+ std::basic_ostringstream<char> os;
+ os << s;
+ a << os.str ();
+ }
+}
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ inline void
+ operator<< (list_stream<C>& ls, unsigned short s)
+ {
+ ls.os_ << s;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_SERIALIZATION_UNSIGNED_SHORT_HXX
diff --git a/libxsd/xsd/cxx/tree/std-ostream-map.hxx b/libxsd/xsd/cxx/tree/std-ostream-map.hxx
new file mode 100644
index 0000000..25f225f
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/std-ostream-map.hxx
@@ -0,0 +1,110 @@
+// file : xsd/cxx/tree/std-ostream-map.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_STD_OSTREAM_MAP_HXX
+#define XSD_CXX_TREE_STD_OSTREAM_MAP_HXX
+
+#include <map>
+#include <cstddef> // std::size_t
+#include <ostream>
+#include <typeinfo>
+
+#include <xsd/cxx/tree/elements.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct std_ostream_map
+ {
+ typedef std::type_info type_id;
+ typedef void (*inserter) (std::ostream&, const type&);
+
+ std_ostream_map ();
+
+ void
+ register_type (const type_id&, inserter, bool override = true);
+
+ void
+ insert (std::ostream&, const type&);
+
+ public:
+ inserter
+ find (const type_id&) const;
+
+ private:
+ struct type_id_comparator
+ {
+ bool
+ operator() (const type_id* x, const type_id* y) const
+ {
+ // XL C++ on AIX has buggy type_info::before() in that
+ // it returns true for two different type_info objects
+ // that happened to be for the same type.
+ //
+#if defined(__xlC__) && defined(_AIX)
+ return *x != *y && x->before (*y);
+#else
+ return x->before (*y);
+#endif
+ }
+ };
+
+ typedef
+ std::map<const type_id*, inserter, type_id_comparator>
+ type_map;
+
+ type_map type_map_;
+ };
+
+ //
+ //
+ template<unsigned long id, typename C>
+ struct std_ostream_plate
+ {
+ static std_ostream_map<C>* map;
+ static std::size_t count;
+
+ std_ostream_plate ();
+ ~std_ostream_plate ();
+ };
+
+ template<unsigned long id, typename C>
+ std_ostream_map<C>* std_ostream_plate<id, C>::map = 0;
+
+ template<unsigned long id, typename C>
+ std::size_t std_ostream_plate<id, C>::count = 0;
+
+
+ //
+ //
+ template<unsigned long id, typename C>
+ inline std_ostream_map<C>&
+ std_ostream_map_instance ()
+ {
+ return *std_ostream_plate<id, C>::map;
+ }
+
+ //
+ //
+ template<typename T>
+ void
+ inserter_impl (std::ostream&, const type&);
+
+ template<unsigned long id, typename C, typename T>
+ struct std_ostream_initializer
+ {
+ std_ostream_initializer ();
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/tree/std-ostream-map.txx>
+
+#endif // XSD_CXX_TREE_STD_OSTREAM_MAP_HXX
diff --git a/libxsd/xsd/cxx/tree/std-ostream-map.txx b/libxsd/xsd/cxx/tree/std-ostream-map.txx
new file mode 100644
index 0000000..c1187ef
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/std-ostream-map.txx
@@ -0,0 +1,279 @@
+// file : xsd/cxx/tree/std-ostream-map.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd/cxx/tree/types.hxx>
+#include <xsd/cxx/tree/std-ostream-operators.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // std_ostream_map
+ //
+ template <typename C>
+ std_ostream_map<C>::
+ std_ostream_map ()
+ {
+ // anyType and anySimpleType.
+ //
+ register_type (
+ typeid (type),
+ &inserter_impl<type>,
+ false);
+
+ typedef simple_type<type> simple_type;
+ register_type (
+ typeid (simple_type),
+ &inserter_impl<simple_type>,
+ false);
+
+
+ // Strings
+ //
+ typedef string<C, simple_type> string;
+ register_type (
+ typeid (string),
+ &inserter_impl<string>,
+ false);
+
+ typedef normalized_string<C, string> normalized_string;
+ register_type (
+ typeid (normalized_string),
+ &inserter_impl<normalized_string>,
+ false);
+
+ typedef token<C, normalized_string> token;
+ register_type (
+ typeid (token),
+ &inserter_impl<token>,
+ false);
+
+ typedef name<C, token> name;
+ register_type (
+ typeid (name),
+ &inserter_impl<name>,
+ false);
+
+ typedef nmtoken<C, token> nmtoken;
+ register_type (
+ typeid (nmtoken),
+ &inserter_impl<nmtoken>,
+ false);
+
+ typedef nmtokens<C, simple_type, nmtoken> nmtokens;
+ register_type (
+ typeid (nmtokens),
+ &inserter_impl<nmtokens>,
+ false);
+
+ typedef ncname<C, name> ncname;
+ register_type (
+ typeid (ncname),
+ &inserter_impl<ncname>,
+ false);
+
+ typedef language<C, token> language;
+ register_type (
+ typeid (language),
+ &inserter_impl<language>,
+ false);
+
+
+ // ID/IDREF.
+ //
+ typedef id<C, ncname> id;
+ register_type (
+ typeid (id),
+ &inserter_impl<id>,
+ false);
+
+ typedef idref<type, C, ncname> idref;
+ register_type (
+ typeid (idref),
+ &inserter_impl<idref>,
+ false);
+
+ typedef idrefs<C, simple_type, idref> idrefs;
+ register_type (
+ typeid (idrefs),
+ &inserter_impl<idrefs>,
+ false);
+
+
+ // URI.
+ //
+ typedef uri<C, simple_type> uri;
+ register_type (
+ typeid (uri),
+ &inserter_impl<uri>,
+ false);
+
+
+ // Qualified name.
+ //
+ typedef qname<C, simple_type, uri, ncname> qname;
+ register_type (
+ typeid (qname),
+ &inserter_impl<qname>,
+ false);
+
+
+ // Binary.
+ //
+ typedef base64_binary<C, simple_type> base64_binary;
+ register_type (
+ typeid (base64_binary),
+ &inserter_impl<base64_binary>,
+ false);
+
+ typedef hex_binary<C, simple_type> hex_binary;
+ register_type (
+ typeid (hex_binary),
+ &inserter_impl<hex_binary>,
+ false);
+
+
+ // Date/time.
+ //
+ typedef gday<C, simple_type> gday;
+ register_type (
+ typeid (gday),
+ &inserter_impl<gday>,
+ false);
+
+ typedef gmonth<C, simple_type> gmonth;
+ register_type (
+ typeid (gmonth),
+ &inserter_impl<gmonth>,
+ false);
+
+ typedef gyear<C, simple_type> gyear;
+ register_type (
+ typeid (gyear),
+ &inserter_impl<gyear>,
+ false);
+
+ typedef gmonth_day<C, simple_type> gmonth_day;
+ register_type (
+ typeid (gmonth_day),
+ &inserter_impl<gmonth_day>,
+ false);
+
+ typedef gyear_month<C, simple_type> gyear_month;
+ register_type (
+ typeid (gyear_month),
+ &inserter_impl<gyear_month>,
+ false);
+
+ typedef date<C, simple_type> date;
+ register_type (
+ typeid (date),
+ &inserter_impl<date>,
+ false);
+
+ typedef time<C, simple_type> time;
+ register_type (
+ typeid (time),
+ &inserter_impl<time>,
+ false);
+
+ typedef date_time<C, simple_type> date_time;
+ register_type (
+ typeid (date_time),
+ &inserter_impl<date_time>,
+ false);
+
+ typedef duration<C, simple_type> duration;
+ register_type (
+ typeid (duration),
+ &inserter_impl<duration>,
+ false);
+
+
+ // Entity.
+ //
+ typedef entity<C, ncname> entity;
+ register_type (
+ typeid (entity),
+ &inserter_impl<entity>,
+ false);
+
+ typedef entities<C, simple_type, entity> entities;
+ register_type (
+ typeid (entities),
+ &inserter_impl<entities>,
+ false);
+ }
+
+ template <typename C>
+ void std_ostream_map<C>::
+ register_type (const type_id& tid, inserter i, bool override)
+ {
+ if (override || type_map_.find (&tid) == type_map_.end ())
+ type_map_[&tid] = i;
+ }
+
+ template <typename C>
+ void std_ostream_map<C>::
+ insert (std::ostream& os, const type& x)
+ {
+ if (inserter i = find (typeid (x)))
+ i (os, x);
+ else
+ throw no_type_info<C> (std::basic_string<C> (),
+ std::basic_string<C> ()); // @@ TODO
+ }
+
+ template <typename C>
+ typename std_ostream_map<C>::inserter std_ostream_map<C>::
+ find (const type_id& tid) const
+ {
+ typename type_map::const_iterator i (type_map_.find (&tid));
+ return i == type_map_.end () ? 0 : i->second;
+ }
+
+ // std_ostream_plate
+ //
+ template<unsigned long id, typename C>
+ std_ostream_plate<id, C>::
+ std_ostream_plate ()
+ {
+ if (count == 0)
+ map = new std_ostream_map<C>;
+
+ ++count;
+ }
+
+ template<unsigned long id, typename C>
+ std_ostream_plate<id, C>::
+ ~std_ostream_plate ()
+ {
+ if (--count == 0)
+ delete map;
+ }
+
+ //
+ //
+ template<typename T>
+ void
+ inserter_impl (std::ostream& os, const type& x)
+ {
+ os << static_cast<const T&> (x);
+ }
+
+ // std_ostream_initializer
+ //
+ template<unsigned long id, typename C, typename T>
+ std_ostream_initializer<id, C, T>::
+ std_ostream_initializer ()
+ {
+ std_ostream_map_instance<id, C> ().register_type (
+ typeid (T), &inserter_impl<T>);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/std-ostream-operators.hxx b/libxsd/xsd/cxx/tree/std-ostream-operators.hxx
new file mode 100644
index 0000000..e7c9964
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/std-ostream-operators.hxx
@@ -0,0 +1,274 @@
+// file : xsd/cxx/tree/std-ostream-operators.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_STD_OSTREAM_OPERATORS_HXX
+#define XSD_CXX_TREE_STD_OSTREAM_OPERATORS_HXX
+
+#include <ostream>
+
+#include <xsd/cxx/tree/elements.hxx>
+#include <xsd/cxx/tree/containers.hxx>
+#include <xsd/cxx/tree/types.hxx>
+#include <xsd/cxx/tree/list.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // type
+ //
+ template <typename C>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const type&)
+ {
+ return os;
+ }
+
+
+ // simple_type
+ //
+ template <typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const simple_type<B>&)
+ {
+ return os;
+ }
+
+
+ // fundamental_base
+ //
+ template <typename T, typename C, typename B, schema_type::value ST>
+ inline
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, fundamental_base<T, C, B, ST> x)
+ {
+ T& r (x);
+ return os << r;
+ }
+
+ // optional: see containers.hxx
+ //
+
+ // list
+ //
+
+ // This is an xsd:list-style format (space-separated).
+ //
+ template <typename C, typename T, schema_type::value ST, bool fund>
+ std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const list<T, C, ST, fund>& v)
+ {
+ for (typename list<T, C, ST, fund>::const_iterator
+ b (v.begin ()), e (v.end ()), i (b); i != e; ++i)
+ {
+ if (i != b)
+ os << C (' ');
+
+ os << *i;
+ }
+
+ return os;
+ }
+
+
+ // Operators for built-in types.
+ //
+
+
+ // string
+ //
+ template <typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const string<C, B>& v)
+ {
+ const std::basic_string<C>& r (v);
+ return os << r;
+ }
+
+
+ // normalized_string
+ //
+ template <typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const normalized_string<C, B>& v)
+ {
+ const B& r (v);
+ return os << r;
+ }
+
+
+ // token
+ //
+ template <typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const token<C, B>& v)
+ {
+ const B& r (v);
+ return os << r;
+ }
+
+
+ // nmtoken
+ //
+ template <typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const nmtoken<C, B>& v)
+ {
+ const B& r (v);
+ return os << r;
+ }
+
+
+ // nmtokens
+ //
+ template <typename C, typename B, typename nmtoken>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const nmtokens<C, B, nmtoken>& v)
+ {
+ const list<nmtoken, C>& r (v);
+ return os << r;
+ }
+
+
+ // name
+ //
+ template <typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const name<C, B>& v)
+ {
+ const B& r (v);
+ return os << r;
+ }
+
+
+ // ncname
+ //
+ template <typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const ncname<C, B>& v)
+ {
+ const B& r (v);
+ return os << r;
+ }
+
+
+ // language
+ //
+ template <typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const language<C, B>& v)
+ {
+ const B& r (v);
+ return os << r;
+ }
+
+
+ // id
+ //
+ template <typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const id<C, B>& v)
+ {
+ const B& r (v);
+ return os << r;
+ }
+
+
+ // idref
+ //
+ template <typename T, typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const idref<T, C, B>& v)
+ {
+ const B& r (v);
+ return os << r;
+ }
+
+
+ // idrefs
+ //
+ template <typename C, typename B, typename idref>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const idrefs<C, B, idref>& v)
+ {
+ const list<idref, C>& r (v);
+ return os << r;
+ }
+
+
+ // uri
+ //
+ template <typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const uri<C, B>& v)
+ {
+ const std::basic_string<C>& r (v);
+ return os << r;
+ }
+
+
+ // qname
+ //
+ template <typename C, typename B, typename uri, typename ncname>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os,
+ const qname<C, B, uri, ncname>& n)
+ {
+ if (n.qualified ())
+ os << n.namespace_ () << C ('#');
+
+ return os << n.name ();
+ }
+
+
+ // base64_binary
+ //
+ template <typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const base64_binary<C, B>& v)
+ {
+ return os << v.encode ();
+ }
+
+
+ // hex_binary
+ //
+ template <typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const hex_binary<C, B>& v)
+ {
+ return os << v.encode ();
+ }
+
+
+ // entity
+ //
+ template <typename C, typename B>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const entity<C, B>& v)
+ {
+ const B& r (v);
+ return os << r;
+ }
+
+
+ // entities
+ //
+ template <typename C, typename B, typename entity>
+ inline std::basic_ostream<C>&
+ operator<< (std::basic_ostream<C>& os, const entities<C, B, entity>& v)
+ {
+ const list<entity, C>& r (v);
+ return os << r;
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/tree/date-time-ostream.txx>
+
+#endif // XSD_CXX_TREE_STD_OSTREAM_OPERATORS_HXX
diff --git a/libxsd/xsd/cxx/tree/stream-extraction-map.hxx b/libxsd/xsd/cxx/tree/stream-extraction-map.hxx
new file mode 100644
index 0000000..14a5423
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/stream-extraction-map.hxx
@@ -0,0 +1,97 @@
+// file : xsd/cxx/tree/stream-extraction-map.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_STREAM_EXTRACTION_MAP_HXX
+#define XSD_CXX_TREE_STREAM_EXTRACTION_MAP_HXX
+
+#include <map>
+#include <memory> // std::auto_ptr
+#include <cstddef> // std::size_t
+
+#include <xsd/cxx/tree/elements.hxx>
+#include <xsd/cxx/tree/istream.hxx>
+#include <xsd/cxx/xml/qualified-name.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename S, typename C>
+ struct stream_extraction_map
+ {
+ typedef xml::qualified_name<C> qualified_name;
+ typedef std::auto_ptr<type> (*extractor) (
+ istream<S>&, flags, container*);
+
+ public:
+ stream_extraction_map ();
+
+ void
+ register_type (const qualified_name& name,
+ extractor,
+ bool override = true);
+
+ std::auto_ptr<type>
+ extract (istream<S>&, flags, container*);
+
+ public:
+ extractor
+ find (const qualified_name& name) const;
+
+ private:
+ typedef std::map<qualified_name, extractor> type_map;
+
+ type_map type_map_;
+ };
+
+ //
+ //
+ template<unsigned long id, typename S, typename C>
+ struct stream_extraction_plate
+ {
+ static stream_extraction_map<S, C>* map;
+ static std::size_t count;
+
+ stream_extraction_plate ();
+ ~stream_extraction_plate ();
+ };
+
+ template<unsigned long id, typename S, typename C>
+ stream_extraction_map<S, C>* stream_extraction_plate<id, S, C>::map = 0;
+
+ template<unsigned long id, typename S, typename C>
+ std::size_t stream_extraction_plate<id, S, C>::count = 0;
+
+
+ //
+ //
+ template<unsigned long id, typename S, typename C>
+ inline stream_extraction_map<S, C>&
+ stream_extraction_map_instance ()
+ {
+ return *stream_extraction_plate<id, S, C>::map;
+ }
+
+ //
+ //
+ template<typename S, typename T>
+ std::auto_ptr<type>
+ extractor_impl (istream<S>&, flags, container*);
+
+
+ template<unsigned long id, typename S, typename C, typename T>
+ struct stream_extraction_initializer
+ {
+ stream_extraction_initializer (const C* name, const C* ns);
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/tree/stream-extraction-map.txx>
+
+#endif // XSD_CXX_TREE_STREAM_EXTRACTION_MAP_HXX
diff --git a/libxsd/xsd/cxx/tree/stream-extraction-map.txx b/libxsd/xsd/cxx/tree/stream-extraction-map.txx
new file mode 100644
index 0000000..5534da6
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/stream-extraction-map.txx
@@ -0,0 +1,294 @@
+// file : xsd/cxx/tree/stream-extraction-map.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd/cxx/tree/types.hxx>
+#include <xsd/cxx/tree/stream-extraction.hxx>
+#include <xsd/cxx/tree/bits/literals.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // stream_extraction_map
+ //
+ template <typename S, typename C>
+ stream_extraction_map<S, C>::
+ stream_extraction_map ()
+ {
+ // Register extractors for built-in non-fundamental types.
+ //
+ std::basic_string<C> xsd (bits::xml_schema<C> ());
+
+
+ // anyType and anySimpleType.
+ //
+ register_type (
+ qualified_name (bits::any_type<C> (), xsd),
+ &extractor_impl<S, type>,
+ false);
+
+ typedef simple_type<type> simple_type;
+ register_type (
+ qualified_name (bits::any_simple_type<C> (), xsd),
+ &extractor_impl<S, simple_type>,
+ false);
+
+
+ // Strings
+ //
+ typedef string<C, simple_type> string;
+ register_type (
+ qualified_name (bits::string<C> (), xsd),
+ &extractor_impl<S, string>,
+ false);
+
+ typedef normalized_string<C, string> normalized_string;
+ register_type (
+ qualified_name (bits::normalized_string<C> (), xsd),
+ &extractor_impl<S, normalized_string>,
+ false);
+
+ typedef token<C, normalized_string> token;
+ register_type (
+ qualified_name (bits::token<C> (), xsd),
+ &extractor_impl<S, token>,
+ false);
+
+ typedef name<C, token> name;
+ register_type (
+ qualified_name (bits::name<C> (), xsd),
+ &extractor_impl<S, name>,
+ false);
+
+ typedef nmtoken<C, token> nmtoken;
+ register_type (
+ qualified_name (bits::nmtoken<C> (), xsd),
+ &extractor_impl<S, nmtoken>,
+ false);
+
+ typedef nmtokens<C, simple_type, nmtoken> nmtokens;
+ register_type (
+ qualified_name (bits::nmtokens<C> (), xsd),
+ &extractor_impl<S, nmtokens>,
+ false);
+
+ typedef ncname<C, name> ncname;
+ register_type (
+ qualified_name (bits::ncname<C> (), xsd),
+ &extractor_impl<S, ncname>,
+ false);
+
+ typedef language<C, token> language;
+ register_type (
+ qualified_name (bits::language<C> (), xsd),
+ &extractor_impl<S, language>,
+ false);
+
+
+ // ID/IDREF.
+ //
+ typedef id<C, ncname> id;
+ register_type (
+ qualified_name (bits::id<C> (), xsd),
+ &extractor_impl<S, id>,
+ false);
+
+ typedef idref<type, C, ncname> idref;
+ register_type (
+ qualified_name (bits::idref<C> (), xsd),
+ &extractor_impl<S, idref>,
+ false);
+
+ typedef idrefs<C, simple_type, idref> idrefs;
+ register_type (
+ qualified_name (bits::idrefs<C> (), xsd),
+ &extractor_impl<S, idrefs>,
+ false);
+
+
+ // URI.
+ //
+ typedef uri<C, simple_type> uri;
+ register_type (
+ qualified_name (bits::any_uri<C> (), xsd),
+ &extractor_impl<S, uri>,
+ false);
+
+
+ // Qualified name.
+ //
+ typedef qname<C, simple_type, uri, ncname> qname;
+ register_type (
+ qualified_name (bits::qname<C> (), xsd),
+ &extractor_impl<S, qname>,
+ false);
+
+
+ // Binary.
+ //
+ typedef base64_binary<C, simple_type> base64_binary;
+ register_type (
+ qualified_name (bits::base64_binary<C> (), xsd),
+ &extractor_impl<S, base64_binary>,
+ false);
+
+ typedef hex_binary<C, simple_type> hex_binary;
+ register_type (
+ qualified_name (bits::hex_binary<C> (), xsd),
+ &extractor_impl<S, hex_binary>,
+ false);
+
+
+ // Date/time.
+ //
+ typedef gday<C, simple_type> gday;
+ register_type (
+ qualified_name (bits::gday<C> (), xsd),
+ &extractor_impl<S, gday>,
+ false);
+
+ typedef gmonth<C, simple_type> gmonth;
+ register_type (
+ qualified_name (bits::gmonth<C> (), xsd),
+ &extractor_impl<S, gmonth>,
+ false);
+
+ typedef gyear<C, simple_type> gyear;
+ register_type (
+ qualified_name (bits::gyear<C> (), xsd),
+ &extractor_impl<S, gyear>,
+ false);
+
+ typedef gmonth_day<C, simple_type> gmonth_day;
+ register_type (
+ qualified_name (bits::gmonth_day<C> (), xsd),
+ &extractor_impl<S, gmonth_day>,
+ false);
+
+ typedef gyear_month<C, simple_type> gyear_month;
+ register_type (
+ qualified_name (bits::gyear_month<C> (), xsd),
+ &extractor_impl<S, gyear_month>,
+ false);
+
+ typedef date<C, simple_type> date;
+ register_type (
+ qualified_name (bits::date<C> (), xsd),
+ &extractor_impl<S, date>,
+ false);
+
+ typedef time<C, simple_type> time;
+ register_type (
+ qualified_name (bits::time<C> (), xsd),
+ &extractor_impl<S, time>,
+ false);
+
+ typedef date_time<C, simple_type> date_time;
+ register_type (
+ qualified_name (bits::date_time<C> (), xsd),
+ &extractor_impl<S, date_time>,
+ false);
+
+ typedef duration<C, simple_type> duration;
+ register_type (
+ qualified_name (bits::duration<C> (), xsd),
+ &extractor_impl<S, duration>,
+ false);
+
+
+ // Entity.
+ //
+ typedef entity<C, ncname> entity;
+ register_type (
+ qualified_name (bits::entity<C> (), xsd),
+ &extractor_impl<S, entity>,
+ false);
+
+ typedef entities<C, simple_type, entity> entities;
+ register_type (
+ qualified_name (bits::entities<C> (), xsd),
+ &extractor_impl<S, entities>,
+ false);
+ }
+
+ template <typename S, typename C>
+ void stream_extraction_map<S, C>::
+ register_type (const qualified_name& name,
+ extractor e,
+ bool override)
+ {
+ if (override || type_map_.find (name) == type_map_.end ())
+ type_map_[name] = e;
+ }
+
+ template <typename S, typename C>
+ std::auto_ptr<type> stream_extraction_map<S, C>::
+ extract (istream<S>& s, flags f, container* c)
+ {
+ std::basic_string<C> name, ns;
+ s >> ns >> name;
+
+ if (extractor e = find (qualified_name (name, ns)))
+ {
+ return e (s, f, c);
+ }
+ else
+ throw no_type_info<C> (name, ns);
+ }
+
+ template <typename S, typename C>
+ typename stream_extraction_map<S, C>::extractor
+ stream_extraction_map<S, C>::
+ find (const qualified_name& name) const
+ {
+ typename type_map::const_iterator i (type_map_.find (name));
+ return i == type_map_.end () ? 0 : i->second;
+ }
+
+
+ // stream_extraction_plate
+ //
+ template<unsigned long id, typename S, typename C>
+ stream_extraction_plate<id, S, C>::
+ stream_extraction_plate ()
+ {
+ if (count == 0)
+ map = new stream_extraction_map<S, C>;
+
+ ++count;
+ }
+
+ template<unsigned long id, typename S, typename C>
+ stream_extraction_plate<id, S, C>::
+ ~stream_extraction_plate ()
+ {
+ if (--count == 0)
+ delete map;
+ }
+
+ //
+ //
+ template<typename S, typename T>
+ std::auto_ptr<type>
+ extractor_impl (istream<S>& s, flags f, container* c)
+ {
+ return std::auto_ptr<type> (new T (s, f, c));
+ }
+
+
+ // stream_extraction_initializer
+ //
+ template<unsigned long id, typename S, typename C, typename T>
+ stream_extraction_initializer<id, S, C, T>::
+ stream_extraction_initializer (const C* name, const C* ns)
+ {
+ stream_extraction_map_instance<id, S, C> ().register_type (
+ xml::qualified_name<C> (name, ns), &extractor_impl<S, T>);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/stream-extraction.hxx b/libxsd/xsd/cxx/tree/stream-extraction.hxx
new file mode 100644
index 0000000..861358d
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/stream-extraction.hxx
@@ -0,0 +1,303 @@
+// file : xsd/cxx/tree/stream-extraction.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_STREAM_EXTRACTION_HXX
+#define XSD_CXX_TREE_STREAM_EXTRACTION_HXX
+
+#include <xsd/cxx/tree/elements.hxx>
+#include <xsd/cxx/tree/types.hxx>
+#include <xsd/cxx/tree/list.hxx>
+
+#include <xsd/cxx/tree/istream.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // type
+ //
+ template <typename S>
+ inline _type::
+ _type (istream<S>&, flags, container* c)
+ : container_ (c)
+ {
+ }
+
+ // simple_type
+ //
+ template <typename B>
+ template <typename S>
+ inline simple_type<B>::
+ simple_type (istream<S>& s, flags f, container* c)
+ : type (s, f, c)
+ {
+ }
+
+ // fundamental_base
+ //
+ template <typename T, typename C, typename B, schema_type::value ST>
+ template <typename S>
+ inline fundamental_base<T, C, B, ST>::
+ fundamental_base (istream<S>& s, flags f, container* c)
+ : B (s, f, c), facet_table_ (0)
+ {
+ T& r (*this);
+ s >> r;
+ }
+
+ // list
+ //
+ template <typename T, typename C, schema_type::value ST>
+ template <typename S>
+ list<T, C, ST, false>::
+ list (istream<S>& s, flags f, container* c)
+ : sequence<T> (f, c)
+ {
+ std::size_t size;
+ istream_common::as_size<std::size_t> as_size (size);
+ s >> as_size;
+
+ if (size > 0)
+ {
+ this->reserve (size);
+
+ while (size--)
+ {
+ std::auto_ptr<T> p (new T (s, f, c));
+ push_back (p);
+ }
+ }
+ }
+
+ template <typename T, typename C, schema_type::value ST>
+ template <typename S>
+ list<T, C, ST, true>::
+ list (istream<S>& s, flags f, container* c)
+ : sequence<T> (f, c)
+ {
+ std::size_t size;
+ istream_common::as_size<std::size_t> as_size (size);
+ s >> as_size;
+
+ if (size > 0)
+ {
+ this->reserve (size);
+
+ while (size--)
+ {
+ T x;
+ s >> x;
+ push_back (x);
+ }
+ }
+ }
+
+ // Extraction operators for built-in types.
+ //
+
+
+ // string
+ //
+ template <typename C, typename B>
+ template <typename S>
+ inline string<C, B>::
+ string (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ std::basic_string<C>& r (*this);
+ s >> r;
+ }
+
+
+ // normalized_string
+ //
+ template <typename C, typename B>
+ template <typename S>
+ inline normalized_string<C, B>::
+ normalized_string (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ }
+
+
+ // token
+ //
+ template <typename C, typename B>
+ template <typename S>
+ inline token<C, B>::
+ token (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ }
+
+
+ // nmtoken
+ //
+ template <typename C, typename B>
+ template <typename S>
+ inline nmtoken<C, B>::
+ nmtoken (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ }
+
+
+ // nmtokens
+ //
+ template <typename C, typename B, typename nmtoken>
+ template <typename S>
+ inline nmtokens<C, B, nmtoken>::
+ nmtokens (istream<S>& s, flags f, container* c)
+ : B (s, f, c), base_type (s, f, c)
+ {
+ }
+
+
+ // name
+ //
+ template <typename C, typename B>
+ template <typename S>
+ inline name<C, B>::
+ name (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ }
+
+
+ // ncname
+ //
+ template <typename C, typename B>
+ template <typename S>
+ inline ncname<C, B>::
+ ncname (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ }
+
+
+ // language
+ //
+ template <typename C, typename B>
+ template <typename S>
+ inline language<C, B>::
+ language (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ }
+
+
+ // id
+ //
+ template <typename C, typename B>
+ template <typename S>
+ inline id<C, B>::
+ id (istream<S>& s, flags f, container* c)
+ : B (s, f, c), identity_ (*this)
+ {
+ register_id ();
+ }
+
+
+ // idref
+ //
+ template <typename T, typename C, typename B>
+ template <typename S>
+ inline idref<T, C, B>::
+ idref (istream<S>& s, flags f, container* c)
+ : B (s, f, c), identity_ (*this)
+ {
+ }
+
+
+ // idrefs
+ //
+ template <typename C, typename B, typename idref>
+ template <typename S>
+ inline idrefs<C, B, idref>::
+ idrefs (istream<S>& s, flags f, container* c)
+ : B (s, f, c), base_type (s, f, c)
+ {
+ }
+
+
+ // uri
+ //
+ template <typename C, typename B>
+ template <typename S>
+ inline uri<C, B>::
+ uri (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ std::basic_string<C>& r (*this);
+ s >> r;
+ }
+
+
+ // qname
+ //
+ template <typename C, typename B, typename uri, typename ncname>
+ template <typename S>
+ inline qname<C, B, uri, ncname>::
+ qname (istream<S>& s, flags f, container* c)
+ : B (s, f, c), ns_ (s), name_ (s)
+ {
+ }
+
+
+ // base64_binary
+ //
+ template <typename C, typename B>
+ template <typename S>
+ inline base64_binary<C, B>::
+ base64_binary (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ buffer<C>& r (*this);
+ s >> r;
+ }
+
+
+ // hex_binary
+ //
+ template <typename C, typename B>
+ template <typename S>
+ inline hex_binary<C, B>::
+ hex_binary (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ buffer<C>& r (*this);
+ s >> r;
+ }
+
+
+ // entity
+ //
+ template <typename C, typename B>
+ template <typename S>
+ inline entity<C, B>::
+ entity (istream<S>& s, flags f, container* c)
+ : B (s, f, c)
+ {
+ }
+
+
+ // entities
+ //
+ template <typename C, typename B, typename entity>
+ template <typename S>
+ inline entities<C, B, entity>::
+ entities (istream<S>& s, flags f, container* c)
+ : B (s, f, c), base_type (s, f, c)
+ {
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/tree/date-time-extraction.txx>
+
+#endif // XSD_CXX_TREE_STREAM_EXTRACTION_HXX
diff --git a/libxsd/xsd/cxx/tree/stream-insertion-map.hxx b/libxsd/xsd/cxx/tree/stream-insertion-map.hxx
new file mode 100644
index 0000000..77d930c
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/stream-insertion-map.hxx
@@ -0,0 +1,150 @@
+// file : xsd/cxx/tree/stream-insertion-map.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_STREAM_INSERTION_MAP_HXX
+#define XSD_CXX_TREE_STREAM_INSERTION_MAP_HXX
+
+#include <map>
+#include <string>
+#include <cstddef> // std::size_t
+#include <typeinfo>
+
+#include <xsd/cxx/tree/elements.hxx>
+#include <xsd/cxx/tree/ostream.hxx>
+#include <xsd/cxx/xml/qualified-name.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename S, typename C>
+ struct stream_insertion_map
+ {
+ typedef std::type_info type_id;
+ typedef xml::qualified_name<C> qualified_name;
+ typedef void (*inserter) (ostream<S>&, const type&);
+
+ stream_insertion_map ();
+
+ void
+ register_type (const type_id&,
+ const qualified_name& name,
+ inserter,
+ bool override = true);
+
+ void
+ insert (ostream<S>&, const type&);
+
+ public:
+ struct type_info
+ {
+ type_info (const qualified_name& name,
+ typename stream_insertion_map::inserter inserter)
+ : name_ (name), inserter_ (inserter)
+ {
+ }
+
+ const qualified_name&
+ name () const
+ {
+ return name_;
+ }
+
+ typename stream_insertion_map::inserter
+ inserter () const
+ {
+ return inserter_;
+ }
+
+ // For std::map.
+ //
+ type_info ()
+ : name_ (std::basic_string<C> (), std::basic_string<C> ()),
+ inserter_ (0)
+ {
+ }
+
+ private:
+ qualified_name name_;
+ typename stream_insertion_map::inserter inserter_;
+ };
+
+ public:
+ const type_info*
+ find (const type_id&) const;
+
+ private:
+ struct type_id_comparator
+ {
+ bool
+ operator() (const type_id* x, const type_id* y) const
+ {
+ // XL C++ on AIX has buggy type_info::before() in that
+ // it returns true for two different type_info objects
+ // that happened to be for the same type.
+ //
+#if defined(__xlC__) && defined(_AIX)
+ return *x != *y && x->before (*y);
+#else
+ return x->before (*y);
+#endif
+ }
+ };
+
+ typedef
+ std::map<const type_id*, type_info, type_id_comparator>
+ type_map;
+
+ type_map type_map_;
+ };
+
+ //
+ //
+ template<unsigned long id, typename S, typename C>
+ struct stream_insertion_plate
+ {
+ static stream_insertion_map<S, C>* map;
+ static std::size_t count;
+
+ stream_insertion_plate ();
+ ~stream_insertion_plate ();
+ };
+
+ template<unsigned long id, typename S, typename C>
+ stream_insertion_map<S, C>* stream_insertion_plate<id, S, C>::map = 0;
+
+ template<unsigned long id, typename S, typename C>
+ std::size_t stream_insertion_plate<id, S, C>::count = 0;
+
+
+ //
+ //
+ template<unsigned long id, typename S, typename C>
+ inline stream_insertion_map<S, C>&
+ stream_insertion_map_instance ()
+ {
+ return *stream_insertion_plate<id, S, C>::map;
+ }
+
+ //
+ //
+ template<typename S, typename T>
+ void
+ inserter_impl (ostream<S>&, const type&);
+
+ template<unsigned long id, typename S, typename C, typename T>
+ struct stream_insertion_initializer
+ {
+ stream_insertion_initializer (const C* name, const C* ns);
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/tree/stream-insertion-map.txx>
+
+#endif // XSD_CXX_TREE_STREAM_INSERTION_MAP_HXX
diff --git a/libxsd/xsd/cxx/tree/stream-insertion-map.txx b/libxsd/xsd/cxx/tree/stream-insertion-map.txx
new file mode 100644
index 0000000..c3cf9b5
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/stream-insertion-map.txx
@@ -0,0 +1,325 @@
+// file : xsd/cxx/tree/stream-insertion-map.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd/cxx/tree/types.hxx>
+#include <xsd/cxx/tree/stream-insertion.hxx>
+#include <xsd/cxx/tree/bits/literals.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // stream_insertion_map
+ //
+ template <typename S, typename C>
+ stream_insertion_map<S, C>::
+ stream_insertion_map ()
+ {
+ // Register inserters for built-in non-fundamental types.
+ //
+ std::basic_string<C> xsd (bits::xml_schema<C> ());
+
+
+ // anyType and anySimpleType.
+ //
+ register_type (
+ typeid (type),
+ qualified_name (bits::any_type<C> (), xsd),
+ &inserter_impl<S, type>,
+ false);
+
+ typedef simple_type<type> simple_type;
+ register_type (
+ typeid (simple_type),
+ qualified_name (bits::any_simple_type<C> (), xsd),
+ &inserter_impl<S, simple_type>,
+ false);
+
+
+ // Strings
+ //
+ typedef string<C, simple_type> string;
+ register_type (
+ typeid (string),
+ qualified_name (bits::string<C> (), xsd),
+ &inserter_impl<S, string>,
+ false);
+
+ typedef normalized_string<C, string> normalized_string;
+ register_type (
+ typeid (normalized_string),
+ qualified_name (bits::normalized_string<C> (), xsd),
+ &inserter_impl<S, normalized_string>,
+ false);
+
+ typedef token<C, normalized_string> token;
+ register_type (
+ typeid (token),
+ qualified_name (bits::token<C> (), xsd),
+ &inserter_impl<S, token>,
+ false);
+
+ typedef name<C, token> name;
+ register_type (
+ typeid (name),
+ qualified_name (bits::name<C> (), xsd),
+ &inserter_impl<S, name>,
+ false);
+
+ typedef nmtoken<C, token> nmtoken;
+ register_type (
+ typeid (nmtoken),
+ qualified_name (bits::nmtoken<C> (), xsd),
+ &inserter_impl<S, nmtoken>,
+ false);
+
+ typedef nmtokens<C, simple_type, nmtoken> nmtokens;
+ register_type (
+ typeid (nmtokens),
+ qualified_name (bits::nmtokens<C> (), xsd),
+ &inserter_impl<S, nmtokens>,
+ false);
+
+ typedef ncname<C, name> ncname;
+ register_type (
+ typeid (ncname),
+ qualified_name (bits::ncname<C> (), xsd),
+ &inserter_impl<S, ncname>,
+ false);
+
+ typedef language<C, token> language;
+ register_type (
+ typeid (language),
+ qualified_name (bits::language<C> (), xsd),
+ &inserter_impl<S, language>,
+ false);
+
+
+ // ID/IDREF.
+ //
+ typedef id<C, ncname> id;
+ register_type (
+ typeid (id),
+ qualified_name (bits::id<C> (), xsd),
+ &inserter_impl<S, id>,
+ false);
+
+ typedef idref<type, C, ncname> idref;
+ register_type (
+ typeid (idref),
+ qualified_name (bits::idref<C> (), xsd),
+ &inserter_impl<S, idref>,
+ false);
+
+ typedef idrefs<C, simple_type, idref> idrefs;
+ register_type (
+ typeid (idrefs),
+ qualified_name (bits::idrefs<C> (), xsd),
+ &inserter_impl<S, idrefs>,
+ false);
+
+
+ // URI.
+ //
+ typedef uri<C, simple_type> uri;
+ register_type (
+ typeid (uri),
+ qualified_name (bits::any_uri<C> (), xsd),
+ &inserter_impl<S, uri>,
+ false);
+
+
+ // Qualified name.
+ //
+ typedef qname<C, simple_type, uri, ncname> qname;
+ register_type (
+ typeid (qname),
+ qualified_name (bits::qname<C> (), xsd),
+ &inserter_impl<S, qname>,
+ false);
+
+
+ // Binary.
+ //
+ typedef base64_binary<C, simple_type> base64_binary;
+ register_type (
+ typeid (base64_binary),
+ qualified_name (bits::base64_binary<C> (), xsd),
+ &inserter_impl<S, base64_binary>,
+ false);
+
+ typedef hex_binary<C, simple_type> hex_binary;
+ register_type (
+ typeid (hex_binary),
+ qualified_name (bits::hex_binary<C> (), xsd),
+ &inserter_impl<S, hex_binary>,
+ false);
+
+
+ // Date/time.
+ //
+ typedef gday<C, simple_type> gday;
+ register_type (
+ typeid (gday),
+ qualified_name (bits::gday<C> (), xsd),
+ &inserter_impl<S, gday>,
+ false);
+
+ typedef gmonth<C, simple_type> gmonth;
+ register_type (
+ typeid (gmonth),
+ qualified_name (bits::gmonth<C> (), xsd),
+ &inserter_impl<S, gmonth>,
+ false);
+
+ typedef gyear<C, simple_type> gyear;
+ register_type (
+ typeid (gyear),
+ qualified_name (bits::gyear<C> (), xsd),
+ &inserter_impl<S, gyear>,
+ false);
+
+ typedef gmonth_day<C, simple_type> gmonth_day;
+ register_type (
+ typeid (gmonth_day),
+ qualified_name (bits::gmonth_day<C> (), xsd),
+ &inserter_impl<S, gmonth_day>,
+ false);
+
+ typedef gyear_month<C, simple_type> gyear_month;
+ register_type (
+ typeid (gyear_month),
+ qualified_name (bits::gyear_month<C> (), xsd),
+ &inserter_impl<S, gyear_month>,
+ false);
+
+ typedef date<C, simple_type> date;
+ register_type (
+ typeid (date),
+ qualified_name (bits::date<C> (), xsd),
+ &inserter_impl<S, date>,
+ false);
+
+ typedef time<C, simple_type> time;
+ register_type (
+ typeid (time),
+ qualified_name (bits::time<C> (), xsd),
+ &inserter_impl<S, time>,
+ false);
+
+ typedef date_time<C, simple_type> date_time;
+ register_type (
+ typeid (date_time),
+ qualified_name (bits::date_time<C> (), xsd),
+ &inserter_impl<S, date_time>,
+ false);
+
+ typedef duration<C, simple_type> duration;
+ register_type (
+ typeid (duration),
+ qualified_name (bits::duration<C> (), xsd),
+ &inserter_impl<S, duration>,
+ false);
+
+
+ // Entity.
+ //
+ typedef entity<C, ncname> entity;
+ register_type (
+ typeid (entity),
+ qualified_name (bits::entity<C> (), xsd),
+ &inserter_impl<S, entity>,
+ false);
+
+ typedef entities<C, simple_type, entity> entities;
+ register_type (
+ typeid (entities),
+ qualified_name (bits::entities<C> (), xsd),
+ &inserter_impl<S, entities>,
+ false);
+ }
+
+ template <typename S, typename C>
+ void stream_insertion_map<S, C>::
+ register_type (const type_id& tid,
+ const qualified_name& name,
+ inserter i,
+ bool override)
+ {
+ if (override || type_map_.find (&tid) == type_map_.end ())
+ type_map_[&tid] = type_info (name, i);
+ }
+
+ template <typename S, typename C>
+ void stream_insertion_map<S, C>::
+ insert (ostream<S>& s, const type& x)
+ {
+ if (const type_info* ti = find (typeid (x)))
+ {
+ const qualified_name& qn (ti->name ());
+
+ s << qn.namespace_ () << qn.name ();
+ ti->inserter () (s, x);
+ }
+ else
+ throw no_type_info<C> (std::basic_string<C> (),
+ std::basic_string<C> ()); // @@ TODO
+ }
+
+ template <typename S, typename C>
+ const typename stream_insertion_map<S, C>::type_info*
+ stream_insertion_map<S, C>::
+ find (const type_id& tid) const
+ {
+ typename type_map::const_iterator i (type_map_.find (&tid));
+ return i == type_map_.end () ? 0 : &i->second;
+ }
+
+
+ // stream_insertion_plate
+ //
+ template<unsigned long id, typename S, typename C>
+ stream_insertion_plate<id, S, C>::
+ stream_insertion_plate ()
+ {
+ if (count == 0)
+ map = new stream_insertion_map<S, C>;
+
+ ++count;
+ }
+
+ template<unsigned long id, typename S, typename C>
+ stream_insertion_plate<id, S, C>::
+ ~stream_insertion_plate ()
+ {
+ if (--count == 0)
+ delete map;
+ }
+
+ //
+ //
+ template<typename S, typename T>
+ void
+ inserter_impl (ostream<S>& s, const type& x)
+ {
+ s << static_cast<const T&> (x);
+ }
+
+ // stream_insertion_initializer
+ //
+ template<unsigned long id, typename S, typename C, typename T>
+ stream_insertion_initializer<id, S, C, T>::
+ stream_insertion_initializer (const C* name, const C* ns)
+ {
+ stream_insertion_map_instance<id, S, C> ().register_type (
+ typeid (T),
+ xml::qualified_name<C> (name, ns),
+ &inserter_impl<S, T>);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/stream-insertion.hxx b/libxsd/xsd/cxx/tree/stream-insertion.hxx
new file mode 100644
index 0000000..5b65bd6
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/stream-insertion.hxx
@@ -0,0 +1,273 @@
+// file : xsd/cxx/tree/stream-insertion.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_STREAM_INSERTION_HXX
+#define XSD_CXX_TREE_STREAM_INSERTION_HXX
+
+#include <xsd/cxx/tree/elements.hxx>
+#include <xsd/cxx/tree/types.hxx>
+#include <xsd/cxx/tree/list.hxx>
+
+#include <xsd/cxx/tree/ostream.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // type
+ //
+ template <typename S>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const type&)
+ {
+ return s;
+ }
+
+ // simple_type
+ //
+ template <typename S, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const simple_type<B>&)
+ {
+ return s;
+ }
+
+ // fundamental_base
+ //
+ template <typename S,
+ typename T,
+ typename C,
+ typename B,
+ schema_type::value ST>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const fundamental_base<T, C, B, ST>& x)
+ {
+ const T& r (x);
+ return s << r;
+ }
+
+ // list
+ //
+ template <typename S,
+ typename T,
+ typename C,
+ schema_type::value ST,
+ bool fund>
+ ostream<S>&
+ operator<< (ostream<S>& s, const list<T, C, ST, fund>& x)
+ {
+ s << ostream_common::as_size<std::size_t> (x.size ());
+
+ for (typename list<T, C, ST, fund>::const_iterator
+ i (x.begin ()), e (x.end ()); i != e; ++i)
+ {
+ s << *i;
+ }
+
+ return s;
+ }
+
+
+ // Insertion operators for built-in types.
+ //
+
+
+ // string
+ //
+ template <typename S, typename C, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const string<C, B>& x)
+ {
+ const std::basic_string<C>& r (x);
+ return s << r;
+ }
+
+
+ // normalized_string
+ //
+ template <typename S, typename C, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const normalized_string<C, B>& x)
+ {
+ const B& r (x);
+ return s << r;
+ }
+
+
+ // token
+ //
+ template <typename S, typename C, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const token<C, B>& x)
+ {
+ const B& r (x);
+ return s << r;
+ }
+
+
+ // nmtoken
+ //
+ template <typename S, typename C, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const nmtoken<C, B>& x)
+ {
+ const B& r (x);
+ return s << r;
+ }
+
+
+ // nmtokens
+ //
+ template <typename S, typename C, typename B, typename nmtoken>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const nmtokens<C, B, nmtoken>& x)
+ {
+ const list<nmtoken, C>& r (x);
+ return s << r;
+ }
+
+
+ // name
+ //
+ template <typename S, typename C, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const name<C, B>& x)
+ {
+ const B& r (x);
+ return s << r;
+ }
+
+
+ // ncname
+ //
+ template <typename S, typename C, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const ncname<C, B>& x)
+ {
+ const B& r (x);
+ return s << r;
+ }
+
+
+ // language
+ //
+ template <typename S, typename C, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const language<C, B>& x)
+ {
+ const std::basic_string<C>& r (x);
+ return s << r;
+ }
+
+
+ // id
+ //
+ template <typename S, typename C, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const id<C, B>& x)
+ {
+ const std::basic_string<C>& r (x);
+ return s << r;
+ }
+
+
+ // idref
+ //
+ template <typename S, typename T, typename C, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const idref<T, C, B>& x)
+ {
+ const B& r (x);
+ return s << r;
+ }
+
+
+ // idrefs
+ //
+ template <typename S, typename C, typename B, typename idref>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const idrefs<C, B, idref>& x)
+ {
+ const list<idref, C>& r (x);
+ return s << r;
+ }
+
+
+ // uri
+ //
+ template <typename S, typename C, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const uri<C, B>& x)
+ {
+ const std::basic_string<C>& r (x);
+ return s << r;
+ }
+
+
+ // qname
+ //
+ template <typename S,
+ typename C,
+ typename B,
+ typename uri,
+ typename ncname>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const qname<C, B, uri, ncname>& x)
+ {
+ return s << x.namespace_ () << x.name ();
+ }
+
+
+ // base64_binary
+ //
+ template <typename S, typename C, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const base64_binary<C, B>& x)
+ {
+ const buffer<C>& r (x);
+ return s << r;
+ }
+
+
+ // hex_binary
+ //
+ template <typename S, typename C, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const hex_binary<C, B>& x)
+ {
+ const buffer<C>& r (x);
+ return s << r;
+ }
+
+
+ // entity
+ //
+ template <typename S, typename C, typename B>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const entity<C, B>& x)
+ {
+ const B& r (x);
+ return s << r;
+ }
+
+
+ // entities
+ //
+ template <typename S, typename C, typename B, typename entity>
+ inline ostream<S>&
+ operator<< (ostream<S>& s, const entities<C, B, entity>& x)
+ {
+ const list<entity, C>& r (x);
+ return s << r;
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/tree/date-time-insertion.txx>
+
+#endif // XSD_CXX_TREE_STREAM_INSERTION_HXX
diff --git a/libxsd/xsd/cxx/tree/text.hxx b/libxsd/xsd/cxx/tree/text.hxx
new file mode 100644
index 0000000..5a08ec1
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/text.hxx
@@ -0,0 +1,30 @@
+// file : xsd/cxx/tree/text.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_TEXT_HXX
+#define XSD_CXX_TREE_TEXT_HXX
+
+#include <string>
+
+#include <xercesc/dom/DOMElement.hpp>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // Throws expected_text_content.
+ //
+ template <typename C>
+ std::basic_string<C>
+ text_content (const xercesc::DOMElement&);
+ }
+ }
+}
+
+#include <xsd/cxx/tree/text.txx>
+
+#endif // XSD_CXX_TREE_TEXT_HXX
diff --git a/libxsd/xsd/cxx/tree/text.txx b/libxsd/xsd/cxx/tree/text.txx
new file mode 100644
index 0000000..97e78ec
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/text.txx
@@ -0,0 +1,77 @@
+// file : xsd/cxx/tree/text.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xercesc/dom/DOMText.hpp>
+
+#include <xsd/cxx/xml/string.hxx>
+
+#include <xsd/cxx/tree/exceptions.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ std::basic_string<C>
+ text_content (const xercesc::DOMElement& e)
+ {
+ using xercesc::DOMNode;
+ using xercesc::DOMText;
+
+ DOMNode* n (e.getFirstChild ());
+
+ // Fast path.
+ //
+ if (n != 0 &&
+ n->getNodeType () == DOMNode::TEXT_NODE &&
+ n->getNextSibling () == 0)
+ {
+ DOMText* t (static_cast<DOMText*> (n));
+
+ // Berkeley DB XML DOM does not implement getLength().
+ //
+#ifndef DBXML_DOM
+ return xml::transcode<C> (t->getData (), t->getLength ());
+#else
+ return xml::transcode<C> (t->getData ());
+#endif
+ }
+
+ std::basic_string<C> r;
+
+ for (; n != 0; n = n->getNextSibling ())
+ {
+ switch (n->getNodeType ())
+ {
+ case DOMNode::TEXT_NODE:
+ case DOMNode::CDATA_SECTION_NODE:
+ {
+ DOMText* t (static_cast<DOMText*> (n));
+
+ // Berkeley DB XML DOM does not implement getLength().
+ //
+#ifndef DBXML_DOM
+ r += xml::transcode<C> (t->getData (), t->getLength ());
+#else
+ r += xml::transcode<C> (t->getData ());
+#endif
+ break;
+ }
+ case DOMNode::ELEMENT_NODE:
+ {
+ throw expected_text_content<C> ();
+ }
+ default:
+ break; // ignore
+ }
+ }
+
+ return r;
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/type-factory-map.hxx b/libxsd/xsd/cxx/tree/type-factory-map.hxx
new file mode 100644
index 0000000..8cf916e
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/type-factory-map.hxx
@@ -0,0 +1,151 @@
+// file : xsd/cxx/tree/type-factory-map.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_TYPE_FACTORY_MAP_HXX
+#define XSD_CXX_TREE_TYPE_FACTORY_MAP_HXX
+
+#include <map>
+#include <string>
+#include <memory> // std::auto_ptr
+#include <cstddef> // std::size_t
+
+#include <xercesc/dom/DOMElement.hpp>
+
+#include <xsd/cxx/tree/elements.hxx>
+#include <xsd/cxx/xml/qualified-name.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct type_factory_map
+ {
+ typedef xml::qualified_name<C> qualified_name;
+ typedef std::auto_ptr<type> (*factory) (const xercesc::DOMElement&,
+ flags,
+ container*);
+ public:
+ type_factory_map ();
+
+ void
+ register_type (const qualified_name& name,
+ factory,
+ bool override = true);
+
+ void
+ register_element (const qualified_name& root,
+ const qualified_name& subst,
+ factory);
+
+ std::auto_ptr<type>
+ create (const C* name, // element name
+ const C* ns, // element namespace
+ factory static_type,
+ bool global,
+ bool qualified,
+ const xercesc::DOMElement&,
+ const qualified_name&,
+ flags,
+ container*) const;
+
+ public:
+ factory
+ find (const qualified_name& name) const;
+
+ private:
+ template <typename T>
+ static std::auto_ptr<type>
+ traits_adapter (const xercesc::DOMElement&, flags, container*);
+
+ private:
+ typedef
+ std::map<qualified_name, factory>
+ type_map;
+
+ // Map of (root-element to map of (subst-element to factory)).
+ //
+ typedef
+ std::map<qualified_name, factory>
+ subst_map;
+
+ typedef
+ std::map<qualified_name, subst_map>
+ element_map;
+
+ type_map type_map_;
+ element_map element_map_;
+
+ private:
+ factory
+ find_substitution (const subst_map& start,
+ const qualified_name& name) const;
+
+ // The name argument is as specified in xsi:type.
+ //
+ factory
+ find_type (const std::basic_string<C>& name,
+ const xercesc::DOMElement&) const;
+ };
+
+
+ //
+ //
+ template<unsigned long id, typename C>
+ struct type_factory_plate
+ {
+ static type_factory_map<C>* map;
+ static std::size_t count;
+
+ type_factory_plate ();
+ ~type_factory_plate ();
+ };
+
+ template<unsigned long id, typename C>
+ type_factory_map<C>* type_factory_plate<id, C>::map = 0;
+
+ template<unsigned long id, typename C>
+ std::size_t type_factory_plate<id, C>::count = 0;
+
+
+ //
+ //
+ template<unsigned long id, typename C>
+ inline type_factory_map<C>&
+ type_factory_map_instance ()
+ {
+ return *type_factory_plate<id, C>::map;
+ }
+
+
+ //
+ //
+ template<typename T>
+ std::auto_ptr<type>
+ factory_impl (const xercesc::DOMElement&, flags, container*);
+
+ //
+ //
+ template<unsigned long id, typename C, typename T>
+ struct type_factory_initializer
+ {
+ // Register type.
+ //
+ type_factory_initializer (const C* name, const C* ns);
+
+ // Register element.
+ //
+ type_factory_initializer (const C* root_name, const C* root_ns,
+ const C* subst_name, const C* subst_ns);
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/tree/type-factory-map.txx>
+
+#endif // XSD_CXX_TREE_TYPE_FACTORY_MAP_HXX
diff --git a/libxsd/xsd/cxx/tree/type-factory-map.txx b/libxsd/xsd/cxx/tree/type-factory-map.txx
new file mode 100644
index 0000000..215f033
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/type-factory-map.txx
@@ -0,0 +1,436 @@
+// file : xsd/cxx/tree/type-factory-map.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xercesc/validators/schema/SchemaSymbols.hpp>
+
+#include <xsd/cxx/xml/string.hxx> // xml::{string, transcode}
+#include <xsd/cxx/xml/elements.hxx> // xml::{prefix, uq_name}
+#include <xsd/cxx/xml/bits/literals.hxx> // xml::bits::{xml_namespace, etc}
+
+#include <xsd/cxx/tree/types.hxx>
+#include <xsd/cxx/tree/bits/literals.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // type_factory_map
+ //
+ template <typename C>
+ type_factory_map<C>::
+ type_factory_map ()
+ {
+ // Register factories for default instantiations of built-in,
+ // non-fundamental types.
+ //
+
+ std::basic_string<C> xsd (bits::xml_schema<C> ());
+
+
+ // anyType and anySimpleType.
+ //
+ register_type (
+ qualified_name (bits::any_type<C> (), xsd),
+ &factory_impl<type>,
+ false);
+
+ typedef simple_type<type> simple_type;
+ register_type (
+ qualified_name (bits::any_simple_type<C> (), xsd),
+ &factory_impl<simple_type>,
+ false);
+
+
+ // Strings
+ //
+ typedef string<C, simple_type> string;
+ register_type (
+ qualified_name (bits::string<C> (), xsd),
+ &factory_impl<string>,
+ false);
+
+ typedef normalized_string<C, string> normalized_string;
+ register_type (
+ qualified_name (bits::normalized_string<C> (), xsd),
+ &factory_impl<normalized_string>,
+ false);
+
+ typedef token<C, normalized_string> token;
+ register_type (
+ qualified_name (bits::token<C> (), xsd),
+ &factory_impl<token>,
+ false);
+
+ typedef name<C, token> name;
+ register_type (
+ qualified_name (bits::name<C> (), xsd),
+ &factory_impl<name>,
+ false);
+
+ typedef nmtoken<C, token> nmtoken;
+ register_type (
+ qualified_name (bits::nmtoken<C> (), xsd),
+ &factory_impl<nmtoken>,
+ false);
+
+ typedef nmtokens<C, simple_type, nmtoken> nmtokens;
+ register_type (
+ qualified_name (bits::nmtokens<C> (), xsd),
+ &factory_impl<nmtokens>,
+ false);
+
+ typedef ncname<C, name> ncname;
+ register_type (
+ qualified_name (bits::ncname<C> (), xsd),
+ &factory_impl<ncname>,
+ false);
+
+ typedef language<C, token> language;
+ register_type (
+ qualified_name (bits::language<C> (), xsd),
+ &factory_impl<language>,
+ false);
+
+
+ // ID/IDREF.
+ //
+ typedef id<C, ncname> id;
+ register_type (
+ qualified_name (bits::id<C> (), xsd),
+ &factory_impl<id>,
+ false);
+
+ typedef idref<type, C, ncname> idref;
+ register_type (
+ qualified_name (bits::idref<C> (), xsd),
+ &factory_impl<idref>,
+ false);
+
+ typedef idrefs<C, simple_type, idref> idrefs;
+ register_type (
+ qualified_name (bits::idrefs<C> (), xsd),
+ &factory_impl<idrefs>,
+ false);
+
+
+ // URI.
+ //
+ typedef uri<C, simple_type> uri;
+ register_type (
+ qualified_name (bits::any_uri<C> (), xsd),
+ &factory_impl<uri>,
+ false);
+
+
+ // Qualified name.
+ //
+ typedef qname<C, simple_type, uri, ncname> qname;
+ register_type (
+ qualified_name (bits::qname<C> (), xsd),
+ &factory_impl<qname>,
+ false);
+
+
+ // Binary.
+ //
+ typedef base64_binary<C, simple_type> base64_binary;
+ register_type (
+ qualified_name (bits::base64_binary<C> (), xsd),
+ &factory_impl<base64_binary>,
+ false);
+
+ typedef hex_binary<C, simple_type> hex_binary;
+ register_type (
+ qualified_name (bits::hex_binary<C> (), xsd),
+ &factory_impl<hex_binary>,
+ false);
+
+
+ // Date/time.
+ //
+ typedef gday<C, simple_type> gday;
+ register_type (
+ qualified_name (bits::gday<C> (), xsd),
+ &factory_impl<gday>,
+ false);
+
+ typedef gmonth<C, simple_type> gmonth;
+ register_type (
+ qualified_name (bits::gmonth<C> (), xsd),
+ &factory_impl<gmonth>,
+ false);
+
+ typedef gyear<C, simple_type> gyear;
+ register_type (
+ qualified_name (bits::gyear<C> (), xsd),
+ &factory_impl<gyear>,
+ false);
+
+ typedef gmonth_day<C, simple_type> gmonth_day;
+ register_type (
+ qualified_name (bits::gmonth_day<C> (), xsd),
+ &factory_impl<gmonth_day>,
+ false);
+
+ typedef gyear_month<C, simple_type> gyear_month;
+ register_type (
+ qualified_name (bits::gyear_month<C> (), xsd),
+ &factory_impl<gyear_month>,
+ false);
+
+ typedef date<C, simple_type> date;
+ register_type (
+ qualified_name (bits::date<C> (), xsd),
+ &factory_impl<date>,
+ false);
+
+ typedef time<C, simple_type> time;
+ register_type (
+ qualified_name (bits::time<C> (), xsd),
+ &factory_impl<time>,
+ false);
+
+ typedef date_time<C, simple_type> date_time;
+ register_type (
+ qualified_name (bits::date_time<C> (), xsd),
+ &factory_impl<date_time>,
+ false);
+
+ typedef duration<C, simple_type> duration;
+ register_type (
+ qualified_name (bits::duration<C> (), xsd),
+ &factory_impl<duration>,
+ false);
+
+
+ // Entity.
+ //
+ typedef entity<C, ncname> entity;
+ register_type (
+ qualified_name (bits::entity<C> (), xsd),
+ &factory_impl<entity>,
+ false);
+
+ typedef entities<C, simple_type, entity> entities;
+ register_type (
+ qualified_name (bits::entities<C> (), xsd),
+ &factory_impl<entities>,
+ false);
+ }
+
+ template <typename C>
+ void type_factory_map<C>::
+ register_type (const qualified_name& name,
+ factory f,
+ bool override)
+ {
+ if (override || type_map_.find (name) == type_map_.end ())
+ type_map_[name] = f;
+ }
+
+ template <typename C>
+ void type_factory_map<C>::
+ register_element (const qualified_name& root,
+ const qualified_name& subst,
+ factory f)
+ {
+ element_map_[root][subst] = f;
+ }
+
+ template <typename C>
+ typename type_factory_map<C>::factory type_factory_map<C>::
+ find (const qualified_name& name) const
+ {
+ typename type_map::const_iterator i (type_map_.find (name));
+ return i == type_map_.end () ? 0 : i->second;
+ }
+
+ template <typename C>
+ std::auto_ptr<type> type_factory_map<C>::
+ create (const C* name,
+ const C* ns,
+ factory static_type,
+ bool global,
+ bool qualified,
+ const xercesc::DOMElement& e,
+ const qualified_name& qn,
+ tree::flags flags,
+ container* c) const
+ {
+ factory f = 0;
+
+ // See if we've got a straight match.
+ //
+ if (qn.name () == name &&
+ (qualified ? qn.namespace_ () == ns : ns[0] == C ('\0')))
+ {
+ f = static_type;
+ }
+ else if (global)
+ {
+ // See if we have a substitution.
+ //
+ typename element_map::const_iterator i (
+ element_map_.find (qualified_name (name, ns)));
+
+ if (i != element_map_.end ())
+ {
+ f = find_substitution (i->second, qn);
+ }
+ }
+
+ if (f == 0)
+ return std::auto_ptr<type> (0); // No match.
+
+ // Check for xsi:type
+ //
+ {
+ const XMLCh* v (
+ e.getAttributeNS (
+ xercesc::SchemaSymbols::fgURI_XSI,
+ xercesc::SchemaSymbols::fgXSI_TYPE));
+
+ if (v != 0 && v[0] != XMLCh (0))
+ f = find_type (xml::transcode<C> (v), e);
+ }
+
+ return f (e, flags, c);
+ }
+
+ template <typename C>
+ template <typename T>
+ std::auto_ptr<type> type_factory_map<C>::
+ traits_adapter (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ std::auto_ptr<T> r (traits<T, C>::create (e, f, c));
+ return std::auto_ptr<type> (r.release ());
+ }
+
+ template <typename C>
+ typename type_factory_map<C>::factory type_factory_map<C>::
+ find_substitution (const subst_map& start,
+ const qualified_name& name) const
+ {
+ typename subst_map::const_iterator i (start.find (name));
+
+ if (i != start.end ())
+ return i->second;
+ else
+ {
+ for (i = start.begin (); i != start.end (); ++i)
+ {
+ typename element_map::const_iterator j (
+ element_map_.find (i->first));
+
+ if (j != element_map_.end ())
+ {
+ if (factory f = find_substitution (j->second, name))
+ return f;
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ template <typename C>
+ typename type_factory_map<C>::factory type_factory_map<C>::
+ find_type (const std::basic_string<C>& name,
+ const xercesc::DOMElement& e) const
+ {
+ using std::basic_string;
+
+ basic_string<C> ns_name, uq_name (xml::uq_name (name));
+
+ // Copied with modifications from xml/dom/elements.hxx.
+ //
+ std::basic_string<C> p (xml::prefix (name));
+
+ // 'xml' prefix requires special handling and Xerces folks refuse
+ // to handle this in DOM so I have to do it myself.
+ //
+ if (p == xml::bits::xml_prefix<C> ())
+ ns_name = xml::bits::xml_namespace<C> ();
+ else
+ {
+ const XMLCh* xns (
+ e.lookupNamespaceURI (
+ p.empty () ? 0 : xml::string (p).c_str ()));
+
+ if (xns != 0)
+ ns_name = xml::transcode<C> (xns);
+ else
+ {
+ // See if we've got any no-namespace types.
+ //
+ if (!p.empty ())
+ throw no_prefix_mapping<C> (p);
+ }
+ }
+
+ factory f (find (qualified_name (uq_name, ns_name)));
+
+ if (f == 0)
+ throw no_type_info<C> (uq_name, ns_name);
+
+ return f;
+ }
+
+
+ // type_factory_plate
+ //
+ template<unsigned long id, typename C>
+ type_factory_plate<id, C>::
+ type_factory_plate ()
+ {
+ if (count == 0)
+ map = new type_factory_map<C>;
+
+ ++count;
+ }
+
+ template<unsigned long id, typename C>
+ type_factory_plate<id, C>::
+ ~type_factory_plate ()
+ {
+ if (--count == 0)
+ delete map;
+ }
+
+
+ //
+ //
+ template<typename T>
+ std::auto_ptr<type>
+ factory_impl (const xercesc::DOMElement& e, flags f, container* c)
+ {
+ return std::auto_ptr<type> (new T (e, f, c));
+ }
+
+ //
+ //
+ template<unsigned long id, typename C, typename T>
+ type_factory_initializer<id, C, T>::
+ type_factory_initializer (const C* name, const C* ns)
+ {
+ type_factory_map_instance<id, C> ().register_type (
+ xml::qualified_name<C> (name, ns), &factory_impl<T>);
+ }
+
+ template<unsigned long id, typename C, typename T>
+ type_factory_initializer<id, C, T>::
+ type_factory_initializer (const C* root_name, const C* root_ns,
+ const C* subst_name, const C* subst_ns)
+ {
+ type_factory_map_instance<id, C> ().register_element (
+ xml::qualified_name<C> (root_name, root_ns),
+ xml::qualified_name<C> (subst_name, subst_ns),
+ &factory_impl<T>);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/type-serializer-map.hxx b/libxsd/xsd/cxx/tree/type-serializer-map.hxx
new file mode 100644
index 0000000..b1ca479
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/type-serializer-map.hxx
@@ -0,0 +1,217 @@
+// file : xsd/cxx/tree/type-serializer-map.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_TYPE_SERIALIZER_MAP_HXX
+#define XSD_CXX_TREE_TYPE_SERIALIZER_MAP_HXX
+
+#include <map>
+#include <string>
+#include <cstddef> // std::size_t
+#include <typeinfo>
+
+#include <xercesc/dom/DOMElement.hpp>
+
+#include <xsd/cxx/tree/elements.hxx>
+
+#include <xsd/cxx/xml/qualified-name.hxx>
+#include <xsd/cxx/xml/dom/serialization-header.hxx> // namespace_infomap
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ template <typename C>
+ struct type_serializer_map
+ {
+ typedef std::type_info type_id;
+ typedef xml::qualified_name<C> qualified_name;
+ typedef void (*serializer) (xercesc::DOMElement&, const type&);
+
+ void
+ register_type (const type_id&,
+ const qualified_name& name,
+ serializer,
+ bool override = true);
+
+ void
+ register_element (const qualified_name& root,
+ const qualified_name& subst,
+ const type_id&,
+ serializer);
+
+ public:
+ void
+ serialize (const C* name, // element name
+ const C* ns, // element namespace
+ bool global,
+ bool qualified,
+ xercesc::DOMElement& parent,
+ const type&) const;
+
+ // Serialize into existing element.
+ //
+ void
+ serialize (const C* static_name,
+ const C* static_ns,
+ xercesc::DOMElement&,
+ const qualified_name&,
+ const type&) const;
+
+ // Create DOMDocument with root element suitable for serializing
+ // x into it.
+ //
+ xml::dom::auto_ptr<xercesc::DOMDocument>
+ serialize (const C* name, // element name
+ const C* ns, // element namespace
+ const xml::dom::namespace_infomap<C>&,
+ const type& x,
+ unsigned long flags) const;
+
+ public:
+ type_serializer_map ();
+
+ public:
+ struct type_info
+ {
+ type_info (const qualified_name& name,
+ typename type_serializer_map::serializer serializer)
+ : name_ (name), serializer_ (serializer)
+ {
+ }
+
+ const qualified_name&
+ name () const
+ {
+ return name_;
+ }
+
+ typename type_serializer_map::serializer
+ serializer () const
+ {
+ return serializer_;
+ }
+
+ // For std::map.
+ //
+ type_info ()
+ : name_ (std::basic_string<C> (), std::basic_string<C> ()),
+ serializer_ (0)
+ {
+ }
+
+ private:
+ qualified_name name_;
+ typename type_serializer_map::serializer serializer_;
+ };
+
+ public:
+ const type_info*
+ find (const type_id&) const;
+
+ private:
+ struct type_id_comparator
+ {
+ bool
+ operator() (const type_id* x, const type_id* y) const
+ {
+ // XL C++ on AIX has buggy type_info::before() in that
+ // it returns true for two different type_info objects
+ // that happened to be for the same type.
+ //
+#if defined(__xlC__) && defined(_AIX)
+ return *x != *y && x->before (*y);
+#else
+ return x->before (*y);
+#endif
+ }
+ };
+
+ typedef
+ std::map<const type_id*, type_info, type_id_comparator>
+ type_map;
+
+ // Map of (root-element to map of (type_id to type_info)).
+ // Note that here type_info::name is element name.
+ //
+ typedef
+ std::map<const type_id*, type_info, type_id_comparator>
+ subst_map;
+
+ typedef
+ std::map<qualified_name, subst_map>
+ element_map;
+
+ type_map type_map_;
+ element_map element_map_;
+
+ private:
+ const type_info*
+ find_substitution (const subst_map& start, const type_id&) const;
+
+ // Sets an xsi:type attribute corresponding to the type_info.
+ //
+ void
+ set_xsi_type (xercesc::DOMElement& parent,
+ xercesc::DOMElement&,
+ const type_info&) const;
+ };
+
+
+ //
+ //
+ template<unsigned long id, typename C>
+ struct type_serializer_plate
+ {
+ static type_serializer_map<C>* map;
+ static std::size_t count;
+
+ type_serializer_plate ();
+ ~type_serializer_plate ();
+ };
+
+ template<unsigned long id, typename C>
+ type_serializer_map<C>* type_serializer_plate<id, C>::map = 0;
+
+ template<unsigned long id, typename C>
+ std::size_t type_serializer_plate<id, C>::count = 0;
+
+
+ //
+ //
+ template<unsigned long id, typename C>
+ inline type_serializer_map<C>&
+ type_serializer_map_instance ()
+ {
+ return *type_serializer_plate<id, C>::map;
+ }
+
+ //
+ //
+ template<typename T>
+ void
+ serializer_impl (xercesc::DOMElement&, const type&);
+
+
+ template<unsigned long id, typename C, typename T>
+ struct type_serializer_initializer
+ {
+ // Register type.
+ //
+ type_serializer_initializer (const C* name, const C* ns);
+
+ // Register element.
+ //
+ type_serializer_initializer (const C* root_name, const C* root_ns,
+ const C* subst_name, const C* subst_ns);
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/tree/type-serializer-map.txx>
+
+#endif // XSD_CXX_TREE_TYPE_SERIALIZER_MAP_HXX
diff --git a/libxsd/xsd/cxx/tree/type-serializer-map.txx b/libxsd/xsd/cxx/tree/type-serializer-map.txx
new file mode 100644
index 0000000..797cb13
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/type-serializer-map.txx
@@ -0,0 +1,539 @@
+// file : xsd/cxx/tree/type-serializer-map.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xercesc/util/XMLUni.hpp>
+#include <xercesc/validators/schema/SchemaSymbols.hpp>
+
+#include <xsd/cxx/xml/bits/literals.hxx> // xml::bits::{xsi_namespace, type}
+#include <xsd/cxx/xml/dom/serialization-source.hxx> // dom::{create_*, prefix}
+
+#include <xsd/cxx/tree/types.hxx>
+#include <xsd/cxx/tree/bits/literals.hxx>
+
+#include <iostream>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // type_serializer_map
+ //
+ template <typename C>
+ type_serializer_map<C>::
+ type_serializer_map ()
+ {
+ // Register serializers for built-in non-fundamental types.
+ //
+ std::basic_string<C> xsd (bits::xml_schema<C> ());
+
+
+ // anyType and anySimpleType.
+ //
+ register_type (
+ typeid (type),
+ qualified_name (bits::any_type<C> (), xsd),
+ &serializer_impl<type>,
+ false);
+
+ typedef simple_type<type> simple_type;
+ register_type (
+ typeid (simple_type),
+ qualified_name (bits::any_simple_type<C> (), xsd),
+ &serializer_impl<simple_type>,
+ false);
+
+
+ // Strings
+ //
+ typedef string<C, simple_type> string;
+ register_type (
+ typeid (string),
+ qualified_name (bits::string<C> (), xsd),
+ &serializer_impl<string>,
+ false);
+
+ typedef normalized_string<C, string> normalized_string;
+ register_type (
+ typeid (normalized_string),
+ qualified_name (bits::normalized_string<C> (), xsd),
+ &serializer_impl<normalized_string>,
+ false);
+
+ typedef token<C, normalized_string> token;
+ register_type (
+ typeid (token),
+ qualified_name (bits::token<C> (), xsd),
+ &serializer_impl<token>,
+ false);
+
+ typedef name<C, token> name;
+ register_type (
+ typeid (name),
+ qualified_name (bits::name<C> (), xsd),
+ &serializer_impl<name>,
+ false);
+
+ typedef nmtoken<C, token> nmtoken;
+ register_type (
+ typeid (nmtoken),
+ qualified_name (bits::nmtoken<C> (), xsd),
+ &serializer_impl<nmtoken>,
+ false);
+
+ typedef nmtokens<C, simple_type, nmtoken> nmtokens;
+ register_type (
+ typeid (nmtokens),
+ qualified_name (bits::nmtokens<C> (), xsd),
+ &serializer_impl<nmtokens>,
+ false);
+
+ typedef ncname<C, name> ncname;
+ register_type (
+ typeid (ncname),
+ qualified_name (bits::ncname<C> (), xsd),
+ &serializer_impl<ncname>,
+ false);
+
+ typedef language<C, token> language;
+ register_type (
+ typeid (language),
+ qualified_name (bits::language<C> (), xsd),
+ &serializer_impl<language>,
+ false);
+
+
+ // ID/IDREF.
+ //
+ typedef id<C, ncname> id;
+ register_type (
+ typeid (id),
+ qualified_name (bits::id<C> (), xsd),
+ &serializer_impl<id>,
+ false);
+
+ typedef idref<type, C, ncname> idref;
+ register_type (
+ typeid (idref),
+ qualified_name (bits::idref<C> (), xsd),
+ &serializer_impl<idref>,
+ false);
+
+ typedef idrefs<C, simple_type, idref> idrefs;
+ register_type (
+ typeid (idrefs),
+ qualified_name (bits::idrefs<C> (), xsd),
+ &serializer_impl<idrefs>,
+ false);
+
+
+ // URI.
+ //
+ typedef uri<C, simple_type> uri;
+ register_type (
+ typeid (uri),
+ qualified_name (bits::any_uri<C> (), xsd),
+ &serializer_impl<uri>,
+ false);
+
+
+ // Qualified name.
+ //
+ typedef qname<C, simple_type, uri, ncname> qname;
+ register_type (
+ typeid (qname),
+ qualified_name (bits::qname<C> (), xsd),
+ &serializer_impl<qname>,
+ false);
+
+
+ // Binary.
+ //
+ typedef base64_binary<C, simple_type> base64_binary;
+ register_type (
+ typeid (base64_binary),
+ qualified_name (bits::base64_binary<C> (), xsd),
+ &serializer_impl<base64_binary>,
+ false);
+
+ typedef hex_binary<C, simple_type> hex_binary;
+ register_type (
+ typeid (hex_binary),
+ qualified_name (bits::hex_binary<C> (), xsd),
+ &serializer_impl<hex_binary>,
+ false);
+
+
+ // Date/time.
+ //
+ typedef gday<C, simple_type> gday;
+ register_type (
+ typeid (gday),
+ qualified_name (bits::gday<C> (), xsd),
+ &serializer_impl<gday>,
+ false);
+
+ typedef gmonth<C, simple_type> gmonth;
+ register_type (
+ typeid (gmonth),
+ qualified_name (bits::gmonth<C> (), xsd),
+ &serializer_impl<gmonth>,
+ false);
+
+ typedef gyear<C, simple_type> gyear;
+ register_type (
+ typeid (gyear),
+ qualified_name (bits::gyear<C> (), xsd),
+ &serializer_impl<gyear>,
+ false);
+
+ typedef gmonth_day<C, simple_type> gmonth_day;
+ register_type (
+ typeid (gmonth_day),
+ qualified_name (bits::gmonth_day<C> (), xsd),
+ &serializer_impl<gmonth_day>,
+ false);
+
+ typedef gyear_month<C, simple_type> gyear_month;
+ register_type (
+ typeid (gyear_month),
+ qualified_name (bits::gyear_month<C> (), xsd),
+ &serializer_impl<gyear_month>,
+ false);
+
+ typedef date<C, simple_type> date;
+ register_type (
+ typeid (date),
+ qualified_name (bits::date<C> (), xsd),
+ &serializer_impl<date>,
+ false);
+
+ typedef time<C, simple_type> time;
+ register_type (
+ typeid (time),
+ qualified_name (bits::time<C> (), xsd),
+ &serializer_impl<time>,
+ false);
+
+ typedef date_time<C, simple_type> date_time;
+ register_type (
+ typeid (date_time),
+ qualified_name (bits::date_time<C> (), xsd),
+ &serializer_impl<date_time>,
+ false);
+
+ typedef duration<C, simple_type> duration;
+ register_type (
+ typeid (duration),
+ qualified_name (bits::duration<C> (), xsd),
+ &serializer_impl<duration>,
+ false);
+
+
+ // Entity.
+ //
+ typedef entity<C, ncname> entity;
+ register_type (
+ typeid (entity),
+ qualified_name (bits::entity<C> (), xsd),
+ &serializer_impl<entity>,
+ false);
+
+ typedef entities<C, simple_type, entity> entities;
+ register_type (
+ typeid (entities),
+ qualified_name (bits::entities<C> (), xsd),
+ &serializer_impl<entities>,
+ false);
+ }
+
+ template <typename C>
+ void type_serializer_map<C>::
+ register_type (const type_id& tid,
+ const qualified_name& name,
+ serializer s,
+ bool override)
+ {
+ if (override || type_map_.find (&tid) == type_map_.end ())
+ type_map_[&tid] = type_info (name, s);
+ }
+
+ template <typename C>
+ void type_serializer_map<C>::
+ register_element (const qualified_name& root,
+ const qualified_name& subst,
+ const type_id& tid,
+ serializer s)
+ {
+ element_map_[root][&tid] = type_info (subst, s);
+ }
+
+ template <typename C>
+ void type_serializer_map<C>::
+ serialize (const C* name, // element name
+ const C* ns, // element namespace
+ bool global,
+ bool qualified,
+ xercesc::DOMElement& parent,
+ const type& x) const
+ {
+ const type_id& tid (typeid (x));
+
+ // First see if we can find a substitution.
+ //
+ if (global)
+ {
+ typename element_map::const_iterator i (
+ element_map_.find (qualified_name (name, ns)));
+
+ if (i != element_map_.end ())
+ {
+ if (const type_info* ti = find_substitution (i->second, tid))
+ {
+ xercesc::DOMElement& e (
+ xml::dom::create_element (
+ ti->name ().name ().c_str (),
+ ti->name ().namespace_ ().c_str (),
+ parent));
+
+ ti->serializer () (e, x);
+ return;
+ }
+ }
+ }
+
+ // The last resort is xsi:type.
+ //
+ if (const type_info* ti = find (tid))
+ {
+ xercesc::DOMElement& e (
+ qualified
+ ? xml::dom::create_element (name, ns, parent)
+ : xml::dom::create_element (name, parent));
+
+ ti->serializer () (e, x);
+ set_xsi_type (parent, e, *ti);
+ return;
+ }
+
+ throw no_type_info<C> (std::basic_string<C> (),
+ std::basic_string<C> ()); //@@ TODO
+ }
+
+ template <typename C>
+ void type_serializer_map<C>::
+ serialize (const C* static_name,
+ const C* static_ns,
+ xercesc::DOMElement& e,
+ const qualified_name& qn,
+ const type& x) const
+ {
+ const type_id& tid (typeid (x));
+
+ // First see if this is a substitution.
+ //
+ if (qn.name () != static_name || qn.namespace_ () != static_ns)
+ {
+ typename element_map::const_iterator i (
+ element_map_.find (qualified_name (static_name, static_ns)));
+
+ if (i != element_map_.end ())
+ {
+ if (const type_info* ti = find_substitution (i->second, tid))
+ {
+ if (ti->name ().name () != qn.name () ||
+ ti->name ().namespace_ () != qn.namespace_ ())
+ {
+ throw unexpected_element<C> (
+ qn.name (), qn.namespace_ (),
+ ti->name ().name (), ti->name ().namespace_ ());
+ }
+
+ ti->serializer () (e, x);
+ return;
+ }
+ }
+
+ // This is not a valid substitution.
+ //
+ throw unexpected_element<C> (qn.name (), qn.namespace_ (),
+ static_name, static_ns);
+ }
+
+ // The last resort is xsi:type.
+ //
+ if (const type_info* ti = find (tid))
+ {
+ ti->serializer () (e, x);
+ set_xsi_type (e, e, *ti);
+ return;
+ }
+
+ throw no_type_info<C> (std::basic_string<C> (),
+ std::basic_string<C> ()); //@@ TODO
+ }
+
+ template <typename C>
+ xml::dom::auto_ptr<xercesc::DOMDocument> type_serializer_map<C>::
+ serialize (const C* name,
+ const C* ns,
+ const xml::dom::namespace_infomap<C>& m,
+ const type& x,
+ unsigned long flags) const
+ {
+ const type_id& tid (typeid (x));
+
+ // See if we can find a substitution.
+ //
+ {
+ typename element_map::const_iterator i (
+ element_map_.find (qualified_name (name, ns)));
+
+ if (i != element_map_.end ())
+ {
+ if (const type_info* ti = find_substitution (i->second, tid))
+ {
+ return xml::dom::serialize<C> (
+ ti->name ().name (), ti->name ().namespace_ (), m, flags);
+ }
+ }
+ }
+
+ // If there is no substitution then serialize() will have to
+ // find suitable xsi:type.
+ //
+ return xml::dom::serialize<C> (name, ns, m, flags);
+ }
+
+ template <typename C>
+ const typename type_serializer_map<C>::type_info*
+ type_serializer_map<C>::
+ find (const type_id& tid) const
+ {
+ typename type_map::const_iterator i (type_map_.find (&tid));
+ return i == type_map_.end () ? 0 : &i->second;
+ }
+
+ template <typename C>
+ const typename type_serializer_map<C>::type_info*
+ type_serializer_map<C>::
+ find_substitution (const subst_map& start, const type_id& tid) const
+ {
+ typename subst_map::const_iterator i (start.find (&tid));
+
+ if (i != start.end ())
+ return &i->second;
+ else
+ {
+ for (i = start.begin (); i != start.end (); ++i)
+ {
+ typename element_map::const_iterator j (
+ element_map_.find (i->second.name ()));
+
+ if (j != element_map_.end ())
+ {
+ if (const type_info* ti = find_substitution (j->second, tid))
+ return ti;
+ }
+ }
+ }
+
+ return 0;
+ }
+
+ template <typename C>
+ void type_serializer_map<C>::
+ set_xsi_type (xercesc::DOMElement& parent,
+ xercesc::DOMElement& e,
+ const type_info& ti) const
+ {
+ std::basic_string<C> id;
+ const std::basic_string<C>& ns (ti.name ().namespace_ ());
+
+ if (!ns.empty ())
+ {
+ id = xml::dom::prefix (ns, e);
+
+ if (!id.empty ())
+ id += C (':');
+ }
+
+ id += ti.name ().name ();
+
+ std::basic_string<C> name = xml::dom::prefix (
+ xml::bits::xsi_namespace<C> (), parent, xml::bits::xsi_prefix<C> ());
+
+ if (!name.empty ())
+ name += C (':');
+
+ name += xml::bits::type<C> ();
+
+ e.setAttributeNS (
+ xercesc::SchemaSymbols::fgURI_XSI,
+ xml::string (name).c_str (),
+ xml::string (id).c_str ());
+ }
+
+
+ // type_serializer_plate
+ //
+ template<unsigned long id, typename C>
+ type_serializer_plate<id, C>::
+ type_serializer_plate ()
+ {
+ if (count == 0)
+ map = new type_serializer_map<C>;
+
+ ++count;
+ }
+
+ template<unsigned long id, typename C>
+ type_serializer_plate<id, C>::
+ ~type_serializer_plate ()
+ {
+ if (--count == 0)
+ delete map;
+ }
+
+
+ //
+ //
+ template<typename T>
+ void
+ serializer_impl (xercesc::DOMElement& e, const type& x)
+ {
+ e << static_cast<const T&> (x);
+ }
+
+
+ // type_serializer_initializer
+ //
+ template<unsigned long id, typename C, typename T>
+ type_serializer_initializer<id, C, T>::
+ type_serializer_initializer (const C* name, const C* ns)
+ {
+ type_serializer_map_instance<id, C> ().register_type (
+ typeid (T),
+ xml::qualified_name<C> (name, ns),
+ &serializer_impl<T>);
+ }
+
+ template<unsigned long id, typename C, typename T>
+ type_serializer_initializer<id, C, T>::
+ type_serializer_initializer (const C* root_name,
+ const C* root_ns,
+ const C* subst_name,
+ const C* subst_ns)
+ {
+ type_serializer_map_instance<id, C> ().register_element (
+ xml::qualified_name<C> (root_name, root_ns),
+ xml::qualified_name<C> (subst_name, subst_ns),
+ typeid (T),
+ &serializer_impl<T>);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/types.hxx b/libxsd/xsd/cxx/tree/types.hxx
new file mode 100644
index 0000000..20bcbe4
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/types.hxx
@@ -0,0 +1,3788 @@
+// file : xsd/cxx/tree/types.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+/**
+ * @file
+ *
+ * @brief Contains C++ class definitions for XML Schema built-in types.
+ *
+ * This is an internal header and is included by the generated code. You
+ * normally should not include it directly.
+ *
+ */
+
+#ifndef XSD_CXX_TREE_TYPES_HXX
+#define XSD_CXX_TREE_TYPES_HXX
+
+#include <string>
+#include <cstddef> // std::size_t
+
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMElement.hpp>
+
+#include <xsd/cxx/tree/elements.hxx>
+#include <xsd/cxx/tree/list.hxx>
+#include <xsd/cxx/tree/buffer.hxx>
+#include <xsd/cxx/tree/istream-fwd.hxx>
+
+#include <xsd/cxx/tree/date-time.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ /**
+ * @brief C++/Tree mapping runtime namespace.
+ *
+ * This is an internal namespace and normally should not be referenced
+ * directly. Instead you should use the aliases for types in this
+ * namespaces that are created in the generated code.
+ *
+ */
+ namespace tree
+ {
+ /**
+ * @brief Class corresponding to the XML Schema %string built-in
+ * type.
+ *
+ * The %string class publicly inherits from and has the same set
+ * of constructors as @c std::basic_string. It therefore can be
+ * used as @c std::string (or @c std::wstring if you are using
+ * @c wchar_t as the character type).
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class string: public B, public std::basic_string<C>
+ {
+ typedef std::basic_string<C> base_type;
+
+ base_type&
+ base ()
+ {
+ return *this;
+ }
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Default constructor creates an empty %string.
+ */
+ string ()
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a C %string.
+ *
+ * @param s A C %string to copy.
+ */
+ string (const C* s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a character array.
+ *
+ * @param s A character array to copy.
+ * @param n A number of character to copy.
+ */
+ string (const C* s, std::size_t n)
+ : base_type (s, n)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with multiple copies of the same
+ * character.
+ *
+ * @param n A number of copies to create.
+ * @param c A character to copy.
+ */
+ string (std::size_t n, C c)
+ : base_type (n, c)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a standard %string.
+ *
+ * @param s A standard %string to copy.
+ */
+ string (const std::basic_string<C>& s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a substring.
+ *
+ * @param s A standard %string to copy the substring from.
+ * @param pos An index of the first character to copy from.
+ * @param n A number of characters to copy.
+ */
+ string (const std::basic_string<C>& s,
+ std::size_t pos,
+ std::size_t n = std::basic_string<C>::npos)
+ : base_type (s, pos, n)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ string (const string& x, flags f = 0, container* c = 0)
+ : B (x, f, c), base_type (x)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual string*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ string (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ string (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ string (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ string (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Assign a character to the instance.
+ *
+ * The resulting %string has only one character.
+ *
+ * @param c A character to assign.
+ * @return A reference to the instance.
+ */
+ string&
+ operator= (C c)
+ {
+ base () = c;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a C %string to the instance.
+ *
+ * The resulting %string contains a copy of the C %string.
+ *
+ * @param s A C %string to assign.
+ * @return A reference to the instance.
+ */
+ string&
+ operator= (const C* s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a standard %string to the instance.
+ *
+ * The resulting %string contains a copy of the standard %string.
+ *
+ * @param s A standard %string to assign.
+ * @return A reference to the instance.
+ */
+ string&
+ operator= (const std::basic_string<C>& s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ string&
+ operator= (const string& x)
+ {
+ base () = x;
+ return *this;
+ }
+ };
+
+
+ /**
+ * @brief Class corresponding to the XML Schema normalizedString
+ * built-in type.
+ *
+ * The %normalized_string class publicly inherits from and has
+ * the same set of constructors as @c std::basic_string. It
+ * therefore can be used as @c std::string (or @c std::wstring
+ * if you are using @c wchar_t as the character type).
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class normalized_string: public B
+ {
+ typedef B base_type;
+
+ base_type&
+ base ()
+ {
+ return *this;
+ }
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Default constructor creates an empty %normalized_string.
+ */
+ normalized_string ()
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a C %string.
+ *
+ * @param s A C %string to copy.
+ */
+ normalized_string (const C* s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a character array.
+ *
+ * @param s A character array to copy.
+ * @param n A number of character to copy.
+ */
+ normalized_string (const C* s, std::size_t n)
+ : base_type (s, n)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with multiple copies of the same
+ * character.
+ *
+ * @param n A number of copies to create.
+ * @param c A character to copy.
+ */
+ normalized_string (std::size_t n, C c)
+ : base_type (n, c)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a standard %string.
+ *
+ * @param s A standard %string to copy.
+ */
+ normalized_string (const std::basic_string<C>& s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a substring.
+ *
+ * @param s A standard %string to copy the substring from.
+ * @param pos An index of the first character to copy from.
+ * @param n A number of characters to copy.
+ */
+ normalized_string (const std::basic_string<C>& s,
+ std::size_t pos,
+ std::size_t n = std::basic_string<C>::npos)
+ : base_type (s, pos, n)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ normalized_string (const normalized_string& x,
+ flags f = 0,
+ container* c = 0)
+ : base_type (x, f, c)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual normalized_string*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ normalized_string (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ normalized_string (const xercesc::DOMElement& e,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ normalized_string (const xercesc::DOMAttr& a,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ normalized_string (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Assign a character to the instance.
+ *
+ * The resulting %normalized_string has only one character.
+ *
+ * @param c A character to assign.
+ * @return A reference to the instance.
+ */
+ normalized_string&
+ operator= (C c)
+ {
+ base () = c;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a C %string to the instance.
+ *
+ * The resulting %normalized_string contains a copy of the C %string.
+ *
+ * @param s A C %string to assign.
+ * @return A reference to the instance.
+ */
+ normalized_string&
+ operator= (const C* s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a standard %string to the instance.
+ *
+ * The resulting %normalized_string contains a copy of the standard
+ * %string.
+ *
+ * @param s A standard %string to assign.
+ * @return A reference to the instance.
+ */
+ normalized_string&
+ operator= (const std::basic_string<C>& s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ normalized_string&
+ operator= (const normalized_string& x)
+ {
+ base () = x;
+ return *this;
+ }
+
+ protected:
+ //@cond
+
+ void
+ normalize ();
+
+ //@endcond
+ };
+
+
+ /**
+ * @brief Class corresponding to the XML Schema %token built-in
+ * type.
+ *
+ * The %token class publicly inherits from and has the same set
+ * of constructors as @c std::basic_string. It therefore can be
+ * used as @c std::string (or @c std::wstring if you are using
+ * @c wchar_t as the character type).
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class token: public B
+ {
+ typedef B base_type;
+
+ base_type&
+ base ()
+ {
+ return *this;
+ }
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Default constructor creates an empty %token.
+ */
+ token ()
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a C %string.
+ *
+ * @param s A C %string to copy.
+ */
+ token (const C* s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a character array.
+ *
+ * @param s A character array to copy.
+ * @param n A number of character to copy.
+ */
+ token (const C* s, std::size_t n)
+ : base_type (s, n)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with multiple copies of the same
+ * character.
+ *
+ * @param n A number of copies to create.
+ * @param c A character to copy.
+ */
+ token (std::size_t n, C c)
+ : base_type (n, c)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a standard %string.
+ *
+ * @param s A standard %string to copy.
+ */
+ token (const std::basic_string<C>& s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a substring.
+ *
+ * @param s A standard %string to copy the substring from.
+ * @param pos An index of the first character to copy from.
+ * @param n A number of characters to copy.
+ */
+ token (const std::basic_string<C>& s,
+ std::size_t pos,
+ std::size_t n = std::basic_string<C>::npos)
+ : base_type (s, pos, n)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ token (const token& x, flags f = 0, container* c = 0)
+ : base_type (x, f, c)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual token*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ token (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ token (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ token (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ token (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Assign a character to the instance.
+ *
+ * The resulting %token has only one character.
+ *
+ * @param c A character to assign.
+ * @return A reference to the instance.
+ */
+ token&
+ operator= (C c)
+ {
+ base () = c;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a C %string to the instance.
+ *
+ * The resulting %token contains a copy of the C %string.
+ *
+ * @param s A C %string to assign.
+ * @return A reference to the instance.
+ */
+ token&
+ operator= (const C* s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a standard %string to the instance.
+ *
+ * The resulting %token contains a copy of the standard %string.
+ *
+ * @param s A standard %string to assign.
+ * @return A reference to the instance.
+ */
+ token&
+ operator= (const std::basic_string<C>& s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ token&
+ operator= (const token& x)
+ {
+ base () = x;
+ return *this;
+ }
+
+ protected:
+ //@cond
+
+ void
+ collapse ();
+
+ //@endcond
+ };
+
+
+ /**
+ * @brief Class corresponding to the XML Schema NMTOKEN built-in
+ * type.
+ *
+ * The %nmtoken class publicly inherits from and has the same set
+ * of constructors as @c std::basic_string. It therefore can be
+ * used as @c std::string (or @c std::wstring if you are using
+ * @c wchar_t as the character type).
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class nmtoken: public B
+ {
+ typedef B base_type;
+
+ base_type&
+ base ()
+ {
+ return *this;
+ }
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with a copy of a C %string.
+ *
+ * @param s A C %string to copy.
+ */
+ nmtoken (const C* s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a character array.
+ *
+ * @param s A character array to copy.
+ * @param n A number of character to copy.
+ */
+ nmtoken (const C* s, std::size_t n)
+ : base_type (s, n)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with multiple copies of the same
+ * character.
+ *
+ * @param n A number of copies to create.
+ * @param c A character to copy.
+ */
+ nmtoken (std::size_t n, C c)
+ : base_type (n, c)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a standard %string.
+ *
+ * @param s A standard %string to copy.
+ */
+ nmtoken (const std::basic_string<C>& s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a substring.
+ *
+ * @param s A standard %string to copy the substring from.
+ * @param pos An index of the first character to copy from.
+ * @param n A number of characters to copy.
+ */
+ nmtoken (const std::basic_string<C>& s,
+ std::size_t pos,
+ std::size_t n = std::basic_string<C>::npos)
+ : base_type (s, pos, n)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ nmtoken (const nmtoken& x, flags f = 0, container* c = 0)
+ : base_type (x, f, c)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual nmtoken*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ nmtoken (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ nmtoken (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ nmtoken (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ nmtoken (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Assign a character to the instance.
+ *
+ * The resulting %nmtoken has only one character.
+ *
+ * @param c A character to assign.
+ * @return A reference to the instance.
+ */
+ nmtoken&
+ operator= (C c)
+ {
+ base () = c;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a C %string to the instance.
+ *
+ * The resulting %nmtoken contains a copy of the C %string.
+ *
+ * @param s A C %string to assign.
+ * @return A reference to the instance.
+ */
+ nmtoken&
+ operator= (const C* s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a standard %string to the instance.
+ *
+ * The resulting %nmtoken contains a copy of the standard %string.
+ *
+ * @param s A standard %string to assign.
+ * @return A reference to the instance.
+ */
+ nmtoken&
+ operator= (const std::basic_string<C>& s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ nmtoken&
+ operator= (const nmtoken& x)
+ {
+ base () = x;
+ return *this;
+ }
+
+ protected:
+ //@cond
+
+ nmtoken ()
+ : base_type ()
+ {
+ }
+
+ //@endcond
+ };
+
+
+ /**
+ * @brief Class corresponding to the XML Schema NMTOKENS built-in
+ * type.
+ *
+ * The %nmtokens class is a vector (or %list in XML Schema terminology)
+ * of nmtoken elements. It is implemented in terms of the list class
+ * template.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B, typename nmtoken>
+ class nmtokens: public B, public list<nmtoken, C>
+ {
+ typedef list<nmtoken, C> base_type;
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Default constructor creates no elements.
+ */
+ nmtokens ()
+ {
+ }
+
+ /**
+ * @brief Initialize the instance with copies of an exemplar elements.
+ *
+ * @param n A number of elements to copy.
+ * @param x An exemplar element to copy.
+ */
+ nmtokens (typename base_type::size_type n, const nmtoken& x)
+ : base_type (n, x)
+ {
+ }
+
+ /**
+ * @brief Initialize the instance with copies of elements from an
+ * iterator range.
+ *
+ * @param begin An iterator pointing to the first element.
+ * @param end An iterator pointing to the one past the last element.
+ */
+ template <typename I>
+ nmtokens (const I& begin, const I& end)
+ : base_type (begin, end)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ nmtokens (const nmtokens& x, flags f, container* c = 0)
+ : B (x, f, c), base_type (x, f, c)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual nmtokens*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ nmtokens (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ nmtokens (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ nmtokens (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ nmtokens (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+ };
+
+
+ /**
+ * @brief Class corresponding to the XML Schema Name built-in
+ * type.
+ *
+ * The %name class publicly inherits from and has the same set
+ * of constructors as @c std::basic_string. It therefore can be
+ * used as @c std::string (or @c std::wstring if you are using
+ * @c wchar_t as the character type).
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class name: public B
+ {
+ typedef B base_type;
+
+ base_type&
+ base ()
+ {
+ return *this;
+ }
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with a copy of a C %string.
+ *
+ * @param s A C %string to copy.
+ */
+ name (const C* s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a character array.
+ *
+ * @param s A character array to copy.
+ * @param n A number of character to copy.
+ */
+ name (const C* s, std::size_t n)
+ : base_type (s, n)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with multiple copies of the same
+ * character.
+ *
+ * @param n A number of copies to create.
+ * @param c A character to copy.
+ */
+ name (std::size_t n, C c)
+ : base_type (n, c)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a standard %string.
+ *
+ * @param s A standard %string to copy.
+ */
+ name (const std::basic_string<C>& s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a substring.
+ *
+ * @param s A standard %string to copy the substring from.
+ * @param pos An index of the first character to copy from.
+ * @param n A number of characters to copy.
+ */
+ name (const std::basic_string<C>& s,
+ std::size_t pos,
+ std::size_t n = std::basic_string<C>::npos)
+ : base_type (s, pos, n)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ name (const name& x, flags f = 0, container* c = 0)
+ : base_type (x, f, c)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual name*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ name (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ name (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ name (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ name (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Assign a character to the instance.
+ *
+ * The resulting %name has only one character.
+ *
+ * @param c A character to assign.
+ * @return A reference to the instance.
+ */
+ name&
+ operator= (C c)
+ {
+ base () = c;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a C %string to the instance.
+ *
+ * The resulting %name contains a copy of the C %string.
+ *
+ * @param s A C %string to assign.
+ * @return A reference to the instance.
+ */
+ name&
+ operator= (const C* s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a standard %string to the instance.
+ *
+ * The resulting %name contains a copy of the standard %string.
+ *
+ * @param s A standard %string to assign.
+ * @return A reference to the instance.
+ */
+ name&
+ operator= (const std::basic_string<C>& s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ name&
+ operator= (const name& x)
+ {
+ base () = x;
+ return *this;
+ }
+
+ protected:
+ //@cond
+
+ name ()
+ : base_type ()
+ {
+ }
+
+ //@endcond
+ };
+
+
+ // Forward declaration for Sun CC.
+ //
+ template <typename C, typename B, typename uri, typename ncname>
+ class qname;
+
+
+ /**
+ * @brief Class corresponding to the XML Schema NCame built-in
+ * type.
+ *
+ * The %ncname class publicly inherits from and has the same set
+ * of constructors as @c std::basic_string. It therefore can be
+ * used as @c std::string (or @c std::wstring if you are using
+ * @c wchar_t as the character type).
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class ncname: public B
+ {
+ typedef B base_type;
+
+ base_type&
+ base ()
+ {
+ return *this;
+ }
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with a copy of a C %string.
+ *
+ * @param s A C %string to copy.
+ */
+ ncname (const C* s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a character array.
+ *
+ * @param s A character array to copy.
+ * @param n A number of character to copy.
+ */
+ ncname (const C* s, std::size_t n)
+ : base_type (s, n)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with multiple copies of the same
+ * character.
+ *
+ * @param n A number of copies to create.
+ * @param c A character to copy.
+ */
+ ncname (std::size_t n, C c)
+ : base_type (n, c)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a standard %string.
+ *
+ * @param s A standard %string to copy.
+ */
+ ncname (const std::basic_string<C>& s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a substring.
+ *
+ * @param s A standard %string to copy the substring from.
+ * @param pos An index of the first character to copy from.
+ * @param n A number of characters to copy.
+ */
+ ncname (const std::basic_string<C>& s,
+ std::size_t pos,
+ std::size_t n = std::basic_string<C>::npos)
+ : base_type (s, pos, n)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ ncname (const ncname& x, flags f = 0, container* c = 0)
+ : base_type (x, f, c)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual ncname*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ ncname (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ ncname (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ ncname (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ ncname (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Assign a character to the instance.
+ *
+ * The resulting %ncname has only one character.
+ *
+ * @param c A character to assign.
+ * @return A reference to the instance.
+ */
+ ncname&
+ operator= (C c)
+ {
+ base () = c;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a C %string to the instance.
+ *
+ * The resulting %ncname contains a copy of the C %string.
+ *
+ * @param s A C %string to assign.
+ * @return A reference to the instance.
+ */
+ ncname&
+ operator= (const C* s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a standard %string to the instance.
+ *
+ * The resulting %ncname contains a copy of the standard %string.
+ *
+ * @param s A standard %string to assign.
+ * @return A reference to the instance.
+ */
+ ncname&
+ operator= (const std::basic_string<C>& s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ ncname&
+ operator= (const ncname& x)
+ {
+ base () = x;
+ return *this;
+ }
+
+ protected:
+ //@cond
+
+ ncname ()
+ : base_type ()
+ {
+ }
+
+ //@endcond
+
+ template <typename, typename, typename, typename>
+ friend class qname;
+ };
+
+
+ /**
+ * @brief Class corresponding to the XML Schema %language built-in
+ * type.
+ *
+ * The %language class publicly inherits from and has the same set
+ * of constructors as @c std::basic_string. It therefore can be
+ * used as @c std::string (or @c std::wstring if you are using
+ * @c wchar_t as the character type).
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class language: public B
+ {
+ typedef B base_type;
+
+ base_type&
+ base ()
+ {
+ return *this;
+ }
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with a copy of a C %string.
+ *
+ * @param s A C %string to copy.
+ */
+ language (const C* s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a character array.
+ *
+ * @param s A character array to copy.
+ * @param n A number of character to copy.
+ */
+ language (const C* s, std::size_t n)
+ : base_type (s, n)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with multiple copies of the same
+ * character.
+ *
+ * @param n A number of copies to create.
+ * @param c A character to copy.
+ */
+ language (std::size_t n, C c)
+ : base_type (n, c)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a standard %string.
+ *
+ * @param s A standard %string to copy.
+ */
+ language (const std::basic_string<C>& s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a substring.
+ *
+ * @param s A standard %string to copy the substring from.
+ * @param pos An index of the first character to copy from.
+ * @param n A number of characters to copy.
+ */
+ language (const std::basic_string<C>& s,
+ std::size_t pos,
+ std::size_t n = std::basic_string<C>::npos)
+ : base_type (s, pos, n)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ language (const language& x, flags f = 0, container* c = 0)
+ : base_type (x, f, c)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual language*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ language (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ language (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ language (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ language (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Assign a character to the instance.
+ *
+ * The resulting %language has only one character.
+ *
+ * @param c A character to assign.
+ * @return A reference to the instance.
+ */
+ language&
+ operator= (C c)
+ {
+ base () = c;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a C %string to the instance.
+ *
+ * The resulting %language contains a copy of the C %string.
+ *
+ * @param s A C %string to assign.
+ * @return A reference to the instance.
+ */
+ language&
+ operator= (const C* s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a standard %string to the instance.
+ *
+ * The resulting %language contains a copy of the standard %string.
+ *
+ * @param s A standard %string to assign.
+ * @return A reference to the instance.
+ */
+ language&
+ operator= (const std::basic_string<C>& s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ language&
+ operator= (const language& x)
+ {
+ base () = x;
+ return *this;
+ }
+
+ protected:
+ //@cond
+
+ language ()
+ : base_type ()
+ {
+ }
+
+ //@endcond
+ };
+
+
+ //@cond
+
+ template <typename C, typename ncname>
+ struct identity_impl: identity
+ {
+ identity_impl (const ncname& id)
+ : id_ (id)
+ {
+ }
+
+ virtual bool
+ before (const identity& y) const;
+
+ virtual void
+ throw_duplicate_id () const;
+
+ private:
+ const ncname& id_;
+ };
+
+ //@endcond
+
+
+ /**
+ * @brief Class corresponding to the XML Schema ID built-in
+ * type.
+ *
+ * The %id class publicly inherits from and has the same set
+ * of constructors as @c std::basic_string. It therefore can be
+ * used as @c std::string (or @c std::wstring if you are using
+ * @c wchar_t as the character type).
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class id: public B
+ {
+ typedef B base_type;
+
+ base_type&
+ base ()
+ {
+ return *this;
+ }
+
+ public:
+ ~id()
+ {
+ unregister_id ();
+ }
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with a copy of a C %string.
+ *
+ * @param s A C %string to copy.
+ */
+ id (const C* s)
+ : base_type (s), identity_ (*this)
+ {
+ register_id ();
+ }
+
+ /**
+ * @brief Initialize an instance with a character array.
+ *
+ * @param s A character array to copy.
+ * @param n A number of character to copy.
+ */
+ id (const C* s, std::size_t n)
+ : base_type (s, n), identity_ (*this)
+ {
+ register_id ();
+ }
+
+ /**
+ * @brief Initialize an instance with multiple copies of the same
+ * character.
+ *
+ * @param n A number of copies to create.
+ * @param c A character to copy.
+ */
+ id (std::size_t n, C c)
+ : base_type (n, c), identity_ (*this)
+ {
+ register_id ();
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a standard %string.
+ *
+ * @param s A standard %string to copy.
+ */
+ id (const std::basic_string<C>& s)
+ : base_type (s), identity_ (*this)
+ {
+ register_id ();
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a substring.
+ *
+ * @param s A standard %string to copy the substring from.
+ * @param pos An index of the first character to copy from.
+ * @param n A number of characters to copy.
+ */
+ id (const std::basic_string<C>& s,
+ std::size_t pos,
+ std::size_t n = std::basic_string<C>::npos)
+ : base_type (s, pos, n), identity_ (*this)
+ {
+ register_id ();
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ id (const id& x, flags f = 0, container* c = 0)
+ : base_type (x, f, c), identity_ (*this)
+ {
+ register_id ();
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual id*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ id (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ id (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ id (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ id (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Assign a character to the instance.
+ *
+ * The resulting %id has only one character.
+ *
+ * @param c A character to assign.
+ * @return A reference to the instance.
+ */
+ id&
+ operator= (C c);
+
+
+ /**
+ * @brief Assign a C %string to the instance.
+ *
+ * The resulting %id contains a copy of the C %string.
+ *
+ * @param s A C %string to assign.
+ * @return A reference to the instance.
+ */
+ id&
+ operator= (const C* s);
+
+ /**
+ * @brief Assign a standard %string to the instance.
+ *
+ * The resulting %id contains a copy of the standard %string.
+ *
+ * @param s A standard %string to assign.
+ * @return A reference to the instance.
+ */
+ id&
+ operator= (const std::basic_string<C>& s);
+
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ id&
+ operator= (const id& x);
+
+ public:
+ //@cond
+
+ virtual void
+ _container (container*);
+
+ // The above override also hides other _container versions. We
+ // also cannot do using-declarations because of bugs in HP aCC3.
+ //
+ const container*
+ _container () const
+ {
+ return B::_container ();
+ }
+
+ container*
+ _container ()
+ {
+ return B::_container ();
+ }
+
+ //@endcond
+
+ protected:
+ //@cond
+
+ id ()
+ : base_type (), identity_ (*this)
+ {
+ register_id ();
+ }
+
+ //@endcond
+
+ private:
+ void
+ register_id ();
+
+ void
+ unregister_id ();
+
+ private:
+ identity_impl<C, B> identity_;
+ };
+
+
+ /**
+ * @brief Class corresponding to the XML Schema IDREF built-in
+ * type.
+ *
+ * The %idref class publicly inherits from and has the same set
+ * of constructors as @c std::basic_string. It therefore can be
+ * used as @c std::string (or @c std::wstring if you are using
+ * @c wchar_t as the character type).
+ *
+ * The %idref class also provides an autopointer-like interface
+ * for resolving referenced objects. By default the object is
+ * returned as type (mapping for anyType) but statically-typed
+ * %idref can be created using the XML Schema extension. See the
+ * C++/Tree Mapping User Manual for more information.
+ *
+ * @nosubgrouping
+ */
+ template <typename T, typename C, typename B>
+ class idref: public B
+ {
+ typedef B base_type;
+
+ base_type&
+ base ()
+ {
+ return *this;
+ }
+
+ public:
+ /**
+ * @brief Referenced type.
+ */
+ typedef T ref_type;
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with a copy of a C %string.
+ *
+ * @param s A C %string to copy.
+ */
+ idref (const C* s)
+ : base_type (s), identity_ (*this)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a character array.
+ *
+ * @param s A character array to copy.
+ * @param n A number of character to copy.
+ */
+ idref (const C* s, std::size_t n)
+ : base_type (s, n), identity_ (*this)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with multiple copies of the same
+ * character.
+ *
+ * @param n A number of copies to create.
+ * @param c A character to copy.
+ */
+ idref (std::size_t n, C c)
+ : base_type (n, c), identity_ (*this)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a standard %string.
+ *
+ * @param s A standard %string to copy.
+ */
+ idref (const std::basic_string<C>& s)
+ : base_type (s), identity_ (*this)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a substring.
+ *
+ * @param s A standard %string to copy the substring from.
+ * @param pos An index of the first character to copy from.
+ * @param n A number of characters to copy.
+ */
+ idref (const std::basic_string<C>& s,
+ std::size_t pos,
+ std::size_t n = std::basic_string<C>::npos)
+ : base_type (s, pos, n), identity_ (*this)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ idref (const idref& x, flags f = 0, container* c = 0)
+ : base_type (x, f, c), identity_ (*this)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual idref*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ idref (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ idref (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ idref (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ idref (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Assign a character to the instance.
+ *
+ * The resulting %idref has only one character.
+ *
+ * @param c A character to assign.
+ * @return A reference to the instance.
+ */
+ idref&
+ operator= (C c)
+ {
+ base () = c;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a C %string to the instance.
+ *
+ * The resulting %idref contains a copy of the C %string.
+ *
+ * @param s A C %string to assign.
+ * @return A reference to the instance.
+ */
+ idref&
+ operator= (const C* s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a standard %string to the instance.
+ *
+ * The resulting %idref contains a copy of the standard %string.
+ *
+ * @param s A standard %string to assign.
+ * @return A reference to the instance.
+ */
+ idref&
+ operator= (const std::basic_string<C>& s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ idref&
+ operator= (const idref& x)
+ {
+ base () = x;
+ return *this;
+ }
+
+ public:
+ /**
+ * @brief Call referenced object.
+ *
+ * @return A constant pointer to the referenced object.
+ */
+ const ref_type*
+ operator-> () const
+ {
+ return get ();
+ }
+
+ /**
+ * @brief Call referenced object.
+ *
+ * @return A pointer to the referenced object.
+ */
+ ref_type*
+ operator-> ()
+ {
+ return get ();
+ }
+
+ /**
+ * @brief Dereference referenced object.
+ *
+ * @return A constant C++ reference to the referenced object.
+ */
+ const ref_type&
+ operator* () const
+ {
+ return *(get ());
+ }
+
+ /**
+ * @brief Dereference referenced object.
+ *
+ * @return A C++ reference to the referenced object.
+ */
+ ref_type&
+ operator* ()
+ {
+ return *(get ());
+ }
+
+ /**
+ * @brief Get a constant pointer to the referenced object.
+ *
+ * @return A constant pointer to the referenced object or 0 if
+ * the object is not found.
+ */
+ const ref_type*
+ get () const
+ {
+ return dynamic_cast<const ref_type*> (get_ ());
+ }
+
+ /**
+ * @brief Get a pointer to the referenced object.
+ *
+ * @return A pointer to the referenced object or 0 if the object
+ * is not found.
+ */
+ ref_type*
+ get ()
+ {
+ return dynamic_cast<ref_type*> (get_ ());
+ }
+
+ /**
+ * @brief Opaque type that can be evaluated as true or false.
+ */
+ typedef void (idref::*bool_convertible)();
+
+ /**
+ * @brief Implicit conversion to boolean type.
+ *
+ * @return True if the referenced object is found, false otherwise.
+ */
+ operator bool_convertible () const
+ {
+ return get_ () ? &idref::true_ : 0;
+ }
+
+ protected:
+ //@cond
+
+ idref ()
+ : base_type (), identity_ (*this)
+ {
+ }
+
+ //@endcond
+
+ private:
+ const _type*
+ get_ () const;
+
+ _type*
+ get_ ();
+
+ void
+ true_ ();
+
+ private:
+ identity_impl<C, B> identity_;
+ };
+
+
+ /**
+ * @brief Class corresponding to the XML Schema IDREFS built-in
+ * type.
+ *
+ * The %idrefs class is a vector (or %list in XML Schema terminology)
+ * of idref elements. It is implemented in terms of the list class
+ * template.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B, typename idref>
+ class idrefs: public B, public list<idref, C>
+ {
+ typedef list<idref, C> base_type;
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Default constructor creates no elements.
+ */
+ idrefs ()
+ {
+ }
+
+ /**
+ * @brief Initialize the instance with copies of an exemplar elements.
+ *
+ * @param n A number of elements to copy.
+ * @param x An exemplar element to copy.
+ */
+ idrefs (typename base_type::size_type n, const idref& x)
+ : base_type (n, x)
+ {
+ }
+
+ /**
+ * @brief Initialize the instance with copies of elements from an
+ * iterator range.
+ *
+ * @param begin An iterator pointing to the first element.
+ * @param end An iterator pointing to the one past the last element.
+ */
+ template <typename I>
+ idrefs (const I& begin, const I& end)
+ : base_type (begin, end)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ idrefs (const idrefs& x, flags f = 0, container* c = 0)
+ : B (x, f, c), base_type (x, f, c)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual idrefs*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ idrefs (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ idrefs (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ idrefs (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ idrefs (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+ };
+
+
+ /**
+ * @brief Class corresponding to the XML Schema anyURI built-in
+ * type.
+ *
+ * The %uri class publicly inherits from and has the same set
+ * of constructors as @c std::basic_string. It therefore can be
+ * used as @c std::string (or @c std::wstring if you are using
+ * @c wchar_t as the character type).
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class uri: public B, public std::basic_string<C>
+ {
+ typedef std::basic_string<C> base_type;
+
+ base_type&
+ base ()
+ {
+ return *this;
+ }
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with a copy of a C %string.
+ *
+ * @param s A C %string to copy.
+ */
+ uri (const C* s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a character array.
+ *
+ * @param s A character array to copy.
+ * @param n A number of character to copy.
+ */
+ uri (const C* s, std::size_t n)
+ : base_type (s, n)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with multiple copies of the same
+ * character.
+ *
+ * @param n A number of copies to create.
+ * @param c A character to copy.
+ */
+ uri (std::size_t n, C c)
+ : base_type (n, c)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a standard %string.
+ *
+ * @param s A standard %string to copy.
+ */
+ uri (const std::basic_string<C>& s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a substring.
+ *
+ * @param s A standard %string to copy the substring from.
+ * @param pos An index of the first character to copy from.
+ * @param n A number of characters to copy.
+ */
+ uri (const std::basic_string<C>& s,
+ std::size_t pos,
+ std::size_t n = std::basic_string<C>::npos)
+ : base_type (s, pos, n)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ uri (const uri& x, flags f = 0, container* c = 0)
+ : B (x, f, c), base_type (x)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual uri*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ uri (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ uri (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ uri (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ uri (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Assign a character to the instance.
+ *
+ * The resulting %uri has only one character.
+ *
+ * @param c A character to assign.
+ * @return A reference to the instance.
+ */
+ uri&
+ operator= (C c)
+ {
+ base () = c;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a C %string to the instance.
+ *
+ * The resulting %uri contains a copy of the C %string.
+ *
+ * @param s A C %string to assign.
+ * @return A reference to the instance.
+ */
+ uri&
+ operator= (const C* s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a standard %string to the instance.
+ *
+ * The resulting %uri contains a copy of the standard %string.
+ *
+ * @param s A standard %string to assign.
+ * @return A reference to the instance.
+ */
+ uri&
+ operator= (const std::basic_string<C>& s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ uri&
+ operator= (const uri& x)
+ {
+ base () = x;
+ return *this;
+ }
+
+ protected:
+ //@cond
+
+ uri ()
+ : base_type ()
+ {
+ }
+
+ //@endcond
+
+ template <typename, typename, typename, typename>
+ friend class qname;
+ };
+
+
+ /**
+ * @brief Class corresponding to the XML Schema QName built-in
+ * type.
+ *
+ * The %qname class represents a potentially namespace-qualified
+ * XML %name.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B, typename uri, typename ncname>
+ class qname: public B
+ {
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with a %name only.
+ *
+ * The resulting %qname is unqualified.
+ *
+ * @param n An XML %name (ncname).
+ */
+ qname (const ncname& n)
+ : ns_ (), name_ (n)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a %name and a namespace.
+ *
+ * The resulting %qname is qualified.
+ *
+ * @param ns An XML namespace (uri).
+ * @param n An XML %name (ncname).
+ */
+ qname (const uri& ns, const ncname& n)
+ : ns_ (ns), name_ (n)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ qname (const qname& x, flags f = 0, container* c = 0)
+ : B (x, f, c),
+ ns_ (x.ns_),
+ name_ (x.name_)
+ {
+ // Note that ns_ and name_ have no DOM association.
+ //
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual qname*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ qname (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ qname (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ qname (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ qname (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Determine if the %name is qualified.
+ *
+ * @return True if the %name is qualified, false otherwise.
+ */
+ bool
+ qualified () const
+ {
+ return !ns_.empty ();
+ }
+
+ /**
+ * @brief Get XML namespace.
+ *
+ * @return A constant reference to qualifying XML namespace.
+ */
+ const uri&
+ namespace_ () const
+ {
+ return ns_;
+ }
+
+ /**
+ * @brief Get XML %name.
+ *
+ * @return A constant reference to unqualified XML %name.
+ */
+ const ncname&
+ name () const
+ {
+ return name_;
+ }
+
+ protected:
+ //@cond
+
+ qname ()
+ : ns_ (), name_ ()
+ {
+ }
+
+ //@endcond
+
+ private:
+ static uri
+ resolve (const std::basic_string<C>&, const xercesc::DOMElement*);
+
+ private:
+ uri ns_;
+ ncname name_;
+ };
+
+ /**
+ * @brief %qname comparison operator.
+ *
+ * @return True if the names are equal, false otherwise.
+ */
+ template <typename C, typename B, typename uri, typename ncname>
+ inline bool
+ operator== (const qname<C, B, uri, ncname>& a,
+ const qname<C, B, uri, ncname>& b)
+ {
+ return a.name () == b.name () && a.namespace_ () == b.namespace_ ();
+ }
+
+ /**
+ * @brief %qname comparison operator.
+ *
+ * @return True if the names are not equal, false otherwise.
+ */
+ template <typename C, typename B, typename uri, typename ncname>
+ inline bool
+ operator!= (const qname<C, B, uri, ncname>& a,
+ const qname<C, B, uri, ncname>& b)
+ {
+ return !(a == b);
+ }
+
+
+ /**
+ * @brief Class corresponding to the XML Schema base64Binary
+ * built-in type.
+ *
+ * The %base64_binary class is a binary %buffer abstraction with
+ * base64-encoded representation in XML. It publicly inherits from
+ * the buffer class which provides the %buffer functionality.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class base64_binary: public B, public buffer<C>
+ {
+ public:
+ typedef typename buffer<C>::size_t size_t;
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Allocate a %buffer of the specified size.
+ *
+ * The resulting %buffer has the same size and capacity.
+ *
+ * @param size A %buffer size in bytes.
+ */
+ explicit
+ base64_binary (size_t size = 0);
+
+ /**
+ * @brief Allocate a %buffer of the specified size and capacity.
+ *
+ * @param size A %buffer size in bytes.
+ * @param capacity A %buffer capacity in bytes.
+ * @throw bounds If @a size exceeds @a capacity
+ */
+ base64_binary (size_t size, size_t capacity);
+
+ /**
+ * @brief Allocate a %buffer of the specified size and copy
+ * the data.
+ *
+ * The resulting %buffer has the same size and capacity with
+ * @a size bytes copied from @a data.
+ *
+ * @param data A %buffer to copy the data from.
+ * @param size A %buffer size in bytes.
+ */
+ base64_binary (const void* data, size_t size);
+
+ /**
+ * @brief Allocate a %buffer of the specified size and capacity
+ * and copy the data.
+ *
+ * @a size bytes are copied from @a data to the resulting
+ * %buffer.
+ *
+ * @param data A %buffer to copy the data from.
+ * @param size A %buffer size in bytes.
+ * @param capacity A %buffer capacity in bytes.
+ * @throw bounds If @a size exceeds @a capacity
+ */
+ base64_binary (const void* data, size_t size, size_t capacity);
+
+ /**
+ * @brief Assume ownership of the specified %buffer.
+ *
+ * If the @a assume_ownership argument is true, the %buffer will
+ * assume ownership of @a data and will release the memory
+ * by calling @c operator @c delete().
+ *
+ * @param data A %buffer to assume ownership of.
+ * @param size A %buffer size in bytes.
+ * @param capacity A %buffer capacity in bytes.
+ * @param assume_ownership A boolean value indication whether to
+ * assume ownership.
+ * @throw bounds If @a size exceeds @a capacity
+ */
+ base64_binary (void* data,
+ size_t size,
+ size_t capacity,
+ bool assume_ownership);
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ base64_binary (const base64_binary& x,
+ flags f = 0,
+ container* c = 0)
+ : B (x, f, c), buffer<C> (x)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual base64_binary*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ base64_binary (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ base64_binary (const xercesc::DOMElement& e,
+ flags f = 0,
+ container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ base64_binary (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ base64_binary (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ base64_binary&
+ operator= (const base64_binary& x)
+ {
+ buffer<C>& b (*this);
+ b = x;
+ return *this;
+ }
+
+ public:
+ /**
+ * @brief Encode the %buffer in base64 encoding.
+ *
+ * @return A %string with base64-encoded data.
+ */
+ std::basic_string<C>
+ encode () const;
+
+ private:
+ void
+ decode (const XMLCh*);
+ };
+
+
+ /**
+ * @brief Class corresponding to the XML Schema hexBinary
+ * built-in type.
+ *
+ * The %hex_binary class is a binary %buffer abstraction with
+ * hex-encoded representation in XML. It publicly inherits from
+ * the buffer class which provides the %buffer functionality.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class hex_binary: public B, public buffer<C>
+ {
+ public:
+ typedef typename buffer<C>::size_t size_t;
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Allocate a %buffer of the specified size.
+ *
+ * The resulting %buffer has the same size and capacity.
+ *
+ * @param size A %buffer size in bytes.
+ */
+ explicit
+ hex_binary (size_t size = 0);
+
+ /**
+ * @brief Allocate a %buffer of the specified size and capacity.
+ *
+ * @param size A %buffer size in bytes.
+ * @param capacity A %buffer capacity in bytes.
+ * @throw bounds If @a size exceeds @a capacity
+ */
+ hex_binary (size_t size, size_t capacity);
+
+ /**
+ * @brief Allocate a %buffer of the specified size and copy
+ * the data.
+ *
+ * The resulting %buffer has the same size and capacity with
+ * @a size bytes copied from @a data.
+ *
+ * @param data A %buffer to copy the data from.
+ * @param size A %buffer size in bytes.
+ */
+ hex_binary (const void* data, size_t size);
+
+ /**
+ * @brief Allocate a %buffer of the specified size and capacity
+ * and copy the data.
+ *
+ * @a size bytes are copied from @a data to the resulting
+ * %buffer.
+ *
+ * @param data A %buffer to copy the data from.
+ * @param size A %buffer size in bytes.
+ * @param capacity A %buffer capacity in bytes.
+ * @throw bounds If @a size exceeds @a capacity
+ */
+ hex_binary (const void* data, size_t size, size_t capacity);
+
+ /**
+ * @brief Assume ownership of the specified %buffer.
+ *
+ * If the @a assume_ownership argument is true, the %buffer will
+ * assume ownership of @a data and will release the memory
+ * by calling @c operator @c delete().
+ *
+ * @param data A %buffer to assume ownership of.
+ * @param size A %buffer size in bytes.
+ * @param capacity A %buffer capacity in bytes.
+ * @param assume_ownership A boolean value indication whether to
+ * assume ownership.
+ * @throw bounds If @a size exceeds @a capacity
+ */
+ hex_binary (void* data,
+ size_t size,
+ size_t capacity,
+ bool assume_ownership);
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ hex_binary (const hex_binary& x, flags f = 0, container* c = 0)
+ : B (x, f, c), buffer<C> (x)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual hex_binary*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ hex_binary (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ hex_binary (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ hex_binary (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ hex_binary (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ hex_binary&
+ operator= (const hex_binary& x)
+ {
+ buffer<C>& b (*this);
+ b = x;
+ return *this;
+ }
+
+ public:
+ /**
+ * @brief Encode the %buffer in hex encoding.
+ *
+ * @return A %string with hex-encoded data.
+ */
+ std::basic_string<C>
+ encode () const;
+
+ private:
+ void
+ decode (const XMLCh*);
+ };
+
+
+ /**
+ * @brief Class corresponding to the XML Schema ENTITY built-in
+ * type.
+ *
+ * The %entity class publicly inherits from and has the same set
+ * of constructors as @c std::basic_string. It therefore can be
+ * used as @c std::string (or @c std::wstring if you are using
+ * @c wchar_t as the character type).
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B>
+ class entity: public B
+ {
+ typedef B base_type;
+
+ base_type&
+ base ()
+ {
+ return *this;
+ }
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Initialize an instance with a copy of a C %string.
+ *
+ * @param s A C %string to copy.
+ */
+ entity (const C* s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a character array.
+ *
+ * @param s A character array to copy.
+ * @param n A number of character to copy.
+ */
+ entity (const C* s, std::size_t n)
+ : base_type (s, n)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with multiple copies of the same
+ * character.
+ *
+ * @param n A number of copies to create.
+ * @param c A character to copy.
+ */
+ entity (std::size_t n, C c)
+ : base_type (n, c)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a standard %string.
+ *
+ * @param s A standard %string to copy.
+ */
+ entity (const std::basic_string<C>& s)
+ : base_type (s)
+ {
+ }
+
+ /**
+ * @brief Initialize an instance with a copy of a substring.
+ *
+ * @param s A standard %string to copy the substring from.
+ * @param pos An index of the first character to copy from.
+ * @param n A number of characters to copy.
+ */
+ entity (const std::basic_string<C>& s,
+ std::size_t pos,
+ std::size_t n = std::basic_string<C>::npos)
+ : base_type (s, pos, n)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ entity (const entity& x, flags f = 0, container* c = 0)
+ : base_type (x, f, c)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual entity*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ entity (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ entity (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ entity (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ entity (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+
+ public:
+ /**
+ * @brief Assign a character to the instance.
+ *
+ * The resulting %entity has only one character.
+ *
+ * @param c A character to assign.
+ * @return A reference to the instance.
+ */
+ entity&
+ operator= (C c)
+ {
+ base () = c;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a C %string to the instance.
+ *
+ * The resulting %entity contains a copy of the C %string.
+ *
+ * @param s A C %string to assign.
+ * @return A reference to the instance.
+ */
+ entity&
+ operator= (const C* s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Assign a standard %string to the instance.
+ *
+ * The resulting %entity contains a copy of the standard %string.
+ *
+ * @param s A standard %string to assign.
+ * @return A reference to the instance.
+ */
+ entity&
+ operator= (const std::basic_string<C>& s)
+ {
+ base () = s;
+ return *this;
+ }
+
+ /**
+ * @brief Copy assignment operator.
+ *
+ * @param x An instance to assign.
+ * @return A reference to the instance.
+ */
+ entity&
+ operator= (const entity& x)
+ {
+ base () = x;
+ return *this;
+ }
+
+ protected:
+ //@cond
+
+ entity ()
+ : base_type ()
+ {
+ }
+
+ //@endcond
+ };
+
+
+ /**
+ * @brief Class corresponding to the XML Schema ENTITIES built-in
+ * type.
+ *
+ * The %entities class is a vector (or %list in XML Schema terminology)
+ * of entity elements. It is implemented in terms of the list class
+ * template.
+ *
+ * @nosubgrouping
+ */
+ template <typename C, typename B, typename entity>
+ class entities: public B, public list<entity, C>
+ {
+ typedef list<entity, C> base_type;
+
+ public:
+ /**
+ * @name Constructors
+ */
+ //@{
+
+ /**
+ * @brief Default constructor creates no elements.
+ */
+ entities ()
+ {
+ }
+
+ /**
+ * @brief Initialize the instance with copies of an exemplar elements.
+ *
+ * @param n A number of elements to copy.
+ * @param x An exemplar element to copy.
+ */
+ entities (typename base_type::size_type n, const entity& x)
+ : base_type (n, x)
+ {
+ }
+
+ /**
+ * @brief Initialize the instance with copies of elements from an
+ * iterator range.
+ *
+ * @param begin An iterator pointing to the first element.
+ * @param end An iterator pointing to the one past the last element.
+ */
+ template <typename I>
+ entities (const I& begin, const I& end)
+ : base_type (begin, end)
+ {
+ }
+
+ public:
+ /**
+ * @brief Copy constructor.
+ *
+ * @param x An instance to make a copy of.
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ *
+ * For polymorphic object models use the @c _clone function instead.
+ */
+ entities (const entities& x, flags f = 0, container* c = 0)
+ : B (x, f, c), base_type (x, f, c)
+ {
+ }
+
+ /**
+ * @brief Copy the instance polymorphically.
+ *
+ * @param f Flags to create the copy with.
+ * @param c A pointer to the object that will contain the copy.
+ * @return A pointer to the dynamically allocated copy.
+ *
+ * This function ensures that the dynamic type of the instance
+ * is used for copying and should be used for polymorphic object
+ * models instead of the copy constructor.
+ */
+ virtual entities*
+ _clone (flags f = 0, container* c = 0) const;
+
+ public:
+ /**
+ * @brief Create an instance from a data representation
+ * stream.
+ *
+ * @param s A stream to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ template <typename S>
+ entities (istream<S>& s, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM element.
+ *
+ * @param e A DOM element to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ entities (const xercesc::DOMElement& e, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a DOM Attribute.
+ *
+ * @param a A DOM attribute to extract the data from.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ entities (const xercesc::DOMAttr& a, flags f = 0, container* c = 0);
+
+ /**
+ * @brief Create an instance from a %string fragment.
+ *
+ * @param s A %string fragment to extract the data from.
+ * @param e A pointer to DOM element containing the %string fragment.
+ * @param f Flags to create the new instance with.
+ * @param c A pointer to the object that will contain the new
+ * instance.
+ */
+ entities (const std::basic_string<C>& s,
+ const xercesc::DOMElement* e,
+ flags f = 0,
+ container* c = 0);
+ //@}
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/tree/types.txx>
+
+#endif // XSD_CXX_TREE_TYPES_HXX
diff --git a/libxsd/xsd/cxx/tree/types.txx b/libxsd/xsd/cxx/tree/types.txx
new file mode 100644
index 0000000..799c5fa
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/types.txx
@@ -0,0 +1,610 @@
+// file : xsd/cxx/tree/types.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xercesc/util/Base64.hpp>
+#include <xercesc/util/XMLString.hpp>
+#include <xercesc/util/XercesVersion.hpp>
+
+#include <xsd/cxx/auto-array.hxx>
+
+#include <xsd/cxx/xml/std-memory-manager.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+
+ // string
+ //
+ template <typename C, typename B>
+ string<C, B>* string<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new string (*this, f, c);
+ }
+
+
+ // normalized_string
+ //
+ template <typename C, typename B>
+ normalized_string<C, B>* normalized_string<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new normalized_string (*this, f, c);
+ }
+
+
+ // token
+ //
+ template <typename C, typename B>
+ token<C, B>* token<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new token (*this, f, c);
+ }
+
+
+ // nmtoken
+ //
+ template <typename C, typename B>
+ nmtoken<C, B>* nmtoken<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new nmtoken (*this, f, c);
+ }
+
+
+ // nmtokens
+ //
+ template <typename C, typename B, typename nmtoken>
+ nmtokens<C, B, nmtoken>* nmtokens<C, B, nmtoken>::
+ _clone (flags f, container* c) const
+ {
+ return new nmtokens (*this, f, c);
+ }
+
+
+ // name
+ //
+ template <typename C, typename B>
+ name<C, B>* name<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new name (*this, f, c);
+ }
+
+
+ // ncname
+ //
+ template <typename C, typename B>
+ ncname<C, B>* ncname<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new ncname (*this, f, c);
+ }
+
+
+ // language
+ //
+ template <typename C, typename B>
+ language<C, B>* language<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new language (*this, f, c);
+ }
+
+
+ // identity_impl
+ //
+ template <typename C, typename ncname>
+ bool identity_impl<C, ncname>::
+ before (const identity& y) const
+ {
+ return id_ < static_cast<const identity_impl&> (y).id_;
+ }
+
+ template <typename C, typename ncname>
+ void identity_impl<C, ncname>::
+ throw_duplicate_id () const
+ {
+ throw duplicate_id<C> (id_);
+ }
+
+
+ // id
+ //
+ template <typename C, typename B>
+ id<C, B>* id<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new id (*this, f, c);
+ }
+
+ template <typename C, typename B>
+ id<C, B>& id<C, B>::
+ operator= (C c)
+ {
+ unregister_id ();
+ base () = c;
+ register_id ();
+
+ return *this;
+ }
+
+ template <typename C, typename B>
+ id<C, B>& id<C, B>::
+ operator= (const C* s)
+ {
+ unregister_id ();
+ base () = s;
+ register_id ();
+
+ return *this;
+ }
+
+ template <typename C, typename B>
+ id<C, B>& id<C, B>::
+ operator= (const std::basic_string<C>& s)
+ {
+ unregister_id ();
+ base () = s;
+ register_id ();
+
+ return *this;
+ }
+
+ template <typename C, typename B>
+ id<C, B>& id<C, B>::
+ operator= (const id& x)
+ {
+ unregister_id ();
+ base () = x;
+ register_id ();
+
+ return *this;
+ }
+
+ // It would have been cleaner to mention empty and _container
+ // with the using-declaration but HP aCC3 can't handle it in
+ // some non-trivial to track down cases. So we are going to use
+ // the old-n-ugly this-> techniques.
+ //
+ template <typename C, typename B>
+ void id<C, B>::
+ _container (container* c)
+ {
+ B::_container (c);
+ register_id ();
+ }
+
+ template <typename C, typename B>
+ void id<C, B>::
+ register_id ()
+ {
+ container* c (this->_container ());
+
+ if (c != 0 && !this->empty ())
+ {
+ //std::cerr << "registering " << c
+ // << " as '" << *this
+ // << "' on " << c << std::endl;
+
+ c->_register_id (identity_, c);
+ }
+ }
+
+ template <typename C, typename B>
+ void id<C, B>::
+ unregister_id ()
+ {
+ container* c (this->_container ());
+
+ if (c != 0 && !this->empty ())
+ {
+ //std::cerr << "un-registering " << c
+ // << " as '" << *this
+ // << "' on " << c << std::endl;
+
+ c->_unregister_id (identity_);
+ }
+ }
+
+
+ // idref
+ //
+ template <typename T, typename C, typename B>
+ idref<T, C, B>* idref<T, C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new idref (*this, f, c);
+ }
+
+ // It would have been cleaner to mention empty, _root, etc. with
+ // the using-declaration but HP aCC3 can't handle it in some
+ // non-trivial to track down cases. So we are going to use the
+ // old-n-ugly this-> techniques.
+ //
+ template <typename T, typename C, typename B>
+ const _type* idref<T, C, B>::
+ get_ () const
+ {
+ if (!this->empty () && this->_container () != 0)
+ {
+ return this->_root ()->_lookup_id (identity_);
+ }
+ else
+ return 0;
+ }
+
+ template <typename T, typename C, typename B>
+ _type* idref<T, C, B>::
+ get_ ()
+ {
+ if (!this->empty () && this->_container () != 0)
+ {
+ return this->_root ()->_lookup_id (identity_);
+ }
+ else
+ return 0;
+ }
+
+ template <typename T, typename C, typename B>
+ void idref<T, C, B>::
+ true_ ()
+ {
+ }
+
+
+ // idrefs
+ //
+ template <typename C, typename B, typename idref>
+ idrefs<C, B, idref>* idrefs<C, B, idref>::
+ _clone (flags f, container* c) const
+ {
+ return new idrefs (*this, f, c);
+ }
+
+
+ // uri
+ //
+ template <typename C, typename B>
+ uri<C, B>* uri<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new uri (*this, f, c);
+ }
+
+
+ // qname
+ //
+ template <typename C, typename B, typename uri, typename ncname>
+ qname<C, B, uri, ncname>* qname<C, B, uri, ncname>::
+ _clone (flags f, container* c) const
+ {
+ return new qname (*this, f, c);
+ }
+
+
+ // base64_binary
+ //
+ template <typename C, typename B>
+ base64_binary<C, B>::
+ base64_binary (size_t size)
+ : buffer<C> (size)
+ {
+ }
+
+ template <typename C, typename B>
+ base64_binary<C, B>::
+ base64_binary (size_t size, size_t capacity)
+ : buffer<C> (size, capacity)
+ {
+ }
+
+ template <typename C, typename B>
+ base64_binary<C, B>::
+ base64_binary (const void* data, size_t size)
+ : buffer<C> (data, size)
+ {
+ }
+
+ template <typename C, typename B>
+ base64_binary<C, B>::
+ base64_binary (const void* data, size_t size, size_t capacity)
+ : buffer<C> (data, size, capacity)
+ {
+ }
+
+ template <typename C, typename B>
+ base64_binary<C, B>::
+ base64_binary (void* data, size_t size, size_t capacity, bool own)
+ : buffer<C> (data, size, capacity, own)
+ {
+ }
+
+ template <typename C, typename B>
+ base64_binary<C, B>* base64_binary<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new base64_binary (*this, f, c);
+ }
+
+ // It would have been cleaner to mention size, and data with the
+ // using-declaration but HP aCC3 can't handle it in some non-
+ // trivial to track down cases. So we are going to use the
+ // old-n- ugly this-> techniques.
+ //
+ template <typename C, typename B>
+ std::basic_string<C> base64_binary<C, B>::
+ encode () const
+ {
+ // HP aCC3 cannot handle using namespace xercesc;
+ //
+ using xercesc::Base64;
+ std::basic_string<C> str;
+
+#if _XERCES_VERSION >= 30000
+ XMLSize_t n;
+
+ xml::std_memory_manager mm;
+ auto_array<XMLByte, xml::std_memory_manager> r (
+ Base64::encode (
+ reinterpret_cast<const XMLByte*> (this->data ()),
+ static_cast<XMLSize_t> (this->size ()),
+ &n,
+ &mm),
+ mm);
+
+ if (r)
+ {
+ str.reserve (n + 1);
+ str.resize (n);
+
+ for (XMLSize_t i (0); i < n; ++i)
+ str[i] = C (r[i]);
+ }
+ else
+ {
+ //@@ throw
+ }
+#else
+ unsigned int n;
+
+ xml::std_memory_manager mm;
+ auto_array<XMLByte, xml::std_memory_manager> r (
+ Base64::encode (
+ reinterpret_cast<const XMLByte*> (this->data ()),
+ static_cast<unsigned int> (this->size ()),
+ &n,
+ &mm),
+ mm);
+
+ if (r)
+ {
+ str.reserve (n + 1);
+ str.resize (n);
+
+ for (unsigned int i (0); i < n; ++i)
+ str[i] = C (r[i]);
+ }
+ else
+ {
+ //@@ throw
+ }
+#endif
+
+ return str;
+ }
+
+ template <typename C, typename B>
+ void base64_binary<C, B>::
+ decode (const XMLCh* src)
+ {
+ // HP aCC3 cannot handle using namespace xercesc;
+ //
+ using xercesc::Base64;
+
+ xml::std_memory_manager mm;
+
+ // Xerces 2.6.0 and earlier do not have decodeToXMLByte which
+ // makes my life harder and your code slower.
+ //
+#if _XERCES_VERSION >= 20700
+
+#if _XERCES_VERSION >= 30000
+ XMLSize_t size;
+ auto_array<XMLByte, xml::std_memory_manager> data (
+ Base64::decodeToXMLByte (src, &size, &mm, Base64::Conf_RFC2045),
+ mm);
+#else
+ unsigned int size;
+ auto_array<XMLByte, xml::std_memory_manager> data (
+ Base64::decodeToXMLByte (src, &size, &mm, Base64::Conf_RFC2045),
+ mm);
+#endif // _XERCES_VERSION >= 30000
+
+ if (data)
+ {
+ buffer<C> tmp (data.get (), size, size, true);
+ data.release ();
+ this->swap (tmp); // g++ 4.1 likes it qualified, not sure why.
+ }
+ else
+ {
+ //@@ throw
+ }
+#else
+ unsigned int size;
+
+#if _XERCES_VERSION >= 20600 // Xerces 2.5.0 does not have Conf_RFC2045.
+ auto_array<XMLCh, xml::std_memory_manager> data (
+ Base64::decode (src, &size, &mm, Base64::Conf_RFC2045),
+ mm);
+#else
+ auto_array<XMLCh, xml::std_memory_manager> data (
+ Base64::decode (src, &size, &mm), mm);
+#endif // _XERCES_VERSION >= 20600
+
+ if (data)
+ {
+ buffer<C> tmp (size);
+ for (unsigned int i (0); i < size; ++i)
+ tmp.data ()[i] = static_cast<char> (data[i]);
+ this->swap (tmp); // g++ 4.1 likes it qualified, not sure why.
+ }
+ else
+ {
+ //@@ throw
+ }
+#endif //_XERCES_VERSION >= 20700
+ }
+
+
+ // hex_binary
+ //
+ template <typename C, typename B>
+ hex_binary<C, B>::
+ hex_binary (size_t size)
+ : buffer<C> (size)
+ {
+ }
+
+ template <typename C, typename B>
+ hex_binary<C, B>::
+ hex_binary (size_t size, size_t capacity)
+ : buffer<C> (size, capacity)
+ {
+ }
+
+ template <typename C, typename B>
+ hex_binary<C, B>::
+ hex_binary (const void* data, size_t size)
+ : buffer<C> (data, size)
+ {
+ }
+
+ template <typename C, typename B>
+ hex_binary<C, B>::
+ hex_binary (const void* data, size_t size, size_t capacity)
+ : buffer<C> (data, size, capacity)
+ {
+ }
+
+ template <typename C, typename B>
+ hex_binary<C, B>::
+ hex_binary (void* data, size_t size, size_t capacity, bool own)
+ : buffer<C> (data, size, capacity, own)
+ {
+ }
+
+ template <typename C, typename B>
+ hex_binary<C, B>* hex_binary<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new hex_binary (*this, f, c);
+ }
+
+ // It would have been cleaner to mention size, and data with the
+ // using-declaration but HP aCC3 can't handle it in some non-
+ // trivial to track down cases. So we are going to use the
+ // old-n-ugly this-> techniques.
+ //
+ template <typename C, typename B>
+ std::basic_string<C> hex_binary<C, B>::
+ encode () const
+ {
+ std::basic_string<C> str;
+
+ const char tab[] = "0123456789ABCDEF";
+
+ if (size_t n = this->size ())
+ {
+ str.reserve (2 * n + 1);
+ str.resize (2 * n);
+
+ for (size_t i (0); i < n; ++i)
+ {
+ unsigned char byte (
+ static_cast<unsigned char> (*(this->data () + i)));
+ unsigned char h (byte >> 4);
+ unsigned char l (byte & 0x0F);
+
+ str[2 * i] = C (tab[h]);
+ str[2 * i + 1] = C (tab[l]);
+ }
+ }
+
+ return str;
+ }
+
+ namespace bits
+ {
+ inline unsigned char
+ hex_decode (XMLCh c)
+ {
+ unsigned char r (0xFF);
+
+ if (c >= '0' && c <= '9')
+ r = static_cast<unsigned char> (c - '0');
+ else if (c >= 'A' && c <= 'F')
+ r = static_cast<unsigned char> (10 + (c - 'A'));
+ else if (c >= 'a' && c <= 'f')
+ r = static_cast<unsigned char> (10 + (c - 'a'));
+
+ return r;
+ }
+ }
+
+ template <typename C, typename B>
+ void hex_binary<C, B>::
+ decode (const XMLCh* src)
+ {
+ size_t src_n (xercesc::XMLString::stringLen (src));
+
+ if (src_n % 2 != 0)
+ return; // @@ throw
+
+ size_t n (src_n / 2);
+
+ buffer<C> tmp (n);
+
+ for (size_t i (0); i < n; ++i)
+ {
+ unsigned char h (bits::hex_decode (src[2 * i]));
+ unsigned char l (bits::hex_decode (src[2 * i + 1]));
+
+ if (h == 0xFF || l == 0xFF)
+ return; //@@ throw
+
+ tmp.data()[i] = (h << 4) | l;
+ }
+
+ this->swap (tmp); // g++ 4.1 likes it qualified, not sure why.
+ }
+
+
+ // entity
+ //
+ template <typename C, typename B>
+ entity<C, B>* entity<C, B>::
+ _clone (flags f, container* c) const
+ {
+ return new entity (*this, f, c);
+ }
+
+
+ // entities
+ //
+ template <typename C, typename B, typename entity>
+ entities<C, B, entity>* entities<C, B, entity>::
+ _clone (flags f, container* c) const
+ {
+ return new entities (*this, f, c);
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/tree/xdr-stream-common.hxx b/libxsd/xsd/cxx/tree/xdr-stream-common.hxx
new file mode 100644
index 0000000..33912c4
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/xdr-stream-common.hxx
@@ -0,0 +1,26 @@
+// file : xsd/cxx/tree/xdr-stream-common.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_XDR_STREAM_COMMON_HXX
+#define XSD_CXX_TREE_XDR_STREAM_COMMON_HXX
+
+#include <xsd/cxx/exceptions.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ // Base exception for XDR insertion/extraction exceptions.
+ //
+ struct xdr_stream_operation: xsd::cxx::exception
+ {
+ };
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_XDR_STREAM_COMMON_HXX
diff --git a/libxsd/xsd/cxx/tree/xdr-stream-extraction.hxx b/libxsd/xsd/cxx/tree/xdr-stream-extraction.hxx
new file mode 100644
index 0000000..f71a05e
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/xdr-stream-extraction.hxx
@@ -0,0 +1,295 @@
+// file : xsd/cxx/tree/xdr-stream-extraction.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_XDR_STREAM_EXTRACTION_HXX
+#define XSD_CXX_TREE_XDR_STREAM_EXTRACTION_HXX
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#include <string>
+
+#include <xsd/cxx/tree/buffer.hxx>
+#include <xsd/cxx/tree/istream.hxx>
+#include <xsd/cxx/tree/xdr-stream-common.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ struct xdr_stream_extraction: xdr_stream_operation
+ {
+ virtual const char*
+ what () const throw ()
+ {
+ return "XDR stream extraction operation failed";
+ }
+ };
+
+
+ // as_size
+ //
+#ifdef XSD_CXX_TREE_USE_64_BIT_SIZE
+ template <typename T>
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, istream<XDR>::as_size<T>& x)
+ {
+ uint64_t v;
+
+ if (!xdr_uint64_t (&s.impl (), &v) || v > ~(T (0)))
+ throw xdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (v);
+
+ return s;
+ }
+#else
+ template <typename T>
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, istream<XDR>::as_size<T>& x)
+ {
+ uint32_t v;
+
+ if (!xdr_uint32_t (&s.impl (), &v))
+ throw xdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (v);
+
+ return s;
+ }
+#endif
+
+
+ // 8-bit
+ //
+ template <typename T>
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, istream<XDR>::as_int8<T>& x)
+ {
+ int8_t v;
+
+ if (!xdr_int8_t (&s.impl (), &v))
+ throw xdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (v);
+
+ return s;
+ }
+
+ template <typename T>
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, istream<XDR>::as_uint8<T>& x)
+ {
+ uint8_t v;
+
+ if (!xdr_uint8_t (&s.impl (), &v))
+ throw xdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (v);
+
+ return s;
+ }
+
+
+ // 16-bit
+ //
+ template <typename T>
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, istream<XDR>::as_int16<T>& x)
+ {
+ int16_t v;
+
+ if (!xdr_int16_t (&s.impl (), &v))
+ throw xdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (v);
+
+ return s;
+ }
+
+ template <typename T>
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, istream<XDR>::as_uint16<T>& x)
+ {
+ uint16_t v;
+
+ if (!xdr_uint16_t (&s.impl (), &v))
+ throw xdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (v);
+
+ return s;
+ }
+
+
+ // 32-bit
+ //
+ template <typename T>
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, istream<XDR>::as_int32<T>& x)
+ {
+ int32_t v;
+
+ if (!xdr_int32_t (&s.impl (), &v))
+ throw xdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (v);
+
+ return s;
+ }
+
+ template <typename T>
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, istream<XDR>::as_uint32<T>& x)
+ {
+ uint32_t v;
+
+ if (!xdr_uint32_t (&s.impl (), &v))
+ throw xdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (v);
+
+ return s;
+ }
+
+
+ // 64-bit
+ //
+ template <typename T>
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, istream<XDR>::as_int64<T>& x)
+ {
+ int64_t v;
+
+ if (!xdr_int64_t (&s.impl (), &v))
+ throw xdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (v);
+
+ return s;
+ }
+
+ template <typename T>
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, istream<XDR>::as_uint64<T>& x)
+ {
+ uint64_t v;
+
+ if (!xdr_uint64_t (&s.impl (), &v))
+ throw xdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (v);
+
+ return s;
+ }
+
+
+ // Boolean
+ //
+ template <typename T>
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, istream<XDR>::as_bool<T>& x)
+ {
+ bool_t v;
+
+ if (!xdr_bool (&s.impl (), &v))
+ throw xdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (v);
+
+ return s;
+ }
+
+
+ // Floating-point
+ //
+ template <typename T>
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, istream<XDR>::as_float32<T>& x)
+ {
+ float v;
+
+ if (!xdr_float (&s.impl (), &v))
+ throw xdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (v);
+
+ return s;
+ }
+
+ template <typename T>
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, istream<XDR>::as_float64<T>& x)
+ {
+ double v;
+
+ if (!xdr_double (&s.impl (), &v))
+ throw xdr_stream_extraction ();
+
+ x.x_ = static_cast<T> (v);
+
+ return s;
+ }
+
+ // Extraction of std::basic_string.
+ //
+
+ inline istream<XDR>&
+ operator>> (istream<XDR>& s, std::basic_string<char>& x)
+ {
+ unsigned int n;
+
+ if (!xdr_u_int (&s.impl (), &n))
+ throw xdr_stream_extraction ();
+
+ // Dangerous but fast.
+ //
+ x.clear ();
+
+ if (n != 0)
+ {
+ x.resize (n);
+ char* p (const_cast<char*> (x.c_str ()));
+
+ if (!xdr_opaque (&s.impl (), p, n))
+ throw xdr_stream_extraction ();
+ }
+
+ return s;
+ }
+
+ // Wide strings are not supported by XDR.
+ //
+ // inline istream<XDR>&
+ // operator>> (istream<XDR>& s, std::basic_string<wchar_t>& x)
+ // {
+ // }
+
+
+ // Extraction of a binary buffer.
+ //
+ template <typename C>
+ istream<XDR>&
+ operator>> (istream<XDR>& s, buffer<C>& x)
+ {
+ unsigned int n;
+
+ if (!xdr_u_int (&s.impl (), &n))
+ throw xdr_stream_extraction ();
+
+ x.size (n);
+
+ if (!xdr_opaque (&s.impl (), x.data (), n))
+ throw xdr_stream_extraction ();
+
+ return s;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_XDR_STREAM_EXTRACTION_HXX
diff --git a/libxsd/xsd/cxx/tree/xdr-stream-insertion.hxx b/libxsd/xsd/cxx/tree/xdr-stream-insertion.hxx
new file mode 100644
index 0000000..692680f
--- /dev/null
+++ b/libxsd/xsd/cxx/tree/xdr-stream-insertion.hxx
@@ -0,0 +1,259 @@
+// file : xsd/cxx/tree/xdr-stream-insertion.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_TREE_XDR_STREAM_INSERTION_HXX
+#define XSD_CXX_TREE_XDR_STREAM_INSERTION_HXX
+
+#include <rpc/types.h>
+#include <rpc/xdr.h>
+
+#include <string>
+
+#include <xsd/cxx/tree/buffer.hxx>
+#include <xsd/cxx/tree/ostream.hxx>
+#include <xsd/cxx/tree/xdr-stream-common.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace tree
+ {
+ struct xdr_stream_insertion: xdr_stream_operation
+ {
+ virtual const char*
+ what () const throw ()
+ {
+ return "XDR stream insertion operation failed";
+ }
+ };
+
+ // as_size
+ //
+#ifdef XSD_CXX_TREE_USE_64_BIT_SIZE
+ template <typename T>
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, ostream<XDR>::as_size<T> x)
+ {
+ uint64_t v (static_cast<uint64_t> (x.x_));
+
+ if (!xdr_uint64_t (&s.impl (), &v))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+#else
+ template <typename T>
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, ostream<XDR>::as_size<T> x)
+ {
+ uint32_t v (static_cast<uint32_t> (x.x_));
+
+ if (x.x_ > ~(uint32_t (0)) || !xdr_uint32_t (&s.impl (), &v))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+#endif
+
+
+ // 8-bit
+ //
+ template <typename T>
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, ostream<XDR>::as_int8<T> x)
+ {
+ int8_t v (static_cast<int8_t> (x.x_));
+
+ if (!xdr_int8_t (&s.impl (), &v))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+
+ template <typename T>
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, ostream<XDR>::as_uint8<T> x)
+ {
+ uint8_t v (static_cast<uint8_t> (x.x_));
+
+ if (!xdr_uint8_t (&s.impl (), &v))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+
+
+ // 16-bit
+ //
+ template <typename T>
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, ostream<XDR>::as_int16<T> x)
+ {
+ int16_t v (static_cast<int16_t> (x.x_));
+
+ if (!xdr_int16_t (&s.impl (), &v))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+
+ template <typename T>
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, ostream<XDR>::as_uint16<T> x)
+ {
+ uint16_t v (static_cast<uint16_t> (x.x_));
+
+ if (!xdr_uint16_t (&s.impl (), &v))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+
+
+ // 32-bit
+ //
+ template <typename T>
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, ostream<XDR>::as_int32<T> x)
+ {
+ int32_t v (static_cast<int32_t> (x.x_));
+
+ if (!xdr_int32_t (&s.impl (), &v))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+
+ template <typename T>
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, ostream<XDR>::as_uint32<T> x)
+ {
+ uint32_t v (static_cast<uint32_t> (x.x_));
+
+ if (!xdr_uint32_t (&s.impl (), &v))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+
+
+ // 64-bit
+ //
+ template <typename T>
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, ostream<XDR>::as_int64<T> x)
+ {
+ int64_t v (static_cast<int64_t> (x.x_));
+
+ if (!xdr_int64_t (&s.impl (), &v))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+
+ template <typename T>
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, ostream<XDR>::as_uint64<T> x)
+ {
+ uint64_t v (static_cast<uint64_t> (x.x_));
+
+ if (!xdr_uint64_t (&s.impl (), &v))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+
+
+ // Boolean
+ //
+ template <typename T>
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, ostream<XDR>::as_bool<T> x)
+ {
+ bool_t v (static_cast<bool_t> (x.x_));
+
+ if (!xdr_bool (&s.impl (), &v))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+
+
+ // Floating-point
+ //
+ template <typename T>
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, ostream<XDR>::as_float32<T> x)
+ {
+ float v (static_cast<float> (x.x_));
+
+ if (!xdr_float (&s.impl (), &v))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+
+ template <typename T>
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, ostream<XDR>::as_float64<T> x)
+ {
+ double v (static_cast<double> (x.x_));
+
+ if (!xdr_double (&s.impl (), &v))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+
+ // Insertion of std::basic_string.
+ //
+
+ inline ostream<XDR>&
+ operator<< (ostream<XDR>& s, const std::basic_string<char>& x)
+ {
+ // XDR strings are hard-wired with a 32 bit (unsigned int) length.
+ //
+ char* p (const_cast<char*> (x.c_str ()));
+ unsigned int n (static_cast<unsigned int> (x.length ()));
+
+ if (x.length () > ~((unsigned int) 0) ||
+ !xdr_u_int (&s.impl (), &n) ||
+ !xdr_opaque (&s.impl (), p, n))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+
+ // Wide strings are not supported by XDR.
+ //
+ // inline ostream<XDR>&
+ // operator<< (ostream<XDR>& s, const std::basic_string<wchar_t>& x)
+ // {
+ // }
+
+
+ // Insertion of a binary buffer.
+ //
+ template <typename C>
+ ostream<XDR>&
+ operator<< (ostream<XDR>& s, const buffer<C>& x)
+ {
+ // It is not possible to write an array with a 64-bit size.
+ //
+ unsigned int n (static_cast<unsigned int> (x.size ()));
+
+ if (x.size () > ~((unsigned int) 0) ||
+ !xdr_u_int (&s.impl (), &n) ||
+ !xdr_opaque (&s.impl (), const_cast<char*> (x.data ()), n))
+ throw xdr_stream_insertion ();
+
+ return s;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_TREE_XDR_STREAM_INSERTION_HXX
diff --git a/libxsd/xsd/cxx/version.hxx b/libxsd/xsd/cxx/version.hxx
new file mode 100644
index 0000000..ae9c023
--- /dev/null
+++ b/libxsd/xsd/cxx/version.hxx
@@ -0,0 +1,29 @@
+// file : xsd/cxx/version.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_VERSION_HXX
+#define XSD_CXX_VERSION_HXX
+
+// Version format is AABBCCDD where
+//
+// AA - major version number
+// BB - minor version number
+// CC - bugfix version number
+// DD - alpha / beta (DD + 50) version number
+//
+// When DD is not 00, 1 is subtracted from AABBCC. For example:
+//
+// Version AABBCCDD
+// 2.0.0 02000000
+// 2.1.0 02010000
+// 2.1.1 02010100
+// 2.2.0.a1 02019901
+// 3.0.0.b2 02999952
+//
+
+#define XSD_STR_VERSION "3.3.0.a5"
+#define XSD_INT_VERSION 3029905L
+
+#endif // XSD_CXX_VERSION_HXX
diff --git a/libxsd/xsd/cxx/xml/bits/literals.hxx b/libxsd/xsd/cxx/xml/bits/literals.hxx
new file mode 100644
index 0000000..93df006
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/bits/literals.hxx
@@ -0,0 +1,83 @@
+// file : xsd/cxx/xml/bits/literals.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_BITS_LITERALS_HXX
+#define XSD_CXX_XML_BITS_LITERALS_HXX
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace bits
+ {
+ template <typename C>
+ const C*
+ xml_prefix ();
+
+ template <typename C>
+ const C*
+ xml_namespace ();
+
+ template <typename C>
+ const C*
+ xmlns_prefix ();
+
+ template <typename C>
+ const C*
+ xmlns_namespace ();
+
+ template <typename C>
+ const C*
+ xsi_prefix ();
+
+ template <typename C>
+ const C*
+ xsi_namespace ();
+
+ template <typename C>
+ const C*
+ type ();
+
+ template <typename C>
+ const C*
+ nil ();
+
+ template <typename C>
+ const C*
+ schema_location ();
+
+ template <typename C>
+ const C*
+ no_namespace_schema_location ();
+
+ template <typename C>
+ const C*
+ first_prefix ();
+
+ template <typename C>
+ const C*
+ second_prefix ();
+
+ template <typename C>
+ const C*
+ third_prefix ();
+
+ template <typename C>
+ const C*
+ fourth_prefix ();
+
+ template <typename C>
+ const C*
+ fifth_prefix ();
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_XML_BITS_LITERALS_HXX
+
+#include <xsd/cxx/xml/bits/literals.ixx>
diff --git a/libxsd/xsd/cxx/xml/bits/literals.ixx b/libxsd/xsd/cxx/xml/bits/literals.ixx
new file mode 100644
index 0000000..827d922
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/bits/literals.ixx
@@ -0,0 +1,261 @@
+// file : xsd/cxx/xml/bits/literals.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_BITS_LITERALS_IXX
+#define XSD_CXX_XML_BITS_LITERALS_IXX
+
+#endif // XSD_CXX_XML_BITS_LITERALS_IXX
+
+
+#if defined(XSD_USE_CHAR) || !defined(XSD_USE_WCHAR)
+
+#ifndef XSD_CXX_XML_BITS_LITERALS_IXX_CHAR
+#define XSD_CXX_XML_BITS_LITERALS_IXX_CHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace bits
+ {
+ template <>
+ inline const char*
+ xml_prefix<char> ()
+ {
+ return "xml";
+ }
+
+ template <>
+ inline const char*
+ xml_namespace<char> ()
+ {
+ return "http://www.w3.org/XML/1998/namespace";
+ }
+
+ template <>
+ inline const char*
+ xmlns_prefix<char> ()
+ {
+ return "xmlns";
+ }
+
+ template <>
+ inline const char*
+ xmlns_namespace<char> ()
+ {
+ return "http://www.w3.org/2000/xmlns/";
+ }
+
+ template <>
+ inline const char*
+ xsi_prefix<char> ()
+ {
+ return "xsi";
+ }
+
+ template <>
+ inline const char*
+ xsi_namespace<char> ()
+ {
+ return "http://www.w3.org/2001/XMLSchema-instance";
+ }
+
+ template <>
+ inline const char*
+ type<char> ()
+ {
+ return "type";
+ }
+
+ template <>
+ inline const char*
+ nil<char> ()
+ {
+ return "nil";
+ }
+
+ template <>
+ inline const char*
+ schema_location<char> ()
+ {
+ return "schemaLocation";
+ }
+
+ template <>
+ inline const char*
+ no_namespace_schema_location<char> ()
+ {
+ return "noNamespaceSchemaLocation";
+ }
+
+ template <>
+ inline const char*
+ first_prefix<char> ()
+ {
+ return "p1";
+ }
+
+ template <>
+ inline const char*
+ second_prefix<char> ()
+ {
+ return "p2";
+ }
+
+ template <>
+ inline const char*
+ third_prefix<char> ()
+ {
+ return "p3";
+ }
+
+ template <>
+ inline const char*
+ fourth_prefix<char> ()
+ {
+ return "p4";
+ }
+
+ template <>
+ inline const char*
+ fifth_prefix<char> ()
+ {
+ return "p5";
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_XML_BITS_LITERALS_IXX_CHAR
+#endif // XSD_USE_CHAR
+
+
+#if defined(XSD_USE_WCHAR) || !defined(XSD_USE_CHAR)
+
+#ifndef XSD_CXX_XML_BITS_LITERALS_IXX_WCHAR
+#define XSD_CXX_XML_BITS_LITERALS_IXX_WCHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace bits
+ {
+ template <>
+ inline const wchar_t*
+ xml_prefix<wchar_t> ()
+ {
+ return L"xml";
+ }
+
+ template <>
+ inline const wchar_t*
+ xml_namespace<wchar_t> ()
+ {
+ return L"http://www.w3.org/XML/1998/namespace";
+ }
+
+ template <>
+ inline const wchar_t*
+ xmlns_prefix<wchar_t> ()
+ {
+ return L"xmlns";
+ }
+
+ template <>
+ inline const wchar_t*
+ xmlns_namespace<wchar_t> ()
+ {
+ return L"http://www.w3.org/2000/xmlns/";
+ }
+
+ template <>
+ inline const wchar_t*
+ xsi_prefix<wchar_t> ()
+ {
+ return L"xsi";
+ }
+
+ template <>
+ inline const wchar_t*
+ xsi_namespace<wchar_t> ()
+ {
+ return L"http://www.w3.org/2001/XMLSchema-instance";
+ }
+
+ template <>
+ inline const wchar_t*
+ type<wchar_t> ()
+ {
+ return L"type";
+ }
+
+ template <>
+ inline const wchar_t*
+ nil<wchar_t> ()
+ {
+ return L"nil";
+ }
+
+ template <>
+ inline const wchar_t*
+ schema_location<wchar_t> ()
+ {
+ return L"schemaLocation";
+ }
+
+ template <>
+ inline const wchar_t*
+ no_namespace_schema_location<wchar_t> ()
+ {
+ return L"noNamespaceSchemaLocation";
+ }
+
+ template <>
+ inline const wchar_t*
+ first_prefix<wchar_t> ()
+ {
+ return L"p1";
+ }
+
+ template <>
+ inline const wchar_t*
+ second_prefix<wchar_t> ()
+ {
+ return L"p2";
+ }
+
+ template <>
+ inline const wchar_t*
+ third_prefix<wchar_t> ()
+ {
+ return L"p3";
+ }
+
+ template <>
+ inline const wchar_t*
+ fourth_prefix<wchar_t> ()
+ {
+ return L"p4";
+ }
+
+ template <>
+ inline const wchar_t*
+ fifth_prefix<wchar_t> ()
+ {
+ return L"p5";
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_XML_BITS_LITERALS_IXX_WCHAR
+#endif // XSD_USE_WCHAR
diff --git a/libxsd/xsd/cxx/xml/dom/auto-ptr.hxx b/libxsd/xsd/cxx/xml/dom/auto-ptr.hxx
new file mode 100644
index 0000000..624c0e8
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/auto-ptr.hxx
@@ -0,0 +1,158 @@
+// file : xsd/cxx/xml/dom/auto-ptr.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_DOM_AUTO_PTR_HXX
+#define XSD_CXX_XML_DOM_AUTO_PTR_HXX
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ // Simple auto_ptr version that calls release() instead of delete.
+ //
+
+ template <typename T>
+ struct remove_c
+ {
+ typedef T r;
+ };
+
+ template <typename T>
+ struct remove_c<const T>
+ {
+ typedef T r;
+ };
+
+ template <typename T>
+ struct auto_ptr_ref
+ {
+ T* x_;
+
+ explicit
+ auto_ptr_ref (T* x)
+ : x_ (x)
+ {
+ }
+ };
+
+ template <typename T>
+ struct auto_ptr
+ {
+ ~auto_ptr ()
+ {
+ reset ();
+ }
+
+ explicit
+ auto_ptr (T* x = 0)
+ : x_ (x)
+ {
+ }
+
+ auto_ptr (auto_ptr& y)
+ : x_ (y.release ())
+ {
+ }
+
+ template <typename T2>
+ auto_ptr (auto_ptr<T2>& y)
+ : x_ (y.release ())
+ {
+ }
+
+ auto_ptr (auto_ptr_ref<T> r)
+ : x_ (r.x_)
+ {
+ }
+
+ auto_ptr&
+ operator= (auto_ptr& y)
+ {
+ if (x_ != y.x_)
+ reset (y.release ());
+
+ return *this;
+ }
+
+ template <typename T2>
+ auto_ptr&
+ operator= (auto_ptr<T2>& y)
+ {
+ if (x_ != y.x_)
+ reset (y.release ());
+
+ return *this;
+ }
+
+ auto_ptr&
+ operator= (auto_ptr_ref<T> r)
+ {
+ if (r.x_ != x_)
+ reset (r.x_);
+
+ return *this;
+ }
+
+ template <typename T2>
+ operator auto_ptr_ref<T2> ()
+ {
+ return auto_ptr_ref<T2> (release ());
+ }
+
+ template <typename T2>
+ operator auto_ptr<T2> ()
+ {
+ return auto_ptr<T2> (release ());
+ }
+
+ public:
+ T&
+ operator* () const
+ {
+ return *x_;
+ }
+
+ T*
+ operator-> () const
+ {
+ return x_;
+ }
+
+ T*
+ get () const
+ {
+ return x_;
+ }
+
+ T*
+ release ()
+ {
+ T* x (x_);
+ x_ = 0;
+ return x;
+ }
+
+ void
+ reset (T* x = 0)
+ {
+ if (x_)
+ const_cast<typename remove_c<T>::r*> (x_)->release ();
+
+ x_ = x;
+ }
+
+ private:
+ T* x_;
+ };
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_XML_DOM_AUTO_PTR_HXX
diff --git a/libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.hxx b/libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.hxx
new file mode 100644
index 0000000..e0d9f1d
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.hxx
@@ -0,0 +1,61 @@
+// file : xsd/cxx/xml/dom/bits/error-handler-proxy.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_DOM_BITS_ERROR_HANDLER_PROXY_HXX
+#define XSD_CXX_XML_DOM_BITS_ERROR_HANDLER_PROXY_HXX
+
+#include <xercesc/dom/DOMError.hpp>
+#include <xercesc/dom/DOMLocator.hpp>
+#include <xercesc/dom/DOMErrorHandler.hpp>
+
+#include <xsd/cxx/xml/error-handler.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ namespace bits
+ {
+ template <typename C>
+ class error_handler_proxy: public xercesc::DOMErrorHandler
+ {
+ public:
+ error_handler_proxy (error_handler<C>& eh)
+ : failed_ (false), eh_ (&eh), native_eh_ (0)
+ {
+ }
+
+ error_handler_proxy (xercesc::DOMErrorHandler& eh)
+ : failed_ (false), eh_ (0), native_eh_ (&eh)
+ {
+ }
+
+ virtual bool
+ handleError (const xercesc::DOMError& e);
+
+ bool
+ failed () const
+ {
+ return failed_;
+ }
+
+ private:
+ bool failed_;
+ error_handler<C>* eh_;
+ xercesc::DOMErrorHandler* native_eh_;
+ };
+ }
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.txx>
+
+#endif // XSD_CXX_XML_DOM_BITS_ERROR_HANDLER_PROXY_HXX
diff --git a/libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.txx b/libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.txx
new file mode 100644
index 0000000..65a2cf3
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/bits/error-handler-proxy.txx
@@ -0,0 +1,80 @@
+// file : xsd/cxx/xml/dom/bits/error-handler-proxy.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd/cxx/xml/string.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ namespace bits
+ {
+ template <typename C>
+ bool error_handler_proxy<C>::
+ handleError (const xercesc::DOMError& e)
+ {
+ using xercesc::DOMError;
+
+ if (e.getSeverity() != DOMError::DOM_SEVERITY_WARNING)
+ failed_ = true;
+
+ if (native_eh_)
+ return native_eh_->handleError (e);
+ else
+ {
+ typedef typename error_handler<C>::severity severity;
+
+ severity s (severity::error);
+
+ switch (e.getSeverity())
+ {
+ case DOMError::DOM_SEVERITY_WARNING:
+ {
+ s = severity::warning;
+ break;
+ }
+ case DOMError::DOM_SEVERITY_ERROR:
+ {
+ s = severity::error;
+ break;
+ }
+ case DOMError::DOM_SEVERITY_FATAL_ERROR:
+ {
+ s = severity::fatal;
+ break;
+ }
+ }
+
+ xercesc::DOMLocator* loc (e.getLocation ());
+
+#if _XERCES_VERSION >= 30000
+ return eh_->handle (
+ transcode<C> (loc->getURI ()),
+ static_cast<unsigned long> (loc->getLineNumber ()),
+ static_cast<unsigned long> (loc->getColumnNumber ()),
+ s,
+ transcode<C> (e.getMessage ()));
+#else
+ XMLSSize_t l (loc->getLineNumber ());
+ XMLSSize_t c (loc->getColumnNumber ());
+
+ return eh_->handle (
+ transcode<C> (loc->getURI ()),
+ (l == -1 ? 0 : static_cast<unsigned long> (l)),
+ (c == -1 ? 0 : static_cast<unsigned long> (c)),
+ s,
+ transcode<C> (e.getMessage ()));
+#endif
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/xml/dom/elements.hxx b/libxsd/xsd/cxx/xml/dom/elements.hxx
new file mode 100644
index 0000000..9c4623b
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/elements.hxx
@@ -0,0 +1,36 @@
+// file : xsd/cxx/xml/dom/elements.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_DOM_ELEMENTS_HXX
+#define XSD_CXX_XML_DOM_ELEMENTS_HXX
+
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMElement.hpp>
+
+#include <xsd/cxx/xml/qualified-name.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ template <typename C>
+ qualified_name<C>
+ name (const xercesc::DOMAttr&);
+
+ template <typename C>
+ qualified_name<C>
+ name (const xercesc::DOMElement&);
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/xml/dom/elements.txx>
+
+#endif // XSD_CXX_XML_DOM_ELEMENTS_HXX
diff --git a/libxsd/xsd/cxx/xml/dom/elements.txx b/libxsd/xsd/cxx/xml/dom/elements.txx
new file mode 100644
index 0000000..0286237
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/elements.txx
@@ -0,0 +1,57 @@
+// file : xsd/cxx/xml/dom/elements.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd/cxx/xml/string.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ template <typename C>
+ qualified_name<C>
+ name (const xercesc::DOMAttr& a)
+ {
+ const XMLCh* n (a.getLocalName ());
+
+ // If this DOM doesn't support namespaces then use getName.
+ //
+ if (n != 0)
+ {
+ if (const XMLCh* ns = a.getNamespaceURI ())
+ return qualified_name<C> (transcode<C> (n), transcode<C> (ns));
+ else
+ return qualified_name<C> (transcode<C> (n));
+ }
+ else
+ return qualified_name<C> (transcode<C> (a.getName ()));
+ }
+
+
+ template <typename C>
+ qualified_name<C>
+ name (const xercesc::DOMElement& e)
+ {
+ const XMLCh* n (e.getLocalName ());
+
+ // If this DOM doesn't support namespaces then use getTagName.
+ //
+ if (n != 0)
+ {
+ if (const XMLCh* ns = e.getNamespaceURI ())
+ return qualified_name<C> (transcode<C> (n), transcode<C> (ns));
+ else
+ return qualified_name<C> (transcode<C> (n));
+ }
+ else
+ return qualified_name<C> (transcode<C> (e.getTagName ()));
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/xml/dom/parsing-header.hxx b/libxsd/xsd/cxx/xml/dom/parsing-header.hxx
new file mode 100644
index 0000000..6e82c7e
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/parsing-header.hxx
@@ -0,0 +1,24 @@
+// file : xsd/cxx/xml/dom/parsing-header.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_DOM_PARSING_HEADER_HXX
+#define XSD_CXX_XML_DOM_PARSING_HEADER_HXX
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ template <typename C>
+ class parser;
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_XML_DOM_PARSING_HEADER_HXX
diff --git a/libxsd/xsd/cxx/xml/dom/parsing-source.hxx b/libxsd/xsd/cxx/xml/dom/parsing-source.hxx
new file mode 100644
index 0000000..b6abd58
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/parsing-source.hxx
@@ -0,0 +1,138 @@
+// file : xsd/cxx/xml/dom/parsing-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_DOM_PARSING_SOURCE_HXX
+#define XSD_CXX_XML_DOM_PARSING_SOURCE_HXX
+
+#include <string>
+
+#include <xercesc/dom/DOMNode.hpp>
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMElement.hpp>
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xercesc/dom/DOMNamedNodeMap.hpp>
+#include <xercesc/dom/DOMErrorHandler.hpp>
+
+#include <xercesc/sax/InputSource.hpp>
+
+#include <xsd/cxx/xml/elements.hxx> // properies
+#include <xsd/cxx/xml/error-handler.hxx>
+
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+#include <xsd/cxx/xml/dom/elements.hxx> // name
+#include <xsd/cxx/xml/dom/parsing-header.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ // Parser state object. Can be used for parsing element, attributes,
+ // or both.
+ //
+ template <typename C>
+ class parser
+ {
+ public:
+ parser (const xercesc::DOMElement& e, bool ep, bool ap);
+
+ bool
+ more_elements ()
+ {
+ return next_element_ != 0;
+ }
+
+ const xercesc::DOMElement&
+ cur_element ()
+ {
+ return *static_cast<const xercesc::DOMElement*> (next_element_);
+ }
+
+ void
+ next_element ();
+
+ bool
+ more_attributes ()
+ {
+ return as_ > ai_;
+ }
+
+ const xercesc::DOMAttr&
+ next_attribute ()
+ {
+ return *static_cast<const xercesc::DOMAttr*> (a_->item (ai_++));
+ }
+
+ void
+ reset_attributes ()
+ {
+ ai_ = 0;
+ }
+
+ const xercesc::DOMElement&
+ element () const
+ {
+ return element_;
+ }
+
+ private:
+ parser (const parser&);
+
+ parser&
+ operator= (const parser&);
+
+ private:
+ const xercesc::DOMElement& element_;
+ const xercesc::DOMNode* next_element_;
+
+ const xercesc::DOMNamedNodeMap* a_;
+ XMLSize_t ai_; // Index of the next DOMAttr.
+ XMLSize_t as_; // Cached size of a_.
+ };
+
+
+ // Parsing flags.
+ //
+ const unsigned long dont_validate = 0x00000400UL;
+ const unsigned long no_muliple_imports = 0x00000800UL;
+
+ template <typename C>
+ xml::dom::auto_ptr<xercesc::DOMDocument>
+ parse (xercesc::InputSource&,
+ error_handler<C>&,
+ const properties<C>&,
+ unsigned long flags);
+
+ template <typename C>
+ xml::dom::auto_ptr<xercesc::DOMDocument>
+ parse (xercesc::InputSource&,
+ xercesc::DOMErrorHandler&,
+ const properties<C>&,
+ unsigned long flags);
+
+ template <typename C>
+ xml::dom::auto_ptr<xercesc::DOMDocument>
+ parse (const std::basic_string<C>& uri,
+ error_handler<C>&,
+ const properties<C>&,
+ unsigned long flags);
+
+ template <typename C>
+ xml::dom::auto_ptr<xercesc::DOMDocument>
+ parse (const std::basic_string<C>& uri,
+ xercesc::DOMErrorHandler&,
+ const properties<C>&,
+ unsigned long flags);
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/xml/dom/parsing-source.txx>
+
+#endif // XSD_CXX_XML_DOM_PARSING_SOURCE_HXX
diff --git a/libxsd/xsd/cxx/xml/dom/parsing-source.txx b/libxsd/xsd/cxx/xml/dom/parsing-source.txx
new file mode 100644
index 0000000..ae7ceea
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/parsing-source.txx
@@ -0,0 +1,458 @@
+// file : xsd/cxx/xml/dom/parsing-source.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#if _XERCES_VERSION >= 30000
+# include <xercesc/dom/DOMLSParser.hpp>
+#else
+# include <xercesc/dom/DOMBuilder.hpp>
+#endif
+#include <xercesc/dom/DOMNamedNodeMap.hpp>
+#include <xercesc/dom/DOMImplementation.hpp>
+#include <xercesc/dom/DOMImplementationRegistry.hpp>
+
+#include <xercesc/util/XMLUni.hpp> // xercesc::fg*
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_L, etc
+
+#include <xercesc/framework/Wrapper4InputSource.hpp>
+
+#include <xsd/cxx/xml/string.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ // parser
+ //
+ template <typename C>
+ parser<C>::
+ parser (const xercesc::DOMElement& e, bool ep, bool ap)
+ : element_ (e),
+ next_element_ (0),
+ a_ (0),
+ ai_ (0)
+ {
+ using xercesc::DOMNode;
+
+ if (ep)
+ {
+ for (next_element_ = e.getFirstChild ();
+ next_element_ != 0 &&
+ next_element_->getNodeType () != DOMNode::ELEMENT_NODE;
+ next_element_ = next_element_->getNextSibling ()) /*noop*/;
+ }
+
+ if (ap)
+ {
+ a_ = e.getAttributes ();
+ as_ = a_->getLength ();
+ }
+ }
+
+ template <typename C>
+ void parser<C>::
+ next_element ()
+ {
+ using xercesc::DOMNode;
+
+ for (next_element_ = next_element_->getNextSibling ();
+ next_element_ != 0 &&
+ next_element_->getNodeType () != DOMNode::ELEMENT_NODE;
+ next_element_ = next_element_->getNextSibling ())/*noop*/;
+ }
+
+ // parse()
+ //
+ template <typename C>
+ xml::dom::auto_ptr<xercesc::DOMDocument>
+ parse (xercesc::InputSource& is,
+ error_handler<C>& eh,
+ const properties<C>& prop,
+ unsigned long flags)
+ {
+ bits::error_handler_proxy<C> ehp (eh);
+ return xml::dom::parse (is, ehp, prop, flags);
+ }
+
+ template <typename C>
+ auto_ptr<xercesc::DOMDocument>
+ parse (xercesc::InputSource& is,
+ xercesc::DOMErrorHandler& eh,
+ const properties<C>& prop,
+ unsigned long flags)
+ {
+ // HP aCC cannot handle using namespace xercesc;
+ //
+ using xercesc::DOMImplementationRegistry;
+ using xercesc::DOMImplementationLS;
+ using xercesc::DOMImplementation;
+ using xercesc::DOMDocument;
+#if _XERCES_VERSION >= 30000
+ using xercesc::DOMLSParser;
+ using xercesc::DOMConfiguration;
+#else
+ using xercesc::DOMBuilder;
+#endif
+
+ using xercesc::Wrapper4InputSource;
+ using xercesc::XMLUni;
+
+
+ // Instantiate the DOM parser.
+ //
+ const XMLCh ls_id[] = {xercesc::chLatin_L,
+ xercesc::chLatin_S,
+ xercesc::chNull};
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+#if _XERCES_VERSION >= 30000
+ auto_ptr<DOMLSParser> parser (
+ impl->createLSParser (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ if (flags & dont_validate)
+ {
+ conf->setParameter (XMLUni::fgDOMValidate, false);
+ conf->setParameter (XMLUni::fgXercesSchema, false);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+ else
+ {
+ conf->setParameter (XMLUni::fgDOMValidate, true);
+ conf->setParameter (XMLUni::fgXercesSchema, true);
+
+ if (!(flags & no_muliple_imports))
+ conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+
+ // This feature checks the schema grammar for additional
+ // errors. We most likely do not need it when validating
+ // instances (assuming the schema is valid).
+ //
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+
+ // We will release DOM ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+
+ // Transfer properies if any.
+ //
+
+ if (!prop.schema_location ().empty ())
+ {
+ xml::string sl (prop.schema_location ());
+ const void* v (sl.c_str ());
+
+ conf->setParameter (
+ XMLUni::fgXercesSchemaExternalSchemaLocation,
+ const_cast<void*> (v));
+ }
+
+ if (!prop.no_namespace_schema_location ().empty ())
+ {
+ xml::string sl (prop.no_namespace_schema_location ());
+ const void* v (sl.c_str ());
+
+ conf->setParameter (
+ XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
+ const_cast<void*> (v));
+ }
+
+ // Set error handler.
+ //
+ bits::error_handler_proxy<C> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+#else // _XERCES_VERSION >= 30000
+
+ // Same as above but for Xerces-C++ 2 series.
+ //
+ auto_ptr<DOMBuilder> parser (
+ impl->createDOMBuilder (DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ parser->setFeature (XMLUni::fgDOMComments, false);
+ parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
+ parser->setFeature (XMLUni::fgDOMEntities, false);
+ parser->setFeature (XMLUni::fgDOMNamespaces, true);
+ parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false);
+
+ if (flags & dont_validate)
+ {
+ parser->setFeature (XMLUni::fgDOMValidation, false);
+ parser->setFeature (XMLUni::fgXercesSchema, false);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+ else
+ {
+ parser->setFeature (XMLUni::fgDOMValidation, true);
+ parser->setFeature (XMLUni::fgXercesSchema, true);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+
+ parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ if (!prop.schema_location ().empty ())
+ {
+ xml::string sl (prop.schema_location ());
+ const void* v (sl.c_str ());
+
+ parser->setProperty (
+ XMLUni::fgXercesSchemaExternalSchemaLocation,
+ const_cast<void*> (v));
+ }
+
+ if (!prop.no_namespace_schema_location ().empty ())
+ {
+ xml::string sl (prop.no_namespace_schema_location ());
+ const void* v (sl.c_str ());
+
+ parser->setProperty (
+ XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
+ const_cast<void*> (v));
+ }
+
+ bits::error_handler_proxy<C> ehp (eh);
+ parser->setErrorHandler (&ehp);
+
+#endif // _XERCES_VERSION >= 30000
+
+ xercesc::Wrapper4InputSource wrap (&is, false);
+
+#if _XERCES_VERSION >= 30000
+ auto_ptr<DOMDocument> doc (parser->parse (&wrap));
+#else
+ auto_ptr<DOMDocument> doc (parser->parse (wrap));
+#endif
+ if (ehp.failed ())
+ doc.reset ();
+
+ return doc;
+ }
+
+ template <typename C>
+ xml::dom::auto_ptr<xercesc::DOMDocument>
+ parse (const std::basic_string<C>& uri,
+ error_handler<C>& eh,
+ const properties<C>& prop,
+ unsigned long flags)
+ {
+ bits::error_handler_proxy<C> ehp (eh);
+ return xml::dom::parse (uri, ehp, prop, flags);
+ }
+
+ template <typename C>
+ auto_ptr<xercesc::DOMDocument>
+ parse (const std::basic_string<C>& uri,
+ xercesc::DOMErrorHandler& eh,
+ const properties<C>& prop,
+ unsigned long flags)
+ {
+ // HP aCC cannot handle using namespace xercesc;
+ //
+ using xercesc::DOMImplementationRegistry;
+ using xercesc::DOMImplementationLS;
+ using xercesc::DOMImplementation;
+ using xercesc::DOMDocument;
+#if _XERCES_VERSION >= 30000
+ using xercesc::DOMLSParser;
+ using xercesc::DOMConfiguration;
+#else
+ using xercesc::DOMBuilder;
+#endif
+ using xercesc::XMLUni;
+
+
+ // Instantiate the DOM parser.
+ //
+ const XMLCh ls_id[] = {xercesc::chLatin_L,
+ xercesc::chLatin_S,
+ xercesc::chNull};
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls_id));
+
+#if _XERCES_VERSION >= 30000
+ auto_ptr<DOMLSParser> parser (
+ impl->createLSParser(DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ DOMConfiguration* conf (parser->getDomConfig ());
+
+ // Discard comment nodes in the document.
+ //
+ conf->setParameter (XMLUni::fgDOMComments, false);
+
+ // Enable datatype normalization.
+ //
+ conf->setParameter (XMLUni::fgDOMDatatypeNormalization, true);
+
+ // Do not create EntityReference nodes in the DOM tree. No
+ // EntityReference nodes will be created, only the nodes
+ // corresponding to their fully expanded substitution text
+ // will be created.
+ //
+ conf->setParameter (XMLUni::fgDOMEntities, false);
+
+ // Perform namespace processing.
+ //
+ conf->setParameter (XMLUni::fgDOMNamespaces, true);
+
+ // Do not include ignorable whitespace in the DOM tree.
+ //
+ conf->setParameter (XMLUni::fgDOMElementContentWhitespace, false);
+
+ if (flags & dont_validate)
+ {
+ conf->setParameter (XMLUni::fgDOMValidate, false);
+ conf->setParameter (XMLUni::fgXercesSchema, false);
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+ else
+ {
+ conf->setParameter (XMLUni::fgDOMValidate, true);
+ conf->setParameter (XMLUni::fgXercesSchema, true);
+
+ if (!(flags & no_muliple_imports))
+ conf->setParameter (XMLUni::fgXercesHandleMultipleImports, true);
+
+ // This feature checks the schema grammar for additional
+ // errors. We most likely do not need it when validating
+ // instances (assuming the schema is valid).
+ //
+ conf->setParameter (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+
+ // We will release DOM ourselves.
+ //
+ conf->setParameter (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+
+ // Transfer properies if any.
+ //
+
+ if (!prop.schema_location ().empty ())
+ {
+ xml::string sl (prop.schema_location ());
+ const void* v (sl.c_str ());
+
+ conf->setParameter (
+ XMLUni::fgXercesSchemaExternalSchemaLocation,
+ const_cast<void*> (v));
+ }
+
+ if (!prop.no_namespace_schema_location ().empty ())
+ {
+ xml::string sl (prop.no_namespace_schema_location ());
+ const void* v (sl.c_str ());
+
+ conf->setParameter (
+ XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
+ const_cast<void*> (v));
+ }
+
+ // Set error handler.
+ //
+ bits::error_handler_proxy<C> ehp (eh);
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+#else // _XERCES_VERSION >= 30000
+
+ // Same as above but for Xerces-C++ 2 series.
+ //
+ auto_ptr<DOMBuilder> parser (
+ impl->createDOMBuilder(DOMImplementationLS::MODE_SYNCHRONOUS, 0));
+
+ parser->setFeature (XMLUni::fgDOMComments, false);
+ parser->setFeature (XMLUni::fgDOMDatatypeNormalization, true);
+ parser->setFeature (XMLUni::fgDOMEntities, false);
+ parser->setFeature (XMLUni::fgDOMNamespaces, true);
+ parser->setFeature (XMLUni::fgDOMWhitespaceInElementContent, false);
+
+ if (flags & dont_validate)
+ {
+ parser->setFeature (XMLUni::fgDOMValidation, false);
+ parser->setFeature (XMLUni::fgXercesSchema, false);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+ else
+ {
+ parser->setFeature (XMLUni::fgDOMValidation, true);
+ parser->setFeature (XMLUni::fgXercesSchema, true);
+ parser->setFeature (XMLUni::fgXercesSchemaFullChecking, false);
+ }
+
+ parser->setFeature (XMLUni::fgXercesUserAdoptsDOMDocument, true);
+
+ if (!prop.schema_location ().empty ())
+ {
+ xml::string sl (prop.schema_location ());
+ const void* v (sl.c_str ());
+
+ parser->setProperty (
+ XMLUni::fgXercesSchemaExternalSchemaLocation,
+ const_cast<void*> (v));
+ }
+
+ if (!prop.no_namespace_schema_location ().empty ())
+ {
+ xml::string sl (prop.no_namespace_schema_location ());
+ const void* v (sl.c_str ());
+
+ parser->setProperty (
+ XMLUni::fgXercesSchemaExternalNoNameSpaceSchemaLocation,
+ const_cast<void*> (v));
+ }
+
+ bits::error_handler_proxy<C> ehp (eh);
+ parser->setErrorHandler (&ehp);
+
+#endif // _XERCES_VERSION >= 30000
+
+ auto_ptr<DOMDocument> doc (
+ parser->parseURI (string (uri).c_str ()));
+
+ if (ehp.failed ())
+ doc.reset ();
+
+ return doc;
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/xml/dom/serialization-header.hxx b/libxsd/xsd/cxx/xml/dom/serialization-header.hxx
new file mode 100644
index 0000000..c8d836c
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/serialization-header.hxx
@@ -0,0 +1,81 @@
+// file : xsd/cxx/xml/dom/serialization-header.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_DOM_SERIALIZATION_HEADER_HXX
+#define XSD_CXX_XML_DOM_SERIALIZATION_HEADER_HXX
+
+#include <map>
+#include <string>
+
+#include <xercesc/dom/DOMElement.hpp>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ // Find an existing prefix or establish a new one. Try to use
+ // hint if provided and available.
+ //
+ template <typename C>
+ std::basic_string<C>
+ prefix (const C* ns, xercesc::DOMElement&, const C* hint = 0);
+
+ template <typename C>
+ inline std::basic_string<C>
+ prefix (const std::basic_string<C>& ns,
+ xercesc::DOMElement& e,
+ const C* hint = 0)
+ {
+ return prefix (ns.c_str (), e, hint);
+ }
+
+ //
+ //
+ template <typename C>
+ void
+ clear (xercesc::DOMElement&);
+
+ //
+ //
+ template <typename C>
+ class namespace_info
+ {
+ public:
+ typedef std::basic_string<C> string;
+
+ namespace_info ()
+ {
+ }
+
+ namespace_info (const string& name_, const string& schema_)
+ : name (name_),
+ schema (schema_)
+ {
+ }
+
+ std::basic_string<C> name;
+ std::basic_string<C> schema;
+ };
+
+
+ // Map of namespace prefix to namespace_info.
+ //
+ template <typename C>
+ class namespace_infomap:
+ public std::map<std::basic_string<C>, namespace_info<C> >
+ {
+ };
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/xml/dom/serialization-header.txx>
+
+#endif // XSD_CXX_XML_DOM_SERIALIZATION_HEADER_HXX
diff --git a/libxsd/xsd/cxx/xml/dom/serialization-header.txx b/libxsd/xsd/cxx/xml/dom/serialization-header.txx
new file mode 100644
index 0000000..76d3d43
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/serialization-header.txx
@@ -0,0 +1,192 @@
+// file : xsd/cxx/xml/dom/serialization-header.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <vector>
+#include <sstream>
+#include <cstddef> // std::size_t
+
+#include <xercesc/dom/DOMNode.hpp>
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMNamedNodeMap.hpp>
+
+#include <xercesc/util/XMLUni.hpp> // xercesc::fg*
+#include <xercesc/util/XMLString.hpp>
+#include <xercesc/validators/schema/SchemaSymbols.hpp>
+
+#include <xsd/cxx/xml/string.hxx>
+#include <xsd/cxx/xml/bits/literals.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ //
+ //
+ template <typename C>
+ std::basic_string<C>
+ prefix (const C* ns, xercesc::DOMElement& e, const C* hint)
+ {
+ string xns (ns);
+
+#if _XERCES_VERSION >= 30000
+ const XMLCh* p (e.lookupPrefix (xns.c_str ()));
+#else
+ const XMLCh* p (e.lookupNamespacePrefix (xns.c_str (), false));
+#endif
+ if (p != 0)
+ return transcode<C> (p);
+
+ if (e.isDefaultNamespace (xns.c_str ()))
+ return std::basic_string<C> ();
+
+ // 'xml' prefix requires special handling and Xerces folks
+ // refuse to handle this in DOM so I have to do it myself.
+ //
+ if (std::basic_string<C> (ns) == xml::bits::xml_namespace<C> ())
+ return xml::bits::xml_prefix<C> ();
+
+ // No prefix for this namespace. Will need to establish one.
+ //
+ std::basic_string<C> prefix;
+
+ if (hint != 0 &&
+ e.lookupNamespaceURI (xml::string (hint).c_str ()) == 0)
+ {
+ prefix = hint;
+ }
+ else
+ {
+ for (unsigned long n (1);; ++n)
+ {
+ // Make finding the first few prefixes fast.
+ //
+ switch (n)
+ {
+ case 1:
+ {
+ prefix = xml::bits::first_prefix<C> ();
+ break;
+ }
+ case 2:
+ {
+ prefix = xml::bits::second_prefix<C> ();
+ break;
+ }
+ case 3:
+ {
+ prefix = xml::bits::third_prefix<C> ();
+ break;
+ }
+ case 4:
+ {
+ prefix = xml::bits::fourth_prefix<C> ();
+ break;
+ }
+ case 5:
+ {
+ prefix = xml::bits::fifth_prefix<C> ();
+ break;
+ }
+ default:
+ {
+ std::basic_ostringstream<C> ostr;
+ ostr << C ('p') << n;
+ prefix = ostr.str ();
+ break;
+ }
+ }
+
+ if (e.lookupNamespaceURI (xml::string (prefix).c_str ()) == 0)
+ break;
+ }
+ }
+
+ std::basic_string<C> name (xml::bits::xmlns_prefix<C> ());
+ name += C(':');
+ name += prefix;
+
+ e.setAttributeNS (
+ xercesc::XMLUni::fgXMLNSURIName,
+ xml::string (name).c_str (),
+ xns.c_str ());
+
+ return prefix;
+ }
+
+ //
+ //
+ template <typename C>
+ void
+ clear (xercesc::DOMElement& e)
+ {
+ // HP aCC cannot handle using namespace xercesc;
+ //
+ using xercesc::DOMNode;
+ using xercesc::DOMAttr;
+ using xercesc::DOMNamedNodeMap;
+ using xercesc::XMLString;
+ using xercesc::SchemaSymbols;
+
+ // Remove child nodes.
+ //
+ while (xercesc::DOMNode* n = e.getFirstChild ())
+ {
+ e.removeChild (n);
+ n->release ();
+ }
+
+ // Remove attributes.
+ //
+ DOMNamedNodeMap* att_map (e.getAttributes ());
+ XMLSize_t n (att_map->getLength ());
+
+ if (n != 0)
+ {
+ std::vector<DOMAttr*> atts;
+
+ // Collect all attributes to be removed while filtering
+ // out special cases (xmlns & xsi).
+ //
+ for (XMLSize_t i (0); i != n; ++i)
+ {
+ DOMAttr* a (static_cast<DOMAttr*> (att_map->item (i)));
+ const XMLCh* ns (a->getNamespaceURI ());
+
+ if (ns != 0)
+ {
+ if (XMLString::equals (ns, xercesc::XMLUni::fgXMLNSURIName))
+ continue;
+
+ if (XMLString::equals (ns, SchemaSymbols::fgURI_XSI))
+ {
+ const XMLCh* name (a->getLocalName ());
+
+ if (XMLString::equals (
+ name, SchemaSymbols::fgXSI_SCHEMALOCACTION) ||
+ XMLString::equals (
+ name, SchemaSymbols::fgXSI_NONAMESPACESCHEMALOCACTION))
+ continue;
+ }
+ }
+
+ atts.push_back (a);
+ }
+
+ for (std::vector<DOMAttr*>::iterator i (atts.begin ()),
+ end (atts.end ()); i != end; ++i)
+ {
+ e.removeAttributeNode (*i);
+ (*i)->release ();
+ }
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/xml/dom/serialization-source.hxx b/libxsd/xsd/cxx/xml/dom/serialization-source.hxx
new file mode 100644
index 0000000..4593f9c
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/serialization-source.hxx
@@ -0,0 +1,152 @@
+// file : xsd/cxx/xml/dom/serialization-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_DOM_SERIALIZATION_SOURCE_HXX
+#define XSD_CXX_XML_DOM_SERIALIZATION_SOURCE_HXX
+
+#include <string>
+#include <ostream>
+
+#include <xercesc/dom/DOMAttr.hpp>
+#include <xercesc/dom/DOMElement.hpp>
+#include <xercesc/dom/DOMDocument.hpp>
+#include <xercesc/dom/DOMErrorHandler.hpp>
+#include <xercesc/framework/XMLFormatter.hpp> // XMLFormatTarget, XMLFormatter
+
+#include <xsd/cxx/xml/error-handler.hxx>
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+#include <xsd/cxx/xml/dom/elements.hxx> // name
+#include <xsd/cxx/xml/dom/serialization-header.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ //
+ //
+ template <typename C>
+ xercesc::DOMAttr&
+ create_attribute (const C* name, xercesc::DOMElement&);
+
+ template <typename C>
+ xercesc::DOMAttr&
+ create_attribute (const C* name, const C* ns, xercesc::DOMElement&);
+
+ template <typename C>
+ xercesc::DOMElement&
+ create_element (const C* name, xercesc::DOMElement&);
+
+ template <typename C>
+ xercesc::DOMElement&
+ create_element (const C* name, const C* ns, xercesc::DOMElement&);
+
+ // Serialization flags.
+ //
+ const unsigned long no_xml_declaration = 0x00010000UL;
+ const unsigned long dont_pretty_print = 0x00020000UL;
+
+ template <typename C>
+ xml::dom::auto_ptr<xercesc::DOMDocument>
+ serialize (const std::basic_string<C>& root_element,
+ const std::basic_string<C>& root_element_namespace,
+ const namespace_infomap<C>& map,
+ unsigned long flags);
+
+ // This one helps Sun C++ to overcome its fears.
+ //
+ template <typename C>
+ inline xml::dom::auto_ptr<xercesc::DOMDocument>
+ serialize (const C* root_element,
+ const C* root_element_namespace,
+ const namespace_infomap<C>& map,
+ unsigned long flags)
+ {
+ return serialize (std::basic_string<C> (root_element),
+ std::basic_string<C> (root_element_namespace),
+ map,
+ flags);
+ }
+
+ //
+ //
+ template <typename C>
+ bool
+ serialize (xercesc::XMLFormatTarget& target,
+ const xercesc::DOMDocument& doc,
+ const std::basic_string<C>& enconding,
+ error_handler<C>& eh,
+ unsigned long flags);
+
+ template <typename C>
+ bool
+ serialize (xercesc::XMLFormatTarget& target,
+ const xercesc::DOMDocument& doc,
+ const std::basic_string<C>& enconding,
+ xercesc::DOMErrorHandler& eh,
+ unsigned long flags);
+
+ //
+ //
+ class ostream_format_target: public xercesc::XMLFormatTarget
+ {
+ public:
+ ostream_format_target (std::ostream& os)
+ : os_ (os)
+ {
+ }
+
+
+ public:
+ // I know, some of those consts are stupid. But that's what
+ // Xerces folks put into their interfaces and VC-7.1 thinks
+ // there are different signatures if one strips this fluff off.
+ //
+ virtual void
+ writeChars (const XMLByte* const buf,
+#if _XERCES_VERSION >= 30000
+ const XMLSize_t size,
+#else
+ const unsigned int size,
+#endif
+ xercesc::XMLFormatter* const)
+ {
+ // Ignore the data if there was a stream failure and
+ // the stream is not using exceptions.
+ //
+ if (!(os_.bad () || os_.fail ()))
+ {
+ os_.write (reinterpret_cast<const char*> (buf),
+ static_cast<std::streamsize> (size));
+ }
+ }
+
+
+ virtual void
+ flush ()
+ {
+ // Ignore the flush request if there was a stream failure
+ // and the stream is not using exceptions.
+ //
+ if (!(os_.bad () || os_.fail ()))
+ {
+ os_.flush ();
+ }
+ }
+
+ private:
+ std::ostream& os_;
+ };
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/xml/dom/serialization-source.txx>
+
+#endif // XSD_CXX_XML_DOM_SERIALIZATION_SOURCE_HXX
diff --git a/libxsd/xsd/cxx/xml/dom/serialization-source.txx b/libxsd/xsd/cxx/xml/dom/serialization-source.txx
new file mode 100644
index 0000000..5aaaaed
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/serialization-source.txx
@@ -0,0 +1,394 @@
+// file : xsd/cxx/xml/dom/serialization-source.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xercesc/util/XMLUni.hpp> // xercesc::fg*
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_L, etc
+#include <xercesc/validators/schema/SchemaSymbols.hpp>
+
+#if _XERCES_VERSION >= 30000
+# include <xercesc/dom/DOMLSOutput.hpp>
+# include <xercesc/dom/DOMLSSerializer.hpp>
+#else
+# include <xercesc/dom/DOMWriter.hpp>
+#endif
+#include <xercesc/dom/DOMElement.hpp>
+#include <xercesc/dom/DOMImplementation.hpp>
+#include <xercesc/dom/DOMImplementationRegistry.hpp>
+
+#include <xsd/cxx/xml/string.hxx>
+#include <xsd/cxx/xml/bits/literals.hxx>
+#include <xsd/cxx/xml/dom/bits/error-handler-proxy.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ //
+ //
+ template <typename C>
+ xercesc::DOMAttr&
+ create_attribute (const C* name, xercesc::DOMElement& parent)
+ {
+ xercesc::DOMDocument* doc (parent.getOwnerDocument ());
+ xercesc::DOMAttr* a (doc->createAttribute (string (name).c_str ()));
+ parent.setAttributeNode (a);
+ return *a;
+ }
+
+ template <typename C>
+ xercesc::DOMAttr&
+ create_attribute (const C* name,
+ const C* ns,
+ xercesc::DOMElement& parent)
+ {
+ if (ns[0] == C ('\0'))
+ return create_attribute (name, parent);
+
+ xercesc::DOMDocument* doc (parent.getOwnerDocument ());
+
+ xercesc::DOMAttr* a;
+ std::basic_string<C> p (prefix<C> (ns, parent));
+
+ if (!p.empty ())
+ {
+ p += ':';
+ p += name;
+ a = doc->createAttributeNS (string (ns).c_str (),
+ string (p).c_str ());
+ }
+ else
+ a = doc->createAttributeNS (string (ns).c_str (),
+ string (name).c_str ());
+
+ parent.setAttributeNodeNS (a);
+ return *a;
+ }
+
+ template <typename C>
+ xercesc::DOMElement&
+ create_element (const C* name, xercesc::DOMElement& parent)
+ {
+ xercesc::DOMDocument* doc (parent.getOwnerDocument ());
+ xercesc::DOMElement* e (doc->createElement (string (name).c_str ()));
+ parent.appendChild (e);
+ return *e;
+ }
+
+ template <typename C>
+ xercesc::DOMElement&
+ create_element (const C* name,
+ const C* ns,
+ xercesc::DOMElement& parent)
+ {
+ if (ns[0] == C ('\0'))
+ return create_element (name, parent);
+
+ xercesc::DOMDocument* doc (parent.getOwnerDocument ());
+
+ xercesc::DOMElement* e;
+ std::basic_string<C> p (prefix<C> (ns, parent));
+
+ if (!p.empty ())
+ {
+ p += ':';
+ p += name;
+ e = doc->createElementNS (string (ns).c_str (),
+ string (p).c_str ());
+ }
+ else
+ e = doc->createElementNS (string (ns).c_str (),
+ string (name).c_str ());
+
+ parent.appendChild (e);
+ return *e;
+ }
+
+
+ //
+ //
+ template <typename C>
+ auto_ptr<xercesc::DOMDocument>
+ serialize (const std::basic_string<C>& el,
+ const std::basic_string<C>& ns,
+ const namespace_infomap<C>& map,
+ unsigned long)
+ {
+ // HP aCC cannot handle using namespace xercesc;
+ //
+ using xercesc::DOMImplementationRegistry;
+ using xercesc::DOMImplementation;
+ using xercesc::DOMDocument;
+ using xercesc::DOMElement;
+
+ //
+ //
+ typedef std::basic_string<C> string;
+ typedef namespace_infomap<C> infomap;
+ typedef typename infomap::const_iterator infomap_iterator;
+
+ C colon (':'), space (' ');
+
+ string prefix;
+
+ if (!ns.empty ())
+ {
+ infomap_iterator i (map.begin ()), e (map.end ());
+
+ for ( ;i != e; ++i)
+ {
+ if (i->second.name == ns)
+ {
+ prefix = i->first;
+ break;
+ }
+ }
+
+ // Since this is the first namespace in document we don't
+ // need to worry about conflicts.
+ //
+ if (i == e)
+ prefix = xml::bits::first_prefix<C> ();
+ }
+
+ const XMLCh ls[] = {xercesc::chLatin_L,
+ xercesc::chLatin_S,
+ xercesc::chNull};
+
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls));
+
+ auto_ptr<DOMDocument> doc (
+ impl->createDocument (
+ (ns.empty () ? 0 : xml::string (ns).c_str ()),
+ xml::string ((prefix.empty ()
+ ? el
+ : prefix + colon + el)).c_str (),
+ 0));
+
+ DOMElement* root (doc->getDocumentElement ());
+
+ // Check if we need to provide xsi mapping.
+ //
+ bool xsi (false);
+ string xsi_prefix;
+ string xmlns_prefix (xml::bits::xmlns_prefix<C> ());
+
+ for (infomap_iterator i (map.begin ()), e (map.end ()); i != e; ++i)
+ {
+ if (!i->second.schema.empty ())
+ {
+ xsi = true;
+ break;
+ }
+ }
+
+ // Check if we were told to provide xsi mapping.
+ //
+ if (xsi)
+ {
+ for (infomap_iterator i (map.begin ()), e (map.end ());
+ i != e;
+ ++i)
+ {
+ if (i->second.name == xml::bits::xsi_namespace<C> ())
+ {
+ xsi_prefix = i->first;
+ xsi = false;
+ break;
+ }
+ }
+ }
+
+ // Create user-defined mappings.
+ //
+ for (infomap_iterator i (map.begin ()), e (map.end ()); i != e; ++i)
+ {
+ if (i->first.empty ())
+ {
+ // Empty prefix.
+ //
+ if (!i->second.name.empty ())
+ root->setAttributeNS (
+ xercesc::XMLUni::fgXMLNSURIName,
+ xml::string (xmlns_prefix).c_str (),
+ xml::string (i->second.name).c_str ());
+ }
+ else
+ {
+ root->setAttributeNS (
+ xercesc::XMLUni::fgXMLNSURIName,
+ xml::string (xmlns_prefix + colon + i->first).c_str (),
+ xml::string (i->second.name).c_str ());
+ }
+ }
+
+ // If we were not told to provide xsi mapping but we need it
+ // then we will have to add it ourselves.
+ //
+ if (xsi)
+ xsi_prefix = dom::prefix (xml::bits::xsi_namespace<C> (),
+ *root,
+ xml::bits::xsi_prefix<C> ());
+
+ // Create xsi:schemaLocation and xsi:noNamespaceSchemaLocation
+ // attributes.
+ //
+ string schema_location;
+ string no_namespace_schema_location;
+
+ for (infomap_iterator i (map.begin ()), e (map.end ()); i != e; ++i)
+ {
+ if (!i->second.schema.empty ())
+ {
+ if (i->second.name.empty ())
+ {
+ if (!no_namespace_schema_location.empty ())
+ no_namespace_schema_location += space;
+
+ no_namespace_schema_location += i->second.schema;
+ }
+ else
+ {
+ if (!schema_location.empty ())
+ schema_location += space;
+
+ schema_location += i->second.name + space + i->second.schema;
+ }
+ }
+ }
+
+ if (!schema_location.empty ())
+ {
+ root->setAttributeNS (
+ xercesc::SchemaSymbols::fgURI_XSI,
+ xml::string (xsi_prefix + colon +
+ xml::bits::schema_location<C> ()).c_str (),
+ xml::string (schema_location).c_str ());
+ }
+
+ if (!no_namespace_schema_location.empty ())
+ {
+ root->setAttributeNS (
+ xercesc::SchemaSymbols::fgURI_XSI,
+ xml::string (
+ xsi_prefix + colon +
+ xml::bits::no_namespace_schema_location<C> ()).c_str (),
+ xml::string (no_namespace_schema_location).c_str ());
+ }
+
+ return doc;
+ }
+
+
+ template <typename C>
+ bool
+ serialize (xercesc::XMLFormatTarget& target,
+ const xercesc::DOMDocument& doc,
+ const std::basic_string<C>& encoding,
+ xercesc::DOMErrorHandler& eh,
+ unsigned long flags)
+ {
+ // HP aCC cannot handle using namespace xercesc;
+ //
+ using xercesc::DOMImplementationRegistry;
+ using xercesc::DOMImplementation;
+#if _XERCES_VERSION >= 30000
+ using xercesc::DOMLSSerializer;
+ using xercesc::DOMConfiguration;
+ using xercesc::DOMLSOutput;
+#else
+ using xercesc::DOMWriter;
+#endif
+ using xercesc::XMLUni;
+
+ const XMLCh ls[] = {xercesc::chLatin_L,
+ xercesc::chLatin_S,
+ xercesc::chNull};
+
+ DOMImplementation* impl (
+ DOMImplementationRegistry::getDOMImplementation (ls));
+
+ bits::error_handler_proxy<C> ehp (eh);
+
+#if _XERCES_VERSION >= 30000
+ xml::dom::auto_ptr<DOMLSSerializer> writer (
+ impl->createLSSerializer ());
+
+ DOMConfiguration* conf (writer->getDomConfig ());
+
+ conf->setParameter (XMLUni::fgDOMErrorHandler, &ehp);
+
+ // Set some nice features if the serializer supports them.
+ //
+ if (conf->canSetParameter (
+ XMLUni::fgDOMWRTDiscardDefaultContent, true))
+ conf->setParameter (XMLUni::fgDOMWRTDiscardDefaultContent, true);
+
+ if (!(flags & dont_pretty_print) &&
+ conf->canSetParameter (XMLUni::fgDOMWRTFormatPrettyPrint, true))
+ conf->setParameter (XMLUni::fgDOMWRTFormatPrettyPrint, true);
+
+ // See if we need to write XML declaration.
+ //
+ if ((flags & no_xml_declaration) &&
+ conf->canSetParameter (XMLUni::fgDOMXMLDeclaration, false))
+ conf->setParameter (XMLUni::fgDOMXMLDeclaration, false);
+
+ xml::dom::auto_ptr<DOMLSOutput> out (impl->createLSOutput ());
+
+ out->setEncoding (xml::string (encoding).c_str ());
+ out->setByteStream (&target);
+
+ bool r (writer->write (&doc, out.get ()));
+#else
+ xml::dom::auto_ptr<DOMWriter> writer (impl->createDOMWriter ());
+
+ writer->setErrorHandler (&ehp);
+ writer->setEncoding (xml::string (encoding).c_str ());
+
+ // Set some nice features if the serializer supports them.
+ //
+ if (writer->canSetFeature (
+ XMLUni::fgDOMWRTDiscardDefaultContent, true))
+ writer->setFeature (XMLUni::fgDOMWRTDiscardDefaultContent, true);
+
+ if (!(flags & dont_pretty_print) &&
+ writer->canSetFeature (XMLUni::fgDOMWRTFormatPrettyPrint, true))
+ writer->setFeature (XMLUni::fgDOMWRTFormatPrettyPrint, true);
+
+ // See if we need to write XML declaration.
+ //
+ if ((flags & no_xml_declaration) &&
+ writer->canSetFeature (XMLUni::fgDOMXMLDeclaration, false))
+ writer->setFeature (XMLUni::fgDOMXMLDeclaration, false);
+
+ bool r (writer->writeNode (&target, doc));
+#endif
+
+ if (!r || ehp.failed ())
+ return false;
+
+ return true;
+ }
+
+ template <typename C>
+ bool
+ serialize (xercesc::XMLFormatTarget& target,
+ const xercesc::DOMDocument& doc,
+ const std::basic_string<C>& enconding,
+ error_handler<C>& eh,
+ unsigned long flags)
+ {
+ bits::error_handler_proxy<C> ehp (eh);
+ return serialize (target, doc, enconding, ehp, flags);
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/xml/dom/wildcard-source.hxx b/libxsd/xsd/cxx/xml/dom/wildcard-source.hxx
new file mode 100644
index 0000000..b001f56
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/wildcard-source.hxx
@@ -0,0 +1,31 @@
+// file : xsd/cxx/xml/dom/wildcard-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_DOM_WILDCARD_SOURCE_HXX
+#define XSD_CXX_XML_DOM_WILDCARD_SOURCE_HXX
+
+#include <xercesc/dom/DOMDocument.hpp>
+
+#include <xsd/cxx/xml/dom/auto-ptr.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ template <typename C>
+ xml::dom::auto_ptr<xercesc::DOMDocument>
+ create_document ();
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/xml/dom/wildcard-source.txx>
+
+#endif // XSD_CXX_XML_DOM_WILDCARD_SOURCE_HXX
diff --git a/libxsd/xsd/cxx/xml/dom/wildcard-source.txx b/libxsd/xsd/cxx/xml/dom/wildcard-source.txx
new file mode 100644
index 0000000..dcd54d2
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/dom/wildcard-source.txx
@@ -0,0 +1,39 @@
+// file : xsd/cxx/xml/dom/wildcard-source.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xercesc/util/XMLUniDefs.hpp> // chLatin_L, etc
+
+#include <xercesc/dom/DOMImplementation.hpp>
+#include <xercesc/dom/DOMImplementationRegistry.hpp>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace dom
+ {
+ template <typename C>
+ xml::dom::auto_ptr<xercesc::DOMDocument>
+ create_document ()
+ {
+ const XMLCh ls[] = {xercesc::chLatin_L,
+ xercesc::chLatin_S,
+ xercesc::chNull};
+
+ // Get an implementation of the Load-Store (LS) interface.
+ //
+ xercesc::DOMImplementation* impl (
+ xercesc::DOMImplementationRegistry::getDOMImplementation (ls));
+
+ return xml::dom::auto_ptr<xercesc::DOMDocument> (
+ impl->createDocument ());
+ }
+ }
+ }
+ }
+}
+
diff --git a/libxsd/xsd/cxx/xml/elements.hxx b/libxsd/xsd/cxx/xml/elements.hxx
new file mode 100644
index 0000000..c64afda
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/elements.hxx
@@ -0,0 +1,113 @@
+// file : xsd/cxx/xml/elements.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_ELEMENTS_HXX
+#define XSD_CXX_XML_ELEMENTS_HXX
+
+#include <string>
+
+#include <xercesc/util/PlatformUtils.hpp>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ template <typename C>
+ class properties
+ {
+ public:
+ struct argument {};
+
+
+ // Schema location properties. Note that all locations are
+ // relative to an instance document unless they are full
+ // URIs. For example if you want to use a local schema then
+ // you will need to use 'file:///absolute/path/to/your/schema'.
+ //
+
+ // Add a location for a schema with a target namespace.
+ //
+ void
+ schema_location (const std::basic_string<C>& namespace_,
+ const std::basic_string<C>& location);
+
+ // Add a location for a schema without a target namespace.
+ //
+ void
+ no_namespace_schema_location (const std::basic_string<C>& location);
+
+ public:
+ const std::basic_string<C>&
+ schema_location () const
+ {
+ return schema_location_;
+ }
+
+ const std::basic_string<C>&
+ no_namespace_schema_location () const
+ {
+ return no_namespace_schema_location_;
+ }
+
+ private:
+ std::basic_string<C> schema_location_;
+ std::basic_string<C> no_namespace_schema_location_;
+ };
+
+
+ //
+ //
+
+ template <typename C>
+ std::basic_string<C>
+ prefix (const std::basic_string<C>& n);
+
+ template <typename C>
+ std::basic_string<C>
+ uq_name (const std::basic_string<C>& n);
+
+
+ //
+ //
+
+ inline void
+ initialize ()
+ {
+ xercesc::XMLPlatformUtils::Initialize ();
+ }
+
+ inline void
+ terminate ()
+ {
+ xercesc::XMLPlatformUtils::Terminate ();
+ }
+
+ struct auto_initializer
+ {
+ auto_initializer (bool initialize = true, bool terminate = true)
+ : terminate_ (initialize && terminate)
+ {
+ if (initialize)
+ xml::initialize ();
+ }
+
+ ~auto_initializer ()
+ {
+ if (terminate_)
+ terminate ();
+ }
+
+ private:
+ bool terminate_;
+ };
+ }
+ }
+}
+
+#include <xsd/cxx/xml/elements.txx>
+
+#endif // XSD_CXX_XML_ELEMENTS_HXX
diff --git a/libxsd/xsd/cxx/xml/elements.txx b/libxsd/xsd/cxx/xml/elements.txx
new file mode 100644
index 0000000..dca6cb2
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/elements.txx
@@ -0,0 +1,73 @@
+// file : xsd/cxx/xml/elements.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ // properties
+ //
+
+ template <typename C>
+ void properties<C>::
+ schema_location (const std::basic_string<C>& ns,
+ const std::basic_string<C>& loc)
+ {
+ if (ns.empty () || loc.empty ())
+ throw argument ();
+
+ if (!schema_location_.empty ())
+ schema_location_ += C (' ');
+
+ schema_location_ += ns + C (' ') + loc;
+ }
+
+ template <typename C>
+ void properties<C>::
+ no_namespace_schema_location (const std::basic_string<C>& loc)
+ {
+ if (loc.empty ())
+ throw argument ();
+
+ if (!no_namespace_schema_location_.empty ())
+ no_namespace_schema_location_ += C (' ');
+
+ no_namespace_schema_location_ += loc;
+ }
+
+
+ //
+ //
+
+ template <typename C>
+ std::basic_string<C>
+ prefix (const std::basic_string<C>& n)
+ {
+ std::size_t i (0);
+
+ while (i < n.length () && n[i] != ':')
+ ++i;
+
+ return std::basic_string<C> (n, i == n.length () ? i : 0, i);
+ }
+
+ template <typename C>
+ std::basic_string<C>
+ uq_name (const std::basic_string<C>& n)
+ {
+ std::size_t i (0);
+
+ while (i < n.length () && n[i] != ':')
+ ++i;
+
+ return std::basic_string<C> (
+ n.c_str () + (i == n.length () ? 0 : i + 1));
+ }
+ }
+ }
+}
+
diff --git a/libxsd/xsd/cxx/xml/error-handler.hxx b/libxsd/xsd/cxx/xml/error-handler.hxx
new file mode 100644
index 0000000..76482b7
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/error-handler.hxx
@@ -0,0 +1,60 @@
+// file : xsd/cxx/xml/error-handler.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_ERROR_HANDLER_HXX
+#define XSD_CXX_XML_ERROR_HANDLER_HXX
+
+#include <string>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ template <typename C>
+ class error_handler
+ {
+ public:
+ virtual
+ ~error_handler ()
+ {
+ }
+
+ public:
+
+ // The fatal severity level results in termination
+ // of the parsing process no matter what is returned
+ // from handle.
+ //
+ struct severity
+ {
+ enum value
+ {
+ warning,
+ error,
+ fatal
+ };
+
+ severity (value v) : v_ (v) {}
+ operator value () const { return v_; }
+
+ private:
+ value v_;
+ };
+
+ virtual bool
+ handle (const std::basic_string<C>& id,
+ unsigned long line,
+ unsigned long column,
+ severity,
+ const std::basic_string<C>& message) = 0;
+ };
+ }
+ }
+}
+
+#endif // XSD_CXX_XML_ERROR_HANDLER_HXX
+
diff --git a/libxsd/xsd/cxx/xml/qualified-name.hxx b/libxsd/xsd/cxx/xml/qualified-name.hxx
new file mode 100644
index 0000000..4c4dcd4
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/qualified-name.hxx
@@ -0,0 +1,84 @@
+// file : xsd/cxx/xml/qualified-name.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_QUALIFIED_NAME_HXX
+#define XSD_CXX_XML_QUALIFIED_NAME_HXX
+
+#include <string>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ template <typename C>
+ struct qualified_name
+ {
+ qualified_name (const C* name,
+ const C* namespace_)
+ : name_ (name), namespace__ (namespace_)
+ {
+ }
+
+ qualified_name (const std::basic_string<C>& name,
+ const std::basic_string<C>& namespace_)
+ : name_ (name), namespace__ (namespace_)
+ {
+ }
+
+ qualified_name (const C* name)
+ : name_ (name)
+ {
+ }
+
+ qualified_name (const std::basic_string<C>& name)
+ : name_ (name)
+ {
+ }
+
+ const std::basic_string<C>&
+ name () const
+ {
+ return name_;
+ }
+
+ const std::basic_string<C>&
+ namespace_ () const
+ {
+ return namespace__;
+ }
+
+ private:
+ std::basic_string<C> name_;
+ std::basic_string<C> namespace__;
+ };
+
+ template <typename C>
+ inline bool
+ operator== (const qualified_name<C>& x, const qualified_name<C>& y)
+ {
+ return x.name () == y.name () && x.namespace_ () == y.namespace_ ();
+ }
+
+ template <typename C>
+ inline bool
+ operator!= (const qualified_name<C>& x, const qualified_name<C>& y)
+ {
+ return !(x == y);
+ }
+
+ template <typename C>
+ inline bool
+ operator< (const qualified_name<C>& x, const qualified_name<C>& y)
+ {
+ int r (x.name ().compare (y.name ()));
+ return (r < 0) || (r == 0 && x.namespace_ () < y.namespace_ ());
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_XML_QUALIFIED_NAME_HXX
diff --git a/libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.hxx b/libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.hxx
new file mode 100644
index 0000000..7eca35b
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.hxx
@@ -0,0 +1,81 @@
+// file : xsd/cxx/xml/sax/bits/error-handler-proxy.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_SAX_ERROR_HANDLER_PROXY_HXX
+#define XSD_CXX_XML_SAX_ERROR_HANDLER_PROXY_HXX
+
+#include <xercesc/sax/ErrorHandler.hpp>
+#include <xercesc/sax/SAXParseException.hpp>
+
+#include <xsd/cxx/xml/error-handler.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace sax
+ {
+ namespace bits
+ {
+ template <typename C>
+ class error_handler_proxy: public xercesc::ErrorHandler
+ {
+ public:
+ error_handler_proxy (error_handler<C>& eh)
+ : failed_ (false), eh_ (&eh), native_eh_ (0)
+ {
+ }
+
+ error_handler_proxy (xercesc::ErrorHandler& eh)
+ : failed_ (false), eh_ (0), native_eh_ (&eh)
+ {
+ }
+
+ public:
+ virtual void
+ warning (const xercesc::SAXParseException& e);
+
+ virtual void
+ error (const xercesc::SAXParseException& e);
+
+ virtual void
+ fatalError (const xercesc::SAXParseException& e);
+
+ public:
+ bool
+ failed () const
+ {
+ return failed_;
+ }
+
+ virtual void
+ resetErrors()
+ {
+ failed_ = false;
+ }
+
+ private:
+ typedef typename error_handler<C>::severity severity;
+
+ void
+ handle (const xercesc::SAXParseException&, severity);
+
+ private:
+ bool failed_;
+ error_handler<C>* eh_;
+ xercesc::ErrorHandler* native_eh_;
+ };
+ }
+ }
+ }
+ }
+}
+
+#include <xsd/cxx/xml/sax/bits/error-handler-proxy.txx>
+
+#endif // XSD_CXX_XML_SAX_ERROR_HANDLER_PROXY_HXX
+
diff --git a/libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.txx b/libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.txx
new file mode 100644
index 0000000..dcf2091
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/sax/bits/error-handler-proxy.txx
@@ -0,0 +1,89 @@
+// file : xsd/cxx/xml/sax/bits/error-handler-proxy.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <xsd/cxx/xml/string.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace sax
+ {
+ namespace bits
+ {
+ template <typename C>
+ void error_handler_proxy<C>::
+ warning (const xercesc::SAXParseException& e)
+ {
+ if (native_eh_)
+ native_eh_->warning (e);
+ else
+ handle (e, severity::warning);
+ }
+
+
+ template <typename C>
+ void error_handler_proxy<C>::
+ error (const xercesc::SAXParseException& e)
+ {
+ failed_ = true;
+
+ if (native_eh_)
+ native_eh_->error (e);
+ else
+ handle (e, severity::error);
+ }
+
+
+ template <typename C>
+ void error_handler_proxy<C>::
+ fatalError (const xercesc::SAXParseException& e)
+ {
+ failed_ = true;
+
+ if (native_eh_)
+ native_eh_->fatalError (e);
+ else
+ handle (e, severity::fatal);
+ }
+
+
+ template <typename C>
+ void error_handler_proxy<C>::
+ handle (const xercesc::SAXParseException& e, severity s)
+ {
+ //@@ I do not honor return values from the handler. This
+ // is not too bad at the moment because I set
+ // all-errors-are-fatal flag on the parser.
+ //
+ const XMLCh* id (e.getPublicId ());
+
+ if (id == 0)
+ id = e.getSystemId ();
+
+#if _XERCES_VERSION >= 30000
+ eh_->handle (transcode<C> (id),
+ static_cast<unsigned long> (e.getLineNumber ()),
+ static_cast<unsigned long> (e.getColumnNumber ()),
+ s,
+ transcode<C> (e.getMessage ()));
+#else
+ XMLSSize_t l (e.getLineNumber ());
+ XMLSSize_t c (e.getColumnNumber ());
+
+ eh_->handle (transcode<C> (id),
+ (l == -1 ? 0 : static_cast<unsigned long> (l)),
+ (c == -1 ? 0 : static_cast<unsigned long> (c)),
+ s,
+ transcode<C> (e.getMessage ()));
+#endif
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/libxsd/xsd/cxx/xml/sax/std-input-source.hxx b/libxsd/xsd/cxx/xml/sax/std-input-source.hxx
new file mode 100644
index 0000000..f97d2c7
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/sax/std-input-source.hxx
@@ -0,0 +1,174 @@
+// file : xsd/cxx/xml/std-sax-input-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_SAX_STD_INPUT_SOURCE_HXX
+#define XSD_CXX_XML_SAX_STD_INPUT_SOURCE_HXX
+
+#include <istream>
+
+#include <xsd/cxx/xml/string.hxx>
+
+#include <xercesc/sax/InputSource.hpp>
+#include <xercesc/util/BinInputStream.hpp>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace sax
+ {
+ class std_input_stream: public xercesc::BinInputStream
+ {
+ public :
+ std_input_stream (std::istream& is)
+ : is_ (is)
+ {
+ }
+
+#if _XERCES_VERSION >= 30000
+ virtual XMLFilePos
+ curPos () const
+ {
+ return static_cast<XMLFilePos> (is_.tellg ());
+ }
+#else
+ virtual unsigned int
+ curPos () const
+ {
+ return static_cast<unsigned int> (is_.tellg ());
+ }
+#endif
+
+#if _XERCES_VERSION >= 30000
+ virtual XMLSize_t
+ readBytes (XMLByte* const buf, const XMLSize_t size)
+#else
+ virtual unsigned int
+ readBytes (XMLByte* const buf, const unsigned int size)
+#endif
+ {
+ // 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.
+ //
+ std::ios_base::iostate old (is_.exceptions ());
+ is_.exceptions (old & ~std::ios_base::failbit);
+
+ is_.read (reinterpret_cast<char*> (buf),
+ static_cast<std::streamsize> (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 () & ~std::ios_base::failbit);
+
+ is_.exceptions (old);
+
+ // Make sure that if we failed, readBytes won't be called
+ // again.
+ //
+ if (!(is_.bad () || is_.fail ()))
+ {
+#if _XERCES_VERSION >= 30000
+ return static_cast<XMLSize_t> (is_.gcount ());
+#else
+ return static_cast<unsigned int> (is_.gcount ());
+#endif
+ }
+ else
+ return 0;
+ }
+
+#if _XERCES_VERSION >= 30000
+ virtual const XMLCh*
+ getContentType () const
+ {
+ return 0;
+ }
+#endif
+ private :
+ std::istream& is_;
+ };
+
+
+ class std_input_source: public xercesc::InputSource
+ {
+ public :
+ std_input_source (std::istream& is)
+ : is_ (&is)
+ {
+ }
+
+ template <typename C>
+ std_input_source (std::istream& is, const C* system_id)
+ : xercesc::InputSource (xml::string (system_id).c_str ()),
+ is_ (&is)
+ {
+ }
+
+ template <typename C>
+ std_input_source (std::istream& is,
+ const std::basic_string<C>& system_id)
+ : xercesc::InputSource (xml::string (system_id).c_str ()),
+ is_ (&is)
+ {
+ }
+
+ template <typename C>
+ std_input_source (std::istream& is,
+ const C* system_id,
+ const C* public_id)
+ : xercesc::InputSource (xml::string (system_id).c_str (),
+ xml::string (public_id).c_str ()),
+ is_ (&is)
+ {
+ }
+
+ template <typename C>
+ std_input_source (std::istream& is,
+ const std::basic_string<C>& system_id,
+ const std::basic_string<C>& public_id)
+ : xercesc::InputSource (xml::string (system_id).c_str (),
+ xml::string (public_id).c_str ()),
+ is_ (&is)
+ {
+ }
+
+ struct copy {};
+
+ // Throws the copy exception if this function is called more
+ // than once.
+ //
+ virtual xercesc::BinInputStream*
+ makeStream () const
+ {
+ if (is_ == 0)
+ throw copy ();
+
+ std::istream& is (*is_);
+
+ is_ = 0;
+
+ return new std_input_stream (is);
+ }
+
+ private :
+ mutable std::istream* is_;
+ };
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_XML_SAX_STD_INPUT_SOURCE_HXX
diff --git a/libxsd/xsd/cxx/xml/std-memory-manager.hxx b/libxsd/xsd/cxx/xml/std-memory-manager.hxx
new file mode 100644
index 0000000..5324732
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/std-memory-manager.hxx
@@ -0,0 +1,50 @@
+// file : xsd/cxx/xml/std-memory-manager.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_STD_MEMORY_MANAGER_HXX
+#define XSD_CXX_XML_STD_MEMORY_MANAGER_HXX
+
+#include <new> // operator new, delete
+#include <xercesc/framework/MemoryManager.hpp>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ class std_memory_manager: public xercesc::MemoryManager
+ {
+ public:
+ virtual void*
+#if _XERCES_VERSION >= 30000
+ allocate(XMLSize_t size)
+#else
+ allocate(size_t size)
+#endif
+ {
+ return operator new (size);
+ }
+
+ virtual void
+ deallocate(void* p)
+ {
+ if (p)
+ operator delete (p);
+ }
+
+#if _XERCES_VERSION >= 30000
+ virtual xercesc::MemoryManager*
+ getExceptionMemoryManager()
+ {
+ return xercesc::XMLPlatformUtils::fgMemoryManager;
+ }
+#endif
+ };
+ }
+ }
+}
+
+#endif // XSD_CXX_XML_STD_MEMORY_MANAGER_HXX
diff --git a/libxsd/xsd/cxx/xml/string.hxx b/libxsd/xsd/cxx/xml/string.hxx
new file mode 100644
index 0000000..2d08134
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/string.hxx
@@ -0,0 +1,90 @@
+// file : xsd/cxx/xml/string.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_STRING_HXX
+#define XSD_CXX_XML_STRING_HXX
+
+#include <string>
+
+#include <xsd/cxx/auto-array.hxx>
+#include <xercesc/util/XercesDefs.hpp> // XMLCh
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ //
+ //
+ struct invalid_utf8_string {};
+ struct invalid_utf16_string {};
+
+
+ // Transcode a null-terminated string.
+ //
+ template <typename C>
+ std::basic_string<C>
+ transcode (const XMLCh* s);
+
+ // Transcode a potentially non-null-terminated string.
+ //
+ template <typename C>
+ std::basic_string<C>
+ transcode (const XMLCh* s, std::size_t length);
+
+
+ // For VC7.1 wchar_t and XMLCh are the same type so we cannot
+ // overload the transcode name. You should not use these functions
+ // anyway and instead use the xml::string class below.
+ //
+ template <typename C>
+ XMLCh*
+ transcode_to_xmlch (const C*);
+
+ template <typename C>
+ XMLCh*
+ transcode_to_xmlch (const std::basic_string<C>& s);
+
+ //
+ //
+ class string
+ {
+ public :
+ template <typename C>
+ string (const std::basic_string<C>& s)
+ : s_ (transcode_to_xmlch<C> (s))
+ {
+ }
+
+ template <typename C>
+ string (const C* s)
+ : s_ (transcode_to_xmlch<C> (s))
+ {
+ }
+
+ const XMLCh*
+ c_str () const
+ {
+ return s_.get ();
+ }
+
+ private:
+ string (const string&);
+
+ string&
+ operator= (const string&);
+
+ private:
+ auto_array<XMLCh> s_;
+ };
+ }
+ }
+}
+
+#endif // XSD_CXX_XML_STRING_HXX
+
+#include <xsd/cxx/xml/string.ixx>
+#include <xsd/cxx/xml/string.txx>
diff --git a/libxsd/xsd/cxx/xml/string.ixx b/libxsd/xsd/cxx/xml/string.ixx
new file mode 100644
index 0000000..bde86d8
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/string.ixx
@@ -0,0 +1,225 @@
+// file : xsd/cxx/xml/string.ixx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_STRING_IXX
+#define XSD_CXX_XML_STRING_IXX
+
+#include <cassert>
+#include <cstring> // std::memcpy
+
+#include <xercesc/util/XMLString.hpp>
+#include <xsd/cxx/xml/std-memory-manager.hxx>
+
+// We sometimes need this functionality even if we are building for
+// wchar_t.
+//
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+#ifndef XSD_USE_LCP
+ namespace bits
+ {
+ // UTF-16 to/from UTF-8 transcoder.
+ //
+ template <typename C>
+ struct char_transcoder
+ {
+ static std::basic_string<C>
+ to (const XMLCh* s, std::size_t length);
+
+ static XMLCh*
+ from (const C* s, std::size_t length);
+
+ private:
+ static const unsigned char first_byte_mask_[5];
+ };
+ }
+#endif
+
+ template <>
+ inline std::basic_string<char>
+ transcode<char> (const XMLCh* s)
+ {
+ if (s == 0)
+ return std::basic_string<char> ();
+
+#ifndef XSD_USE_LCP
+ return bits::char_transcoder<char>::to (
+ s, xercesc::XMLString::stringLen (s));
+#else
+ // Use Xerces-C++ local code page transcoding.
+ //
+ std_memory_manager mm;
+ auto_array<char, std_memory_manager> r (
+ xercesc::XMLString::transcode (s, &mm), mm);
+ return std::basic_string<char> (r.get ());
+#endif
+ }
+
+ template <>
+ inline std::basic_string<char>
+ transcode<char> (const XMLCh* s, std::size_t len)
+ {
+ if (s == 0 || len == 0)
+ return std::basic_string<char> ();
+
+#ifndef XSD_USE_LCP
+ // Convert UTF-16 to UTF-8
+ //
+ return bits::char_transcoder<char>::to (s, len);
+#else
+ // Use Xerces-C++ local code page transcoding.
+ //
+ auto_array<XMLCh> tmp (new XMLCh[len + 1]);
+ std::memcpy (tmp.get (), s, len * sizeof (XMLCh));
+ tmp[len] = XMLCh (0);
+
+ std_memory_manager mm;
+ auto_array<char, std_memory_manager> r (
+ xercesc::XMLString::transcode (tmp.get (), &mm), mm);
+
+ tmp.reset ();
+
+ return std::basic_string<char> (r.get ());
+#endif
+ }
+
+ template <>
+ inline XMLCh*
+ transcode_to_xmlch (const char* s)
+ {
+#ifndef XSD_USE_LCP
+ // Convert UTF-8 to UTF-16
+ //
+ return bits::char_transcoder<char>::from (
+ s, std::char_traits<char>::length (s));
+#else
+ // Use Xerces-C++ local code page transcoding.
+ //
+ std_memory_manager mm;
+ return xercesc::XMLString::transcode (s, &mm);
+#endif
+ }
+
+ template <>
+ inline XMLCh*
+ transcode_to_xmlch (const std::basic_string<char>& s)
+ {
+#ifndef XSD_USE_LCP
+ // Convert UTF-8 to UTF-16
+ //
+ return bits::char_transcoder<char>::from (
+ s.c_str (), s.length ());
+#else
+ // Use Xerces-C++ local code page transcoding.
+ //
+ std_memory_manager mm;
+ return xercesc::XMLString::transcode (s.c_str (), &mm);
+#endif
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_XML_STRING_IXX
+
+
+#if defined(XSD_USE_CHAR) || !defined(XSD_USE_WCHAR)
+
+#ifndef XSD_CXX_XML_STRING_IXX_CHAR
+#define XSD_CXX_XML_STRING_IXX_CHAR
+
+#endif // XSD_CXX_XML_STRING_IXX_CHAR
+#endif // XSD_USE_CHAR
+
+
+#if defined(XSD_USE_WCHAR) || !defined(XSD_USE_CHAR)
+
+#ifndef XSD_CXX_XML_STRING_IXX_WCHAR
+#define XSD_CXX_XML_STRING_IXX_WCHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace bits
+ {
+ template <typename W, std::size_t S>
+ struct wchar_transcoder;
+
+ // Specialization for 2-byte wchar_t (resulting encoding is UTF-16).
+ //
+ template <typename W>
+ struct wchar_transcoder<W, 2>
+ {
+ static std::basic_string<W>
+ to (const XMLCh* s, std::size_t length);
+
+ static XMLCh*
+ from (const W* s, std::size_t length);
+ };
+
+
+ // Specialization for 4-byte wchar_t (resulting encoding is UCS-4).
+ //
+ template <typename W>
+ struct wchar_transcoder<W, 4>
+ {
+ static std::basic_string<W>
+ to (const XMLCh* s, std::size_t length);
+
+ static XMLCh*
+ from (const W* s, std::size_t length);
+ };
+ }
+
+ template <>
+ inline std::basic_string<wchar_t>
+ transcode<wchar_t> (const XMLCh* s)
+ {
+ if (s == 0)
+ return std::basic_string<wchar_t> ();
+
+ return bits::wchar_transcoder<wchar_t, sizeof (wchar_t)>::to (
+ s, xercesc::XMLString::stringLen (s));
+ }
+
+ template <>
+ inline std::basic_string<wchar_t>
+ transcode<wchar_t> (const XMLCh* s, std::size_t len)
+ {
+ if (s == 0 || len == 0)
+ return std::basic_string<wchar_t> ();
+
+ return bits::wchar_transcoder<wchar_t, sizeof (wchar_t)>::to (
+ s, len);
+ }
+
+ template <>
+ inline XMLCh*
+ transcode_to_xmlch (const wchar_t* s)
+ {
+ return bits::wchar_transcoder<wchar_t, sizeof (wchar_t)>::from (
+ s, std::char_traits<wchar_t>::length (s));
+ }
+
+ template <>
+ inline XMLCh*
+ transcode_to_xmlch (const std::basic_string<wchar_t>& s)
+ {
+ return bits::wchar_transcoder<wchar_t, sizeof (wchar_t)>::from (
+ s.c_str (), s.length ());
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_XML_STRING_IXX_WCHAR
+#endif // XSD_USE_WCHAR
diff --git a/libxsd/xsd/cxx/xml/string.txx b/libxsd/xsd/cxx/xml/string.txx
new file mode 100644
index 0000000..cdef87e
--- /dev/null
+++ b/libxsd/xsd/cxx/xml/string.txx
@@ -0,0 +1,441 @@
+// file : xsd/cxx/xml/string.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_XML_STRING_TXX
+#define XSD_CXX_XML_STRING_TXX
+
+#ifndef XSD_USE_LCP
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace bits
+ {
+ template <typename C>
+ const unsigned char char_transcoder<C>::first_byte_mask_[5] =
+ {
+ 0x00, 0x00, 0xC0, 0xE0, 0xF0
+ };
+
+ template <typename C>
+ std::basic_string<C> char_transcoder<C>::
+ to (const XMLCh* s, std::size_t len)
+ {
+ const XMLCh* end (s + len);
+
+ // Find what the resulting buffer size will be.
+ //
+ std::size_t rl (0);
+ unsigned int u (0); // Four byte UCS-4 char.
+
+ bool valid (true);
+ const XMLCh* p (s);
+
+ for (; p < end; ++p)
+ {
+ XMLCh x (*p);
+
+ if (x < 0xD800 || x > 0xDBFF)
+ u = x;
+ else
+ {
+ // Make sure we have one more char and it has a valid
+ // value for the second char in a surrogate pair.
+ //
+ if (++p == end || !((*p >= 0xDC00) && (*p <= 0xDFFF)))
+ {
+ valid = false;
+ break;
+ }
+
+ u = ((x - 0xD800) << 10) + (*p - 0xDC00) + 0x10000;
+ }
+
+ if (u < 0x80)
+ rl++;
+ else if (u < 0x800)
+ rl += 2;
+ else if (u < 0x10000)
+ rl += 3;
+ else if (u < 0x110000)
+ rl += 4;
+ else
+ {
+ valid = false;
+ break;
+ }
+ }
+
+ if (!valid)
+ throw invalid_utf16_string ();
+
+ std::basic_string<C> r;
+ r.reserve (rl + 1);
+ r.resize (rl);
+ C* rs (const_cast<C*> (r.c_str ()));
+
+ std::size_t i (0);
+ unsigned int count (0);
+
+ p = s;
+
+ // Tight first loop for the common case.
+ //
+ for (; p < end && *p < 0x80; ++p)
+ rs[i++] = C (*p);
+
+ for (; p < end; ++p)
+ {
+ XMLCh x (*p);
+
+ if ((x >= 0xD800) && (x <= 0xDBFF))
+ {
+ u = ((x - 0xD800) << 10) + (*++p - 0xDC00) + 0x10000;
+ }
+ else
+ u = x;
+
+ if (u < 0x80)
+ count = 1;
+ else if (u < 0x800)
+ count = 2;
+ else if (u < 0x10000)
+ count = 3;
+ else if (u < 0x110000)
+ count = 4;
+
+ switch(count)
+ {
+ case 4:
+ {
+ rs[i + 3] = C ((u | 0x80UL) & 0xBFUL);
+ u >>= 6;
+ }
+ case 3:
+ {
+ rs[i + 2] = C ((u | 0x80UL) & 0xBFUL);
+ u >>= 6;
+ }
+ case 2:
+ {
+ rs[i + 1] = C ((u | 0x80UL) & 0xBFUL);
+ u >>= 6;
+ }
+ case 1:
+ {
+ rs[i] = C (u | first_byte_mask_[count]);
+ }
+ }
+
+ i += count;
+ }
+
+ return r;
+ }
+
+ template <typename C>
+ XMLCh* char_transcoder<C>::
+ from (const C* s, std::size_t len)
+ {
+ bool valid (true);
+ const C* end (s + len);
+
+ // Find what the resulting buffer size will be.
+ //
+ std::size_t rl (0);
+ unsigned int count (0);
+
+ for (const C* p (s); p < end; ++p)
+ {
+ unsigned char c (*p);
+
+ if (c < 0x80)
+ {
+ // Fast path.
+ //
+ rl += 1;
+ continue;
+ }
+ else if ((c >> 5) == 0x06)
+ count = 2;
+ else if ((c >> 4) == 0x0E)
+ count = 3;
+ else if ((c >> 3) == 0x1E)
+ count = 4;
+ else
+ {
+ valid = false;
+ break;
+ }
+
+ p += count - 1; // One will be added in the for loop
+
+ if (p + 1 > end)
+ {
+ valid = false;
+ break;
+ }
+
+ // BMP is represented by up to 3 code points in UTF-8.
+ //
+ rl += count > 3 ? 2 : 1;
+ }
+
+ if (!valid)
+ throw invalid_utf8_string ();
+
+ auto_array<XMLCh> r (new XMLCh[rl + 1]);
+ XMLCh* ir (r.get ());
+
+ unsigned int u (0); // Four byte UCS-4 char.
+
+ for (const C* p (s); p < end; ++p)
+ {
+ unsigned char c (*p);
+
+ if (c < 0x80)
+ {
+ // Fast path.
+ //
+ *ir++ = static_cast<XMLCh> (c);
+ continue;
+ }
+ else if ((c >> 5) == 0x06)
+ {
+ // UTF-8: 110yyyyy 10zzzzzz
+ // Unicode: 00000yyy yyzzzzzz
+ //
+ u = (c & 0x1F) << 6;
+
+ c = *++p;
+ if ((c >> 6) != 2)
+ {
+ valid = false;
+ break;
+ }
+ u |= c & 0x3F;
+ }
+ else if ((c >> 4) == 0x0E)
+ {
+ // UTF-8: 1110xxxx 10yyyyyy 10zzzzzz
+ // Unicode: xxxxyyyy yyzzzzzz
+ //
+ u = (c & 0x0F) << 6;
+
+ c = *++p;
+ if ((c >> 6) != 2)
+ {
+ valid = false;
+ break;
+ }
+ u = (u | (c & 0x3F)) << 6;
+
+ c = *++p;
+ if ((c >> 6) != 2)
+ {
+ valid = false;
+ break;
+ }
+ u |= c & 0x3F;
+ }
+ else if ((c >> 3) == 0x1E)
+ {
+ // UTF-8: 000wwwxx xxxxyyyy yyzzzzzz
+ // Unicode: 11110www 10xxxxxx 10yyyyyy 10zzzzzz
+ //
+ u = (c & 0x07) << 6;
+
+ c = *++p;
+ if ((c >> 6) != 2)
+ {
+ valid = false;
+ break;
+ }
+ u = (u | (c & 0x3F)) << 6;
+
+ c = *++p;
+ if ((c >> 6) != 2)
+ {
+ valid = false;
+ break;
+ }
+ u = (u | (c & 0x3F)) << 6;
+
+ c = *++p;
+ if ((c >> 6) != 2)
+ {
+ valid = false;
+ break;
+ }
+ u |= c & 0x3F;
+ }
+
+ if (u & 0xFFFF0000)
+ {
+ // Surrogate pair.
+ //
+ *ir++ = static_cast<XMLCh> (((u - 0x10000) >> 10) + 0xD800);
+ *ir++ = static_cast<XMLCh> ((u & 0x3FF) + 0xDC00);
+ }
+ else
+ *ir++ = static_cast<XMLCh> (u);
+ }
+
+ if (!valid)
+ throw invalid_utf8_string ();
+
+ *ir = XMLCh (0);
+
+ return r.release ();
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_USE_LCP
+#endif // XSD_CXX_XML_STRING_TXX
+
+
+#if defined(XSD_USE_WCHAR) || !defined(XSD_USE_CHAR)
+
+#ifndef XSD_CXX_XML_STRING_TXX_WCHAR
+#define XSD_CXX_XML_STRING_TXX_WCHAR
+
+namespace xsd
+{
+ namespace cxx
+ {
+ namespace xml
+ {
+ namespace bits
+ {
+ // wchar_transcoder (specialization for 2-byte wchar_t)
+ //
+ template <typename W>
+ std::basic_string<W> wchar_transcoder<W, 2>::
+ to (const XMLCh* s, std::size_t length)
+ {
+ std::basic_string<W> r;
+ r.reserve (length + 1);
+ r.resize (length);
+ W* rs (const_cast<W*> (r.c_str ()));
+
+ for (std::size_t i (0); i < length; ++s, ++i)
+ {
+ rs[i] = *s;
+ }
+
+ return r;
+ }
+
+ template <typename W>
+ XMLCh* wchar_transcoder<W, 2>::
+ from (const W* s, std::size_t length)
+ {
+ auto_array<XMLCh> r (new XMLCh[length + 1]);
+ XMLCh* ir (r.get ());
+
+ for (std::size_t i (0); i < length; ++ir, ++i)
+ {
+ *ir = static_cast<XMLCh> (s[i]);
+ }
+
+ *ir = XMLCh (0);
+
+ return r.release ();
+ }
+
+
+ // wchar_transcoder (specialization for 4-byte wchar_t)
+ //
+ template <typename W>
+ std::basic_string<W> wchar_transcoder<W, 4>::
+ to (const XMLCh* s, std::size_t length)
+ {
+ const XMLCh* end (s + length);
+
+ // Find what the resulting buffer size will be.
+ //
+ std::size_t rl (0);
+
+ for (const XMLCh* p (s); p < end; ++p)
+ {
+ rl++;
+
+ if ((*p >= 0xD800) && (*p <= 0xDBFF))
+ {
+ // Make sure we have one more char and it has a valid
+ // value for the second char in a surrogate pair.
+ //
+ if (++p == end || !((*p >= 0xDC00) && (*p <= 0xDFFF)))
+ throw invalid_utf16_string ();
+ }
+ }
+
+ std::basic_string<W> r;
+ r.reserve (rl + 1);
+ r.resize (rl);
+ W* rs (const_cast<W*> (r.c_str ()));
+
+ std::size_t i (0);
+
+ for (const XMLCh* p (s); p < end; ++p)
+ {
+ XMLCh x (*p);
+
+ if (x < 0xD800 || x > 0xDBFF)
+ rs[i++] = W (x);
+ else
+ rs[i++] = ((x - 0xD800) << 10) + (*++p - 0xDC00) + 0x10000;
+ }
+
+ return r;
+ }
+
+ template <typename W>
+ XMLCh* wchar_transcoder<W, 4>::
+ from (const W* s, std::size_t length)
+ {
+ // Find what the resulting buffer size will be.
+ //
+ std::size_t rl (0);
+
+ for (const W* p (s); p < s + length; ++p)
+ {
+ rl += (*p & 0xFFFF0000) ? 2 : 1;
+ }
+
+ auto_array<XMLCh> r (new XMLCh[rl + 1]);
+ XMLCh* ir (r.get ());
+
+ for (const W* p (s); p < s + length; ++p)
+ {
+ W w (*p);
+
+ if (w & 0xFFFF0000)
+ {
+ // Surrogate pair.
+ //
+ *ir++ = static_cast<XMLCh> (((w - 0x10000) >> 10) + 0xD800);
+ *ir++ = static_cast<XMLCh> ((w & 0x3FF) + 0xDC00);
+ }
+ else
+ *ir++ = static_cast<XMLCh> (w);
+ }
+
+ *ir = XMLCh (0);
+
+ return r.release ();
+ }
+ }
+ }
+ }
+}
+
+#endif // XSD_CXX_XML_STRING_TXX_WCHAR
+#endif // XSD_USE_WCHAR
diff --git a/libxsd/xsd/cxx/zc-istream.hxx b/libxsd/xsd/cxx/zc-istream.hxx
new file mode 100644
index 0000000..2f0c1ed
--- /dev/null
+++ b/libxsd/xsd/cxx/zc-istream.hxx
@@ -0,0 +1,92 @@
+// file : xsd/cxx/zc-istream.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_CXX_ZC_ISTREAM_HXX
+#define XSD_CXX_ZC_ISTREAM_HXX
+
+#include <string>
+#include <istream>
+
+#include <xsd/cxx/ro-string.hxx>
+
+namespace xsd
+{
+ namespace cxx
+ {
+ // Input streambuffer that does not copy the underlying
+ // buffer (zero copy).
+ //
+ template <typename C>
+ class zc_streambuf: public std::basic_streambuf<C>
+ {
+ public:
+ typedef typename std::basic_streambuf<C>::int_type int_type;
+ typedef typename std::basic_streambuf<C>::traits_type traits_type;
+
+ public:
+ zc_streambuf (const ro_string<C>&);
+ zc_streambuf (const std::basic_string<C>&);
+
+ protected:
+ virtual std::streamsize
+ showmanyc ();
+
+ virtual int_type
+ underflow ();
+
+ private:
+ void
+ init ();
+
+ private:
+ zc_streambuf (const zc_streambuf&);
+
+ zc_streambuf&
+ operator= (const zc_streambuf&);
+
+ private:
+ ro_string<C> str_;
+ };
+
+
+ // Input string stream that does not copy the underlying string.
+ //
+ template <typename C>
+ class zc_istream_base
+ {
+ protected:
+ zc_istream_base (const ro_string<C>&);
+ zc_istream_base (const std::basic_string<C>&);
+
+ protected:
+ zc_streambuf<C> buf_;
+ };
+
+ template <typename C>
+ class zc_istream: protected zc_istream_base<C>,
+ public std::basic_istream<C>
+ {
+ public:
+ zc_istream (const ro_string<C>&);
+ zc_istream (const std::basic_string<C>&);
+
+ bool
+ exhausted ()
+ {
+ return this->get () == std::basic_istream<C>::traits_type::eof ();
+ }
+
+ private:
+ zc_istream (const zc_istream&);
+
+ zc_istream&
+ operator= (const zc_istream&);
+ };
+ }
+}
+
+#include <xsd/cxx/zc-istream.txx>
+
+#endif // XSD_CXX_ZC_ISTREAM_HXX
diff --git a/libxsd/xsd/cxx/zc-istream.txx b/libxsd/xsd/cxx/zc-istream.txx
new file mode 100644
index 0000000..68d1933
--- /dev/null
+++ b/libxsd/xsd/cxx/zc-istream.txx
@@ -0,0 +1,94 @@
+// file : xsd/cxx/zc-istream.txx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+namespace xsd
+{
+ namespace cxx
+ {
+ // zc_streambuf
+ //
+ template <typename C>
+ zc_streambuf<C>::
+ zc_streambuf (const ro_string<C>& str)
+ : str_ (str.data (), str.size ())
+ {
+ init ();
+ }
+
+ template <typename C>
+ zc_streambuf<C>::
+ zc_streambuf (const std::basic_string<C>& str)
+ : str_ (str)
+ {
+ init ();
+ }
+
+ template <typename C>
+ void zc_streambuf<C>::
+ init ()
+ {
+ C* b (const_cast<C*> (str_.data ()));
+ C* e (b + str_.size ());
+
+ setg (b, b, e);
+ }
+
+ template <typename C>
+ std::streamsize zc_streambuf<C>::
+ showmanyc ()
+ {
+ return static_cast<std::streamsize> (
+ this->egptr () - this->gptr ());
+ }
+
+ template <typename C>
+ typename zc_streambuf<C>::int_type zc_streambuf<C>::
+ underflow ()
+ {
+ int_type r = traits_type::eof ();
+
+ if (this->gptr () < this->egptr ())
+ r = traits_type::to_int_type (*this->gptr ());
+
+ return r;
+ }
+
+
+ // zc_istream_base
+ //
+ template <typename C>
+ zc_istream_base<C>::
+ zc_istream_base (const ro_string<C>& str)
+ : buf_ (str)
+ {
+ }
+
+ template <typename C>
+ zc_istream_base<C>::
+ zc_istream_base (const std::basic_string<C>& str)
+ : buf_ (str)
+ {
+ }
+
+
+ // zc_istream
+ //
+ template <typename C>
+ zc_istream<C>::
+ zc_istream (const ro_string<C>& str)
+ : zc_istream_base<C> (str),
+ std::basic_istream<C> (&this->buf_)
+ {
+ }
+
+ template <typename C>
+ zc_istream<C>::
+ zc_istream (const std::basic_string<C>& str)
+ : zc_istream_base<C> (str),
+ std::basic_istream<C> (&this->buf_)
+ {
+ }
+ }
+}
diff --git a/makefile b/makefile
new file mode 100644
index 0000000..55d8fdc
--- /dev/null
+++ b/makefile
@@ -0,0 +1,41 @@
+# file : makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))build/bootstrap.make
+
+default := $(out_base)/
+test := $(out_base)/.test
+install := $(out_base)/.install
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(install) $(clean)
+
+$(default): $(out_base)/xsd/ \
+ $(out_base)/tests/ \
+ $(out_base)/examples/
+
+$(test): $(out_base)/tests/.test
+
+$(install): $(out_base)/xsd/.install \
+ $(out_base)/libxsd/.install \
+ $(out_base)/documentation/.install
+ $(call install-data,$(src_base)/FLOSSE,$(install_doc_dir)/xsd/FLOSSE)
+ $(call install-data,$(src_base)/GPLv2,$(install_doc_dir)/xsd/GPLv2)
+ $(call install-data,$(src_base)/LICENSE,$(install_doc_dir)/xsd/LICENSE)
+ $(call install-data,$(src_base)/NEWS,$(install_doc_dir)/xsd/NEWS)
+ $(call install-data,$(src_base)/README,$(install_doc_dir)/xsd/README)
+
+
+$(clean): $(out_base)/xsd/.clean \
+ $(out_base)/tests/.clean \
+ $(out_base)/examples/.clean
+
+$(call include,$(bld_root)/install.make)
+
+$(call import,$(src_base)/xsd/makefile)
+$(call import,$(src_base)/libxsd/makefile)
+$(call import,$(src_base)/tests/makefile)
+$(call import,$(src_base)/examples/makefile)
+$(call import,$(src_base)/documentation/makefile)
diff --git a/tests/clash/clash.xsd b/tests/clash/clash.xsd
new file mode 100644
index 0000000..8458908
--- /dev/null
+++ b/tests/clash/clash.xsd
@@ -0,0 +1,25 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns="http://www.codesynthesis.com/xmlns/test/bar"
+ xmlns:f="http://www.codesynthesis.com/xmlns/test/foo"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test/bar">
+
+ <xsd:import namespace="http://www.codesynthesis.com/xmlns/test/foo" schemaLocation="foo.xsd"/>
+
+ <!-- example of a name clash. -->
+
+ <xsd:element name="foo" type="xsd:string"/>
+
+ <xsd:complexType name="Foo">
+ <xsd:sequence>
+ <xsd:element ref="foo"/>
+ <xsd:element name="foo" type="xsd:long"/>
+ <xsd:element ref="f:foo"/>
+ <xsd:element ref="f:foo"/>
+ </xsd:sequence>
+ <xsd:attribute name="foo" type="xsd:string"/>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/tests/clash/foo.xsd b/tests/clash/foo.xsd
new file mode 100644
index 0000000..8a06ba8
--- /dev/null
+++ b/tests/clash/foo.xsd
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns="http://www.codesynthesis.com/xmlns/test/foo"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test/foo">
+
+ <xsd:element name="foo" type="xsd:int"/>
+ <xsd:element name="bar" type="xsd:int"/>
+
+</xsd:schema>
diff --git a/tests/code/name-conflict/test.xsd b/tests/code/name-conflict/test.xsd
new file mode 100644
index 0000000..a017cc8
--- /dev/null
+++ b/tests/code/name-conflict/test.xsd
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:simpleType name="enumeration">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="enumeration"/>
+ <xsd:enumeration value="enumeration1"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:element name="enumeration" type="enumeration"/>
+
+ <xsd:complexType name="complex">
+ <xsd:sequence>
+ <xsd:element name="complex" type="xsd:string"/>
+ <xsd:element name="complex1" type="xsd:string"/>
+ <xsd:element name="type" type="xsd:string"/>
+ <xsd:element name="container" type="xsd:string" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="complex" type="complex"/>
+
+ <xsd:complexType name="anonymous">
+ <xsd:sequence>
+ <xsd:element name="anonymous">
+ <xsd:complexType> <!-- this is really twisted -->
+ <xsd:sequence>
+ <xsd:element name="anonymous2" type="xsd:string"/>
+ <xsd:element name="anonymous21" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ <xsd:element name="anonymous1" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="anonymous" type="anonymous"/>
+
+</xsd:schema>
diff --git a/tests/code/name-escaping/test.xsd b/tests/code/name-escaping/test.xsd
new file mode 100644
index 0000000..08c7530
--- /dev/null
+++ b/tests/code/name-escaping/test.xsd
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- type -->
+
+ <xsd:simpleType name="long">
+ <xsd:restriction base="xsd:long"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="strange.type-name.">
+ <xsd:restriction base="long"/>
+ </xsd:simpleType>
+
+ <xsd:element name="one-two-explicit">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NCName">
+ <xsd:enumeration value="on.e-"/>
+ <xsd:enumeration value="t-wo."/>
+ <xsd:enumeration value="explicit"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+
+ <!-- element [global/local] -->
+
+ <xsd:element name="switch" type="long"/>
+ <xsd:element name="strange.element-name." type="strange.type-name."/>
+
+
+ <xsd:element name="with-anonymous-type-1">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="for" type="long"/>
+ <xsd:element name="switch" minOccurs="0" type="long"/>
+ <xsd:element name="strange.element-name." maxOccurs="unbounded" type="strange.type-name."/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+
+
+ <!-- attributes [global/local] -->
+
+ <xsd:attribute name="default" type="long"/>
+ <xsd:attribute name="strange.attribute-name." type="strange.type-name."/>
+
+ <xsd:element name="with-anonymous-type-2">
+ <xsd:complexType>
+ <xsd:attribute name="and" type="long" use="required"/>
+ <xsd:attribute name="strange.attribute-name." type="strange.type-name."/>
+ </xsd:complexType>
+ </xsd:element>
+
+
+</xsd:schema>
diff --git a/tests/cxx/makefile b/tests/cxx/makefile
new file mode 100644
index 0000000..8d4cbd5
--- /dev/null
+++ b/tests/cxx/makefile
@@ -0,0 +1,19 @@
+# file : tests/cxx/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../build/bootstrap.make
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(out_base)/parser/ $(out_base)/tree/
+$(test): $(out_base)/parser/.test $(out_base)/tree/.test
+$(clean): $(out_base)/parser/.clean $(out_base)/tree/.clean
+
+$(call import,$(src_base)/parser/makefile)
+$(call import,$(src_base)/tree/makefile)
diff --git a/tests/cxx/parser/built-in/driver.cxx b/tests/cxx/parser/built-in/driver.cxx
new file mode 100644
index 0000000..5c9c6e8
--- /dev/null
+++ b/tests/cxx/parser/built-in/driver.cxx
@@ -0,0 +1,531 @@
+// file : tests/cxx/parser/built-in/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test built-in type parsing.
+//
+
+#include <string>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace test;
+using xml_schema::ro_string;
+
+struct any_type_pimpl: xml_schema::any_type_pimpl
+{
+ virtual void
+ pre ()
+ {
+ cout << "{" << endl;
+ }
+
+ virtual void
+ _start_any_element (ro_string const&,
+ ro_string const& n,
+ ro_string const*)
+ {
+ cout << " start any element '" << n << "'" << endl;
+ }
+
+ virtual void
+ _end_any_element (ro_string const&, ro_string const& n)
+ {
+ cout << " end any element '" << n << "'" << endl;
+ }
+
+ virtual void
+ _any_attribute (ro_string const&,
+ ro_string const& n,
+ ro_string const& v)
+ {
+ cout << " any attribute " << n << " = '" << v << "'" << endl;
+ }
+
+ virtual void
+ _any_characters (ro_string const& s)
+ {
+ cout << " any text: '" << s << "'" << endl;
+ }
+
+ virtual void
+ post_any_type ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct any_simple_type_pimpl: xml_schema::any_simple_type_pimpl
+{
+ virtual void
+ pre ()
+ {
+ cout << "{" << endl;
+ }
+
+ virtual void
+ _any_characters (ro_string const& s)
+ {
+ cout << " any text: '" << s << "'" << endl;
+ }
+
+ virtual void
+ post_any_simple_type ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct type_pimpl: type_pskel
+{
+ virtual void
+ boolean (bool v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ byte (signed char v)
+ {
+ cout << short (v) << endl;
+ }
+
+ virtual void
+ unsigned_byte (unsigned char v)
+ {
+ cout << (unsigned short) (v) << endl;
+ }
+
+ virtual void
+ short_ (short v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ unsigned_short (unsigned short v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ int_ (int v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ unsigned_int (unsigned int v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ long_ (long long v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ unsigned_long (unsigned long long v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ integer (long long v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ negative_integer (long long v)
+ {
+ cout << v << endl;
+ }
+
+
+ virtual void
+ non_positive_integer (long long v)
+ {
+ cout << v << endl;
+ }
+
+
+ virtual void
+ positive_integer (unsigned long long v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ non_negative_integer (unsigned long long v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ float_ (float v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ double_ (double v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ decimal (double v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ string (std::string const& v)
+ {
+ cout << "'" << v << "'" << endl;
+ }
+
+ virtual void
+ normalized_string (std::string const& v)
+ {
+ cout << "'" << v << "'" << endl;
+ }
+
+ virtual void
+ token (std::string const& v)
+ {
+ cout << "'" << v << "'" << endl;
+ }
+
+ virtual void
+ name (std::string const& v)
+ {
+ cout << "'" << v << "'" << endl;
+ }
+
+ virtual void
+ nmtoken (std::string const& v)
+ {
+ cout << "'" << v << "'" << endl;
+ }
+
+ virtual void
+ nmtokens (xml_schema::string_sequence const& s)
+ {
+ cout << "'";
+
+ for (xml_schema::string_sequence::const_iterator i (s.begin ());
+ i != s.end (); ++i)
+ cout << *i << " ";
+
+ cout << "'" << endl;
+ }
+
+ virtual void
+ ncname (std::string const& v)
+ {
+ cout << "'" << v << "'" << endl;
+ }
+
+ virtual void
+ id (std::string const& v)
+ {
+ cout << "'" << v << "'" << endl;
+ }
+
+ virtual void
+ idref (std::string const& v)
+ {
+ cout << "'" << v << "'" << endl;
+ }
+
+ virtual void
+ idrefs (xml_schema::string_sequence const& s)
+ {
+ cout << "'";
+
+ for (xml_schema::string_sequence::const_iterator i (s.begin ());
+ i != s.end (); ++i)
+ cout << *i << " ";
+
+ cout << "'" << endl;
+ }
+
+ virtual void
+ language (std::string const& v)
+ {
+ cout << "'" << v << "'" << endl;
+ }
+
+ virtual void
+ uri (std::string const& v)
+ {
+ cout << "'" << v << "'" << endl;
+ }
+
+ virtual void
+ qname (xml_schema::qname const& v)
+ {
+ cout << "'" << v.prefix () << ":" << v.name () << "'" << endl;
+ }
+
+ virtual void
+ base64_binary (std::auto_ptr<xml_schema::buffer> v)
+ {
+ std::string tmp (v->data (), v->size ());
+ cout << "'" << tmp << "'" << endl;
+ }
+
+ virtual void
+ hex_binary (std::auto_ptr<xml_schema::buffer> v)
+ {
+ std::string tmp (v->data (), v->size ());
+ cout << "'" << tmp << "'" << endl;
+ }
+
+ virtual void
+ gday (xml_schema::gday const& v)
+ {
+ cout << v.day ();
+
+ if (v.zone_present ())
+ cout << (v.zone_hours () < 0 ? "" : "+") << v.zone_hours ()
+ << ':' << v.zone_minutes ();
+
+ cout << endl;
+ }
+
+ virtual void
+ gmonth (xml_schema::gmonth const& v)
+ {
+ cout << v.month ();
+
+ if (v.zone_present ())
+ cout << (v.zone_hours () < 0 ? "" : "+") << v.zone_hours ()
+ << ':' << v.zone_minutes ();
+
+ cout << endl;
+ }
+
+ virtual void
+ gyear (xml_schema::gyear const& v)
+ {
+ cout << v.year ();
+
+ if (v.zone_present ())
+ cout << (v.zone_hours () < 0 ? "" : "+") << v.zone_hours ()
+ << ':' << v.zone_minutes ();
+
+ cout << endl;
+ }
+
+ virtual void
+ gmonth_day (xml_schema::gmonth_day const& v)
+ {
+ cout << v.month () << '-' << v.day ();
+
+ if (v.zone_present ())
+ cout << (v.zone_hours () < 0 ? "" : "+") << v.zone_hours ()
+ << ':' << v.zone_minutes ();
+
+ cout << endl;
+ }
+
+ virtual void
+ gyear_month (xml_schema::gyear_month const& v)
+ {
+ cout << v.year () << '-' << v.month ();
+
+ if (v.zone_present ())
+ cout << (v.zone_hours () < 0 ? "" : "+") << v.zone_hours ()
+ << ':' << v.zone_minutes ();
+
+ cout << endl;
+ }
+
+ virtual void
+ date (xml_schema::date const& v)
+ {
+ cout << v.year () << '-' << v.month () << '-' << v.day ();
+
+ if (v.zone_present ())
+ cout << (v.zone_hours () < 0 ? "" : "+") << v.zone_hours ()
+ << ':' << v.zone_minutes ();
+
+ cout << endl;
+ }
+
+ virtual void
+ time (xml_schema::time const& v)
+ {
+ cout << v.hours () << ':' << v.minutes () << ':' << v.seconds ();
+
+ if (v.zone_present ())
+ cout << (v.zone_hours () < 0 ? "" : "+") << v.zone_hours ()
+ << ':' << v.zone_minutes ();
+
+ cout << endl;
+ }
+
+ virtual void
+ date_time (xml_schema::date_time const& v)
+ {
+ cout << v.year () << '-' << v.month () << '-' << v.day () << 'T'
+ << v.hours () << ':' << v.minutes () << ':' << v.seconds ();
+
+ if (v.zone_present ())
+ cout << (v.zone_hours () < 0 ? "" : "+") << v.zone_hours ()
+ << ':' << v.zone_minutes ();
+
+ cout << endl;
+ }
+
+ virtual void
+ duration (xml_schema::duration const& v)
+ {
+ cout << (v.negative () ? "-" : "") << 'P'
+ << v.years () << 'Y'
+ << v.months () << 'M'
+ << v.days () << 'D'
+ << 'T'
+ << v.hours () << 'H'
+ << v.minutes () << 'M'
+ << v.seconds () << 'S'
+ << endl;
+ }
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ any_type_pimpl any_type_p;
+ any_simple_type_pimpl any_simple_type_p;
+
+ xml_schema::boolean_pimpl boolean_p;
+
+ xml_schema::byte_pimpl byte_p;
+ xml_schema::unsigned_byte_pimpl unsigned_byte_p;
+ xml_schema::short_pimpl short_p;
+ xml_schema::unsigned_short_pimpl unsigned_short_p;
+ xml_schema::int_pimpl int_p;
+ xml_schema::unsigned_int_pimpl unsigned_int_p;
+ xml_schema::long_pimpl long_p;
+ xml_schema::unsigned_long_pimpl unsigned_long_p;
+
+ xml_schema::integer_pimpl integer_p;
+ xml_schema::negative_integer_pimpl negative_integer_p;
+ xml_schema::non_positive_integer_pimpl non_positive_integer_p;
+ xml_schema::positive_integer_pimpl positive_integer_p;
+ xml_schema::non_negative_integer_pimpl non_negative_integer_p;
+
+ xml_schema::float_pimpl float_p;
+ xml_schema::double_pimpl double_p;
+ xml_schema::decimal_pimpl decimal_p;
+
+ xml_schema::string_pimpl string_p;
+ xml_schema::normalized_string_pimpl normalized_string_p;
+ xml_schema::token_pimpl token_p;
+ xml_schema::name_pimpl name_p;
+ xml_schema::nmtoken_pimpl nmtoken_p;
+ xml_schema::nmtokens_pimpl nmtokens_p;
+ xml_schema::ncname_pimpl ncname_p;
+ xml_schema::id_pimpl id_p;
+ xml_schema::idref_pimpl idref_p;
+ xml_schema::idrefs_pimpl idrefs_p;
+
+ xml_schema::language_pimpl language_p;
+ xml_schema::uri_pimpl uri_p;
+ xml_schema::qname_pimpl qname_p;
+
+ xml_schema::base64_binary_pimpl base64_binary_p;
+ xml_schema::hex_binary_pimpl hex_binary_p;
+
+ xml_schema::gday_pimpl gday_p;
+ xml_schema::gmonth_pimpl gmonth_p;
+ xml_schema::gyear_pimpl gyear_p;
+ xml_schema::gmonth_day_pimpl gmonth_day_p;
+ xml_schema::gyear_month_pimpl gyear_month_p;
+ xml_schema::date_pimpl date_p;
+ xml_schema::time_pimpl time_p;
+ xml_schema::date_time_pimpl date_time_p;
+ xml_schema::duration_pimpl duration_p;
+
+ type_pimpl type_p;
+
+ type_p.parsers (any_type_p,
+ any_simple_type_p,
+ boolean_p,
+ byte_p,
+ unsigned_byte_p,
+ short_p,
+ unsigned_short_p,
+ int_p,
+ unsigned_int_p,
+ long_p,
+ unsigned_long_p,
+ integer_p,
+ negative_integer_p,
+ non_positive_integer_p,
+ positive_integer_p,
+ non_negative_integer_p,
+ float_p,
+ double_p,
+ decimal_p,
+ string_p,
+ normalized_string_p,
+ token_p,
+ name_p,
+ nmtoken_p,
+ nmtokens_p,
+ ncname_p,
+ id_p,
+ idref_p,
+ idrefs_p,
+ language_p,
+ uri_p,
+ qname_p,
+ base64_binary_p,
+ hex_binary_p,
+ gday_p,
+ gmonth_p,
+ gyear_p,
+ gmonth_day_p,
+ gyear_month_p,
+ date_p,
+ time_p,
+ date_time_p,
+ duration_p);
+
+ xml_schema::document doc_p (type_p, "test", "root");
+
+ type_p.pre ();
+ doc_p.parse (argv[1]);
+ type_p.post_type ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (std::ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/built-in/makefile b/tests/cxx/parser/built-in/makefile
new file mode 100644
index 0000000..c38e16a
--- /dev/null
+++ b/tests/cxx/parser/built-in/makefile
@@ -0,0 +1,75 @@
+# file : tests/cxx/parser/built-in/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
+
diff --git a/tests/cxx/parser/built-in/output b/tests/cxx/parser/built-in/output
new file mode 100644
index 0000000..756abcd
--- /dev/null
+++ b/tests/cxx/parser/built-in/output
@@ -0,0 +1,164 @@
+{
+ any attribute x = 'x'
+ any text: '
+ '
+ start any element 'a'
+ any text: 'a'
+ end any element 'a'
+ any text: '
+ '
+ start any element 'any-type'
+ any attribute x = 'xxx'
+ any text: 'aaa'
+ start any element 'a'
+ any text: 'bbb'
+ end any element 'a'
+ any text: 'ccc'
+ end any element 'any-type'
+ any text: '
+ '
+}
+
+{
+ any text: '123abc'
+}
+
+1
+0
+1
+0
+0
+127
+-128
+123
+0
+255
+123
+0
+32767
+-32768
+-12345
+0
+65535
+12345
+0
+2147483647
+-2147483648
+-1234567890
+0
+4294967295
+1234567890
+0
+9223372036854775807
+-9223372036854775808
+-1234567890123456789
+0
+18446744073709551615
+12345678901234567890
+0
+2147483647
+-2147483648
+-1234567890
+-2147483648
+-1234567890
+0
+-2147483648
+-1234567890
+4294967295
+1234567890
+0
+4294967295
+1234567890
+0
+0
+-0
+inf
+-inf
+nan
+123.567
+123.567
+-1.23567e+07
+-4.5e-06
+0
+0
+-0
+inf
+-inf
+nan
+123.567
+123.567
+-1.23567e+07
+-4.5e-06
+0
+0
+-0
+123.567
+123.567
+-123.567
+'string space
+newline
+ '
+' string space newline '
+'string space newline'
+'as123:345-.abs'
+'1as123:345-.abs'
+'abc 123 '
+'as123_345-.abs'
+'as123_345-.abs'
+'abc'
+'a123'
+'as123_345-.abs'
+'abc a123 '
+'x'
+'en'
+'en-us'
+'one-two-three-four44-seven77-eight888'
+''
+'relative'
+'#id'
+'http://www.example.com/foo#bar'
+':schemaLocation'
+'xsi:schemaLocation'
+'12345abcjk'
+'a'
+'ab'
+'abc'
+''
+'12345abcjk'
+12+12:0
+1
+31
+15+0:0
+15-14:0
+10+12:0
+1
+12+0:0
+2007+12:0
+1
+-20000+0:0
+10-28+12:0
+12-31
+1-1+0:0
+2007-12+12:0
+-2007-10
+20007-10+0:0
+-20007-1
+2007-12-26+12:0
+-2007-10-15
+20007-12-31+0:0
+-20007-1-1
+12:46:23.456+12:0
+12:13:14
+12:13:14+0:0
+2007-12-26T12:13:14.123+12:0
+-2007-10-15T12:13:14
+20007-12-31T12:13:14+0:0
+-20007-1-1T12:13:14
+-P2007Y13M32DT25H61M61.123S
+P1Y0M0DT0H0M0S
+P0Y1M0DT0H0M0S
+P0Y0M1DT0H0M0S
+P0Y0M0DT1H0M0S
+P0Y0M0DT0H1M0S
+P0Y0M0DT0H0M1.1S
+P1Y0M0DT0H0M1S
diff --git a/tests/cxx/parser/built-in/test.xml b/tests/cxx/parser/built-in/test.xml
new file mode 100644
index 0000000..8d9332a
--- /dev/null
+++ b/tests/cxx/parser/built-in/test.xml
@@ -0,0 +1,199 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <any-type x="x">
+ <a>a</a>
+ <any-type x="xxx">aaa<a>bbb</a>ccc</any-type>
+ </any-type>
+
+ <any-simple-type>123abc</any-simple-type>
+
+ <boolean>1</boolean>
+ <boolean> 0 </boolean>
+ <boolean>true</boolean>
+ <boolean> false </boolean>
+
+ <byte>0</byte>
+ <byte>+127</byte>
+ <byte>-128</byte>
+ <byte> 123 </byte>
+
+ <unsigned-byte>0</unsigned-byte>
+ <unsigned-byte>255</unsigned-byte>
+ <unsigned-byte> 123 </unsigned-byte>
+
+ <short>0</short>
+ <short>+32767</short>
+ <short>-32768</short>
+ <short> -12345 </short>
+
+ <unsigned-short>0</unsigned-short>
+ <unsigned-short>65535</unsigned-short>
+ <unsigned-short> 12345 </unsigned-short>
+
+ <int>0</int>
+ <int>+2147483647</int>
+ <int>-2147483648</int>
+ <int> -1234567890 </int>
+
+ <unsigned-int>0</unsigned-int>
+ <unsigned-int>4294967295</unsigned-int>
+ <unsigned-int> 1234567890 </unsigned-int>
+
+ <long>0</long>
+ <long>+9223372036854775807</long>
+ <long>-9223372036854775808</long>
+ <long> -1234567890123456789 </long>
+
+ <unsigned-long>0</unsigned-long>
+ <unsigned-long>18446744073709551615</unsigned-long>
+ <unsigned-long> 12345678901234567890 </unsigned-long>
+
+ <integer>0</integer>
+ <integer> +2147483647 </integer>
+ <integer>-02147483648</integer>
+ <integer>-1234567890</integer>
+
+ <negative-integer>-02147483648</negative-integer>
+ <negative-integer> -1234567890 </negative-integer>
+
+ <non-positive-integer>0</non-positive-integer>
+ <non-positive-integer>-02147483648</non-positive-integer>
+ <non-positive-integer> -1234567890 </non-positive-integer>
+
+ <positive-integer>4294967295</positive-integer>
+ <positive-integer> +01234567890 </positive-integer>
+
+ <non-negative-integer>0</non-negative-integer>
+ <non-negative-integer>4294967295</non-negative-integer>
+ <non-negative-integer> +01234567890 </non-negative-integer>
+
+ <float>0</float>
+ <float>+0</float>
+ <float>-0</float>
+ <float>INF</float>
+ <float>-INF</float>
+ <float>NaN</float>
+ <float> 123.567 </float>
+ <float>+123.567</float>
+ <float>-123.567e5</float>
+ <float>-.45E-5</float>
+
+ <double>0</double>
+ <double>+0</double>
+ <double>-0</double>
+ <double>INF</double>
+ <double>-INF</double>
+ <double>NaN</double>
+ <double> 123.567 </double>
+ <double>+123.567</double>
+ <double>-123.567e5</double>
+ <double>-.45E-5</double>
+
+ <decimal>0</decimal>
+ <decimal>+0</decimal>
+ <decimal>-0</decimal>
+ <decimal> 123.567 </decimal>
+ <decimal>+123.567</decimal>
+ <decimal>-123.567</decimal>
+
+ <string>string space
+newline
+ </string>
+
+ <normalized-string> string space
+newline
+
+ </normalized-string>
+
+ <token> string space
+newline
+
+ </token>
+
+ <name> as123:345-.abs </name>
+
+ <nmtoken> 1as123:345-.abs </nmtoken>
+
+ <nmtokens> abc 123 </nmtokens>
+
+ <ncname> as123_345-.abs </ncname>
+
+ <id> as123_345-.abs </id>
+ <id> abc </id>
+ <id> a123 </id>
+
+ <idref> as123_345-.abs </idref>
+
+ <idrefs> abc a123 </idrefs>
+
+ <language> x </language>
+ <language> en </language>
+ <language> en-us </language>
+ <language>one-two-three-four44-seven77-eight888</language>
+
+ <uri> </uri>
+ <uri> relative </uri>
+ <uri> #id </uri>
+ <uri> http://www.example.com/foo#bar </uri>
+
+ <qname>schemaLocation</qname>
+ <qname>xsi:schemaLocation</qname>
+
+ <base64_binary> MTIzND
+ VhYmNqaw = =</base64_binary>
+ <base64_binary>YQ==</base64_binary>
+ <base64_binary>YWI=</base64_binary>
+ <base64_binary>YWJj</base64_binary>
+
+ <hex_binary> </hex_binary>
+ <hex_binary> 31323334356162636a6b </hex_binary>
+
+ <gday> ---12+12:00 </gday>
+ <gday>---01</gday>
+ <gday>---31</gday>
+ <gday>---15Z</gday>
+ <gday>---15-14:00</gday>
+
+ <gmonth> --10+12:00 </gmonth>
+ <gmonth>--01</gmonth>
+ <gmonth>--12Z</gmonth>
+
+ <gyear> 2007+12:00 </gyear>
+ <gyear>0001</gyear>
+ <gyear>-20000Z</gyear>
+
+ <gmonth_day> --10-28+12:00 </gmonth_day>
+ <gmonth_day>--12-31</gmonth_day>
+ <gmonth_day>--01-01Z</gmonth_day>
+
+ <gyear_month> 2007-12+12:00 </gyear_month>
+ <gyear_month>-2007-10</gyear_month>
+ <gyear_month>20007-10Z</gyear_month>
+ <gyear_month>-20007-01</gyear_month>
+
+ <date> 2007-12-26+12:00 </date>
+ <date>-2007-10-15</date>
+ <date>20007-12-31Z</date>
+ <date>-20007-01-01</date>
+
+ <time> 12:46:23.456+12:00 </time>
+ <time>12:13:14</time>
+ <time>12:13:14Z</time>
+
+ <date_time> 2007-12-26T12:13:14.123+12:00 </date_time>
+ <date_time>-2007-10-15T12:13:14</date_time>
+ <date_time>20007-12-31T12:13:14Z</date_time>
+ <date_time>-20007-01-01T12:13:14</date_time>
+
+ <duration> -P2007Y13M32DT25H61M61.123S </duration>
+ <duration>P1Y</duration>
+ <duration>P1M</duration>
+ <duration>P1D</duration>
+ <duration>PT1H</duration>
+ <duration>PT1M</duration>
+ <duration>PT1.1S</duration>
+ <duration>P1YT1S</duration>
+
+</t:root>
diff --git a/tests/cxx/parser/built-in/test.xsd b/tests/cxx/parser/built-in/test.xsd
new file mode 100644
index 0000000..9c00eb4
--- /dev/null
+++ b/tests/cxx/parser/built-in/test.xsd
@@ -0,0 +1,63 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="type">
+ <sequence>
+ <element name="any-type" type="anyType" maxOccurs="unbounded"/>
+ <element name="any-simple-type" type="anySimpleType" maxOccurs="unbounded"/>
+
+ <element name="boolean" type="boolean" maxOccurs="unbounded"/>
+
+ <element name="byte" type="byte" maxOccurs="unbounded"/>
+ <element name="unsigned-byte" type="unsignedByte" maxOccurs="unbounded"/>
+ <element name="short" type="short" maxOccurs="unbounded"/>
+ <element name="unsigned-short" type="unsignedShort" maxOccurs="unbounded"/>
+ <element name="int" type="int" maxOccurs="unbounded"/>
+ <element name="unsigned-int" type="unsignedInt" maxOccurs="unbounded"/>
+ <element name="long" type="long" maxOccurs="unbounded"/>
+ <element name="unsigned-long" type="unsignedLong" maxOccurs="unbounded"/>
+
+ <element name="integer" type="integer" maxOccurs="unbounded"/>
+ <element name="negative-integer" type="negativeInteger" maxOccurs="unbounded"/>
+ <element name="non-positive-integer" type="nonPositiveInteger" maxOccurs="unbounded"/>
+ <element name="positive-integer" type="positiveInteger" maxOccurs="unbounded"/>
+ <element name="non-negative-integer" type="nonNegativeInteger" maxOccurs="unbounded"/>
+
+ <element name="float" type="float" maxOccurs="unbounded"/>
+ <element name="double" type="double" maxOccurs="unbounded"/>
+ <element name="decimal" type="decimal" maxOccurs="unbounded"/>
+
+ <element name="string" type="string" maxOccurs="unbounded"/>
+ <element name="normalized-string" type="normalizedString" maxOccurs="unbounded"/>
+ <element name="token" type="token" maxOccurs="unbounded"/>
+ <element name="name" type="Name" maxOccurs="unbounded"/>
+ <element name="nmtoken" type="NMTOKEN" maxOccurs="unbounded"/>
+ <element name="nmtokens" type="NMTOKENS" maxOccurs="unbounded"/>
+ <element name="ncname" type="NCName" maxOccurs="unbounded"/>
+ <element name="id" type="ID" maxOccurs="unbounded"/>
+ <element name="idref" type="IDREF" maxOccurs="unbounded"/>
+ <element name="idrefs" type="IDREFS" maxOccurs="unbounded"/>
+
+ <element name="language" type="language" maxOccurs="unbounded"/>
+ <element name="uri" type="anyURI" maxOccurs="unbounded"/>
+ <element name="qname" type="QName" maxOccurs="unbounded"/>
+
+ <element name="base64_binary" type="base64Binary" maxOccurs="unbounded"/>
+ <element name="hex_binary" type="hexBinary" maxOccurs="unbounded"/>
+
+ <element name="gday" type="gDay" maxOccurs="unbounded"/>
+ <element name="gmonth" type="gMonth" maxOccurs="unbounded"/>
+ <element name="gyear" type="gYear" maxOccurs="unbounded"/>
+ <element name="gmonth_day" type="gMonthDay" maxOccurs="unbounded"/>
+ <element name="gyear_month" type="gYearMonth" maxOccurs="unbounded"/>
+ <element name="date" type="date" maxOccurs="unbounded"/>
+ <element name="time" type="time" maxOccurs="unbounded"/>
+ <element name="date_time" type="dateTime" maxOccurs="unbounded"/>
+ <element name="duration" type="duration" maxOccurs="unbounded"/>
+
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/parser/enumeration/driver.cxx b/tests/cxx/parser/enumeration/driver.cxx
new file mode 100644
index 0000000..056df76
--- /dev/null
+++ b/tests/cxx/parser/enumeration/driver.cxx
@@ -0,0 +1,83 @@
+// file : tests/cxx/parser/enumeration/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test xsd:enumeration parsing.
+//
+
+#include <string>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace xml_schema;
+
+struct digit_pimpl: test::digit_pskel, int_pimpl
+{
+};
+
+struct gender_pimpl: test::gender_pskel, string_pimpl
+{
+ virtual ::gender
+ post_gender ()
+ {
+ std::string str (post_string ());
+
+ if (str == "male")
+ return male;
+ else
+ return female;
+ }
+};
+
+struct type_pimpl: test::type_pskel
+{
+ virtual void
+ digit (int i)
+ {
+ cout << i << endl;
+ }
+
+ virtual void
+ gender (::gender g)
+ {
+ cout << g << endl;
+ }
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ digit_pimpl digit_p;
+ gender_pimpl gender_p;
+ type_pimpl type_p;
+
+ type_p.parsers (digit_p, gender_p);
+
+ document doc_p (type_p, "test", "root");
+
+ type_p.pre ();
+ doc_p.parse (argv[1]);
+ type_p.post_type ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (std::ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/enumeration/gender.hxx b/tests/cxx/parser/enumeration/gender.hxx
new file mode 100644
index 0000000..be74b4a
--- /dev/null
+++ b/tests/cxx/parser/enumeration/gender.hxx
@@ -0,0 +1,15 @@
+// file : tests/cxx/parser/enumeration/gender.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef GENDER_HXX
+#define GENDER_HXX
+
+enum gender
+{
+ male,
+ female
+};
+
+#endif // GENDER_HXX
diff --git a/tests/cxx/parser/enumeration/makefile b/tests/cxx/parser/enumeration/makefile
new file mode 100644
index 0000000..0376d1a
--- /dev/null
+++ b/tests/cxx/parser/enumeration/makefile
@@ -0,0 +1,75 @@
+# file : tests/cxx/parser/enumeration/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --type-map $(src_base)/test.map
+$(skel): $(out_root)/xsd/xsd $(src_base)/test.map
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/enumeration/output b/tests/cxx/parser/enumeration/output
new file mode 100644
index 0000000..16db301
--- /dev/null
+++ b/tests/cxx/parser/enumeration/output
@@ -0,0 +1,3 @@
+1
+0
+1
diff --git a/tests/cxx/parser/enumeration/test.map b/tests/cxx/parser/enumeration/test.map
new file mode 100644
index 0000000..f8868d6
--- /dev/null
+++ b/tests/cxx/parser/enumeration/test.map
@@ -0,0 +1,7 @@
+namespace test
+{
+ include "gender.hxx";
+
+ digit int int;
+ gender ::gender ::gender;
+}
diff --git a/tests/cxx/parser/enumeration/test.xml b/tests/cxx/parser/enumeration/test.xml
new file mode 100644
index 0000000..a6fa893
--- /dev/null
+++ b/tests/cxx/parser/enumeration/test.xml
@@ -0,0 +1,10 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <digit>1</digit>
+
+ <gender>male</gender>
+ <gender>female</gender>
+
+</t:root>
diff --git a/tests/cxx/parser/enumeration/test.xsd b/tests/cxx/parser/enumeration/test.xsd
new file mode 100644
index 0000000..ded3a18
--- /dev/null
+++ b/tests/cxx/parser/enumeration/test.xsd
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="digit">
+ <restriction base="int">
+ <enumeration value="0"/>
+ <enumeration value="1"/>
+ <enumeration value="2"/>
+ <enumeration value="3"/>
+ <enumeration value="4"/>
+ <enumeration value="5"/>
+ <enumeration value="6"/>
+ <enumeration value="7"/>
+ <enumeration value="8"/>
+ <enumeration value="9"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="gender">
+ <restriction base="string">
+ <enumeration value="male"/>
+ <enumeration value="female"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="type">
+ <choice maxOccurs="unbounded">
+ <element name="digit" type="t:digit"/>
+ <element name="gender" type="t:gender"/>
+ </choice>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/parser/generated-impl/makefile b/tests/cxx/parser/generated-impl/makefile
new file mode 100644
index 0000000..71f94ab
--- /dev/null
+++ b/tests/cxx/parser/generated-impl/makefile
@@ -0,0 +1,81 @@
+# file : tests/cxx/parser/generated-impl/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+
+obj := $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.o) $(xsd:.xsd=-pimpl.o) $(xsd:.xsd=-driver.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/$(xsd:.xsd=-driver)
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+gen := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx) \
+ $(out_base)/$(xsd:.xsd=-pimpl.hxx) \
+ $(out_base)/$(xsd:.xsd=-pimpl.cxx) \
+ $(out_base)/$(xsd:.xsd=-driver.cxx)
+
+$(gen): xsd := $(out_root)/xsd/xsd
+$(gen): xsd_options := --generate-print-impl --generate-test-driver \
+--force-overwrite
+$(gen): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pimpl.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+
+xsd_parser_impl_suffix := -pimpl
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/generated-impl/output b/tests/cxx/parser/generated-impl/output
new file mode 100644
index 0000000..7c58647
--- /dev/null
+++ b/tests/cxx/parser/generated-impl/output
@@ -0,0 +1,122 @@
+gender: male
+foo: foo
+gender: male
+int: 0
+int: 1
+int: 2
+int: 3
+foo: foo
+int: 3
+int: 2
+int: 1
+int: 0
+union: 9
+foo: foo
+union: string
+x: x
+a: aaa
+x: x
+y: y
+a: aaa
+b: bbb
+boolean: 1
+boolean: 0
+boolean: 1
+boolean: 0
+byte: 0
+byte: 123
+byte: -123
+unsigned-byte: 0
+unsigned-byte: 123
+short: 0
+short: -1234
+short: 1234
+unsigned-short: 0
+unsigned-short: 1234
+int: 0
+int: -12345
+int: 12345
+unsigned-int: 0
+unsigned-int: 12345
+long: 0
+long: -123456
+long: 123456
+unsigned-long: 0
+unsigned-long: 123456
+integer: 0
+integer: -123456
+integer: 123456
+negative-integer: -123456
+non-positive-integer: 0
+non-positive-integer: -123456
+positive-integer: 123456
+non-negative-integer: 0
+non-negative-integer: 123456
+float: 0
+float: 1.123
+float: -1.123
+double: 0
+double: 1.1234
+double: -1.1234
+decimal: 0
+decimal: 1.1234
+decimal: -1.1234
+string: string space newline
+normalized-string: string space newline
+token: string space newline
+name: as123:345-.abs
+nmtoken: 1as123:345-.abs
+nmtokens: abc 123
+ncname: as123_345-.abs
+id: abc
+id: a123
+idref: abc
+idrefs: abc a123
+language: en
+language: en-us
+uri: http://www.example.com/foo#bar
+qname: schemaLocation
+qname: xsi:schemaLocation
+base64_binary: 10 bytes
+base64_binary: 1 bytes
+base64_binary: 2 bytes
+base64_binary: 3 bytes
+hex_binary: 0 bytes
+hex_binary: 10 bytes
+gday: ---12+12:0
+gday: ---1
+gday: ---31
+gday: ---15+0:0
+gday: ---15-14:0
+gmonth: --10+12:0
+gmonth: --1
+gmonth: --12+0:0
+gyear: 2007+12:0
+gyear: 1
+gyear: -20000+0:0
+gmonth_day: --10-28+12:0
+gmonth_day: --12-31
+gmonth_day: --1-1+0:0
+gyear_month: 2007-12+12:0
+gyear_month: -2007-10
+gyear_month: 20007-10+0:0
+gyear_month: -20007-1
+date: 2007-12-26+12:0
+date: -2007-10-15
+date: 20007-12-31+0:0
+date: -20007-1-1
+time: 12:46:23.456+12:0
+time: 12:13:14
+time: 12:13:14+0:0
+date_time: 2007-12-26T12:13:14.123+12:0
+date_time: -2007-10-15T12:13:14
+date_time: 20007-12-31T12:13:14+0:0
+date_time: -20007-1-1T12:13:14
+duration: -P2007Y13M32DT25H61M61.123S
+duration: P1Y0M0DT0H0M0S
+duration: P0Y1M0DT0H0M0S
+duration: P0Y0M1DT0H0M0S
+duration: P0Y0M0DT1H0M0S
+duration: P0Y0M0DT0H1M0S
+duration: P0Y0M0DT0H0M1.1S
+duration: P1Y0M0DT0H0M1S
diff --git a/tests/cxx/parser/generated-impl/test.xml b/tests/cxx/parser/generated-impl/test.xml
new file mode 100644
index 0000000..2f29a39
--- /dev/null
+++ b/tests/cxx/parser/generated-impl/test.xml
@@ -0,0 +1,168 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <gender>male</gender>
+ <gender-extension foo="foo">male</gender-extension>
+
+ <list>0 1 2 3</list>
+ <list-extension foo="foo">3 2 1 0</list-extension>
+
+ <union>9</union>
+ <union-extension foo="foo">string</union-extension>
+
+ <complex x="x">
+ <a>aaa</a>
+ </complex>
+
+ <complex-extension x="x" y="y">
+ <a>aaa</a>
+ <b>bbb</b>
+ </complex-extension>
+
+ <any-type>aaa<b>bbb</b>ccc</any-type>
+ <any-simple-type>abc123</any-simple-type>
+
+ <boolean>1</boolean>
+ <boolean> 0 </boolean>
+ <boolean>true</boolean>
+ <boolean> false </boolean>
+
+ <byte>0</byte>
+ <byte>123</byte>
+ <byte>-123</byte>
+
+ <unsigned-byte>0</unsigned-byte>
+ <unsigned-byte>123</unsigned-byte>
+
+ <short>0</short>
+ <short>-1234</short>
+ <short>1234</short>
+
+ <unsigned-short>0</unsigned-short>
+ <unsigned-short>1234</unsigned-short>
+
+ <int>0</int>
+ <int>-12345</int>
+ <int>12345</int>
+
+ <unsigned-int>0</unsigned-int>
+ <unsigned-int>12345</unsigned-int>
+
+ <long>0</long>
+ <long>-123456</long>
+ <long>123456</long>
+
+ <unsigned-long>0</unsigned-long>
+ <unsigned-long>123456</unsigned-long>
+
+ <integer>0</integer>
+ <integer>-123456</integer>
+ <integer>123456</integer>
+
+ <negative-integer>-123456</negative-integer>
+
+ <non-positive-integer>0</non-positive-integer>
+ <non-positive-integer>-123456</non-positive-integer>
+
+ <positive-integer>123456</positive-integer>
+
+ <non-negative-integer>0</non-negative-integer>
+ <non-negative-integer>123456</non-negative-integer>
+
+ <float>0</float>
+ <float>1.123</float>
+ <float>-1.123</float>
+
+ <double>0</double>
+ <double>1.1234</double>
+ <double>-1.1234</double>
+
+ <decimal>0</decimal>
+ <decimal>1.1234</decimal>
+ <decimal>-1.1234</decimal>
+
+ <string>string space newline</string>
+
+ <normalized-string>string space newline</normalized-string>
+
+ <token> string space newline</token>
+
+ <name>as123:345-.abs</name>
+
+ <nmtoken>1as123:345-.abs</nmtoken>
+
+ <nmtokens>abc 123</nmtokens>
+
+ <ncname>as123_345-.abs</ncname>
+
+ <id>abc</id>
+ <id>a123</id>
+
+ <idref>abc</idref>
+
+ <idrefs>abc a123</idrefs>
+
+ <language>en</language>
+ <language>en-us</language>
+
+ <uri>http://www.example.com/foo#bar</uri>
+
+ <qname>schemaLocation</qname>
+ <qname>xsi:schemaLocation</qname>
+
+ <base64_binary>MTIzNDVhYmNqaw==</base64_binary>
+ <base64_binary>YQ==</base64_binary>
+ <base64_binary>YWI=</base64_binary>
+ <base64_binary>YWJj</base64_binary>
+
+ <hex_binary></hex_binary>
+ <hex_binary>31323334356162636a6b</hex_binary>
+
+ <gday>---12+12:00</gday>
+ <gday>---01</gday>
+ <gday>---31</gday>
+ <gday>---15Z</gday>
+ <gday>---15-14:00</gday>
+
+ <gmonth>--10+12:00</gmonth>
+ <gmonth>--01</gmonth>
+ <gmonth>--12Z</gmonth>
+
+ <gyear>2007+12:00</gyear>
+ <gyear>0001</gyear>
+ <gyear>-20000Z</gyear>
+
+ <gmonth_day>--10-28+12:00</gmonth_day>
+ <gmonth_day>--12-31</gmonth_day>
+ <gmonth_day>--01-01Z</gmonth_day>
+
+ <gyear_month>2007-12+12:00</gyear_month>
+ <gyear_month>-2007-10</gyear_month>
+ <gyear_month>20007-10Z</gyear_month>
+ <gyear_month>-20007-01</gyear_month>
+
+ <date>2007-12-26+12:00</date>
+ <date>-2007-10-15</date>
+ <date>20007-12-31Z</date>
+ <date>-20007-01-01</date>
+
+ <time>12:46:23.456+12:00</time>
+ <time>12:13:14</time>
+ <time>12:13:14Z</time>
+
+ <date_time>2007-12-26T12:13:14.123+12:00</date_time>
+ <date_time>-2007-10-15T12:13:14</date_time>
+ <date_time>20007-12-31T12:13:14Z</date_time>
+ <date_time>-20007-01-01T12:13:14</date_time>
+
+ <duration>-P2007Y13M32DT25H61M61.123S</duration>
+ <duration>P1Y</duration>
+ <duration>P1M</duration>
+ <duration>P1D</duration>
+ <duration>PT1H</duration>
+ <duration>PT1M</duration>
+ <duration>PT1.1S</duration>
+ <duration>P1YT1S</duration>
+
+</t:root>
diff --git a/tests/cxx/parser/generated-impl/test.xsd b/tests/cxx/parser/generated-impl/test.xsd
new file mode 100644
index 0000000..7bc8f23
--- /dev/null
+++ b/tests/cxx/parser/generated-impl/test.xsd
@@ -0,0 +1,142 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- enum -->
+
+ <simpleType name="gender">
+ <restriction base="string">
+ <enumeration value="male"/>
+ <enumeration value="female"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="gender-extension">
+ <simpleContent>
+ <extension base="t:gender">
+ <attribute name="foo" type="string"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <!-- list -->
+
+ <simpleType name="list">
+ <list itemType="int"/>
+ </simpleType>
+
+ <complexType name="list-extension">
+ <simpleContent>
+ <extension base="t:list">
+ <attribute name="foo" type="string"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <!-- union -->
+
+ <simpleType name="union">
+ <union memberTypes="int string"/>
+ </simpleType>
+
+ <complexType name="union-extension">
+ <simpleContent>
+ <extension base="t:union">
+ <attribute name="foo" type="string"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <!-- complex -->
+
+ <complexType name="complex">
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ <attribute name="x" type="string"/>
+ </complexType>
+
+ <complexType name="complex-extension">
+ <complexContent>
+ <extension base="t:complex">
+ <sequence>
+ <element name="b" type="string"/>
+ </sequence>
+ <attribute name="y" type="string"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="gender" type="t:gender"/>
+ <element name="gender-extension" type="t:gender-extension"/>
+
+ <element name="list" type="t:list"/>
+ <element name="list-extension" type="t:list-extension"/>
+
+ <element name="union" type="t:union"/>
+ <element name="union-extension" type="t:union-extension"/>
+
+ <element name="complex" type="t:complex"/>
+ <element name="complex-extension" type="t:complex-extension"/>
+
+ <!-- Built-in types. -->
+
+ <element name="any-type" type="anyType" maxOccurs="unbounded"/>
+ <element name="any-simple-type" type="anySimpleType" maxOccurs="unbounded"/>
+
+ <element name="boolean" type="boolean" maxOccurs="unbounded"/>
+
+ <element name="byte" type="byte" maxOccurs="unbounded"/>
+ <element name="unsigned-byte" type="unsignedByte" maxOccurs="unbounded"/>
+ <element name="short" type="short" maxOccurs="unbounded"/>
+ <element name="unsigned-short" type="unsignedShort" maxOccurs="unbounded"/>
+ <element name="int" type="int" maxOccurs="unbounded"/>
+ <element name="unsigned-int" type="unsignedInt" maxOccurs="unbounded"/>
+ <element name="long" type="long" maxOccurs="unbounded"/>
+ <element name="unsigned-long" type="unsignedLong" maxOccurs="unbounded"/>
+
+ <element name="integer" type="integer" maxOccurs="unbounded"/>
+ <element name="negative-integer" type="negativeInteger" maxOccurs="unbounded"/>
+ <element name="non-positive-integer" type="nonPositiveInteger" maxOccurs="unbounded"/>
+ <element name="positive-integer" type="positiveInteger" maxOccurs="unbounded"/>
+ <element name="non-negative-integer" type="nonNegativeInteger" maxOccurs="unbounded"/>
+
+ <element name="float" type="float" maxOccurs="unbounded"/>
+ <element name="double" type="double" maxOccurs="unbounded"/>
+ <element name="decimal" type="decimal" maxOccurs="unbounded"/>
+
+ <element name="string" type="string" maxOccurs="unbounded"/>
+ <element name="normalized-string" type="normalizedString" maxOccurs="unbounded"/>
+ <element name="token" type="token" maxOccurs="unbounded"/>
+ <element name="name" type="Name" maxOccurs="unbounded"/>
+ <element name="nmtoken" type="NMTOKEN" maxOccurs="unbounded"/>
+ <element name="nmtokens" type="NMTOKENS" maxOccurs="unbounded"/>
+ <element name="ncname" type="NCName" maxOccurs="unbounded"/>
+ <element name="id" type="ID" maxOccurs="unbounded"/>
+ <element name="idref" type="IDREF" maxOccurs="unbounded"/>
+ <element name="idrefs" type="IDREFS" maxOccurs="unbounded"/>
+
+ <element name="language" type="language" maxOccurs="unbounded"/>
+ <element name="uri" type="anyURI" maxOccurs="unbounded"/>
+ <element name="qname" type="QName" maxOccurs="unbounded"/>
+
+ <element name="base64_binary" type="base64Binary" maxOccurs="unbounded"/>
+ <element name="hex_binary" type="hexBinary" maxOccurs="unbounded"/>
+
+ <element name="gday" type="gDay" maxOccurs="unbounded"/>
+ <element name="gmonth" type="gMonth" maxOccurs="unbounded"/>
+ <element name="gyear" type="gYear" maxOccurs="unbounded"/>
+ <element name="gmonth_day" type="gMonthDay" maxOccurs="unbounded"/>
+ <element name="gyear_month" type="gYearMonth" maxOccurs="unbounded"/>
+ <element name="date" type="date" maxOccurs="unbounded"/>
+ <element name="time" type="time" maxOccurs="unbounded"/>
+ <element name="date_time" type="dateTime" maxOccurs="unbounded"/>
+ <element name="duration" type="duration" maxOccurs="unbounded"/>
+
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/parser/list/driver.cxx b/tests/cxx/parser/list/driver.cxx
new file mode 100644
index 0000000..531ad94
--- /dev/null
+++ b/tests/cxx/parser/list/driver.cxx
@@ -0,0 +1,107 @@
+// file : tests/cxx/parser/list/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test xsd:list parsing.
+//
+
+#include <string>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace test;
+
+struct string_list_pimpl: string_list_pskel
+{
+ virtual void
+ pre ()
+ {
+ cout << "{" << endl;
+ }
+
+ virtual void
+ item (string const& v)
+ {
+ cout << " '" << v << "'" << endl;
+ }
+
+ virtual void
+ post_string_list ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct string_list_lang_pimpl: string_list_lang_pskel
+{
+ virtual void
+ pre ()
+ {
+ cout << "{" << endl;
+ }
+
+ virtual void
+ item (string const& v)
+ {
+ cout << " '" << v << "'" << endl;
+ }
+
+ virtual void
+ lang (string const& v)
+ {
+ cout << " lang: '" << v << "'" << endl;
+ }
+
+ virtual void
+ post_string_list_lang ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct type_pimpl: type_pskel
+{
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ xml_schema::string_pimpl string_p;
+ string_list_pimpl string_list_p;
+ string_list_lang_pimpl string_list_lang_p;
+ type_pimpl type_p;
+
+ string_list_p.parsers (string_p);
+ string_list_lang_p.parsers (string_p, string_p);
+ type_p.parsers (string_list_p, string_list_lang_p);
+
+ xml_schema::document doc_p (type_p, "test", "root");
+
+ type_p.pre ();
+ doc_p.parse (argv[1]);
+ type_p.post_type ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/list/makefile b/tests/cxx/parser/list/makefile
new file mode 100644
index 0000000..c86fc31
--- /dev/null
+++ b/tests/cxx/parser/list/makefile
@@ -0,0 +1,74 @@
+# file : tests/cxx/parser/list/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/list/output b/tests/cxx/parser/list/output
new file mode 100644
index 0000000..3642c4d
--- /dev/null
+++ b/tests/cxx/parser/list/output
@@ -0,0 +1,26 @@
+{
+}
+
+{
+}
+
+{
+}
+
+{
+ 'one'
+}
+
+{
+ 'one'
+ 'two'
+ 'three'
+}
+
+{
+ lang: 'en'
+ 'one'
+ 'two'
+ 'three'
+}
+
diff --git a/tests/cxx/parser/list/test.xml b/tests/cxx/parser/list/test.xml
new file mode 100644
index 0000000..52229db
--- /dev/null
+++ b/tests/cxx/parser/list/test.xml
@@ -0,0 +1,25 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <string-list/>
+
+ <string-list> </string-list>
+
+ <string-list>
+
+ </string-list>
+
+ <string-list>one</string-list>
+
+ <string-list>
+ one two
+ three
+ </string-list>
+
+ <string-list-lang lang="en">
+ one two
+ three
+ </string-list-lang>
+
+</t:root>
diff --git a/tests/cxx/parser/list/test.xsd b/tests/cxx/parser/list/test.xsd
new file mode 100644
index 0000000..79bd084
--- /dev/null
+++ b/tests/cxx/parser/list/test.xsd
@@ -0,0 +1,25 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="string-list">
+ <list itemType="string"/>
+ </simpleType>
+
+ <complexType name="string-list-lang">
+ <simpleContent>
+ <extension base="t:string-list">
+ <attribute name="lang" type="string"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="type">
+ <choice maxOccurs="unbounded">
+ <element name="string-list" type="t:string-list"/>
+ <element name="string-list-lang" type="t:string-list-lang"/>
+ </choice>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/parser/makefile b/tests/cxx/parser/makefile
new file mode 100644
index 0000000..955be44
--- /dev/null
+++ b/tests/cxx/parser/makefile
@@ -0,0 +1,24 @@
+# file : tests/cxx/parser/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make
+
+
+tests := built-in enumeration generated-impl list recursive \
+name-clash/inheritance polymorphism test-template validation \
+union
+
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/parser/name-clash/inheritance/driver.cxx b/tests/cxx/parser/name-clash/inheritance/driver.cxx
new file mode 100644
index 0000000..86b2746
--- /dev/null
+++ b/tests/cxx/parser/name-clash/inheritance/driver.cxx
@@ -0,0 +1,64 @@
+// file : tests/cxx/parser/name-clash/inheritance/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test for name clashes across inheritance hierarchy.
+//
+
+#include <string>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace test;
+
+struct derived_pimpl: derived_pskel
+{
+ virtual void
+ e (string const& v)
+ {
+ cout << "e: " << v << endl;
+ }
+
+ virtual void
+ e1 (string const& v)
+ {
+ cout << "e1: " << v << endl;
+ }
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ xml_schema::string_pimpl string_p;
+ derived_pimpl derived_p;
+
+ derived_p.parsers (string_p, string_p);
+
+ xml_schema::document doc_p (derived_p, "test", "root");
+
+ derived_p.pre ();
+ doc_p.parse (argv[1]);
+ derived_p.post_derived ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (std::ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/name-clash/inheritance/makefile b/tests/cxx/parser/name-clash/inheritance/makefile
new file mode 100644
index 0000000..1d530d7
--- /dev/null
+++ b/tests/cxx/parser/name-clash/inheritance/makefile
@@ -0,0 +1,75 @@
+# file : tests/cxx/parser/name-clash/inheritance/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-validation
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/name-clash/inheritance/output b/tests/cxx/parser/name-clash/inheritance/output
new file mode 100644
index 0000000..4efd51b
--- /dev/null
+++ b/tests/cxx/parser/name-clash/inheritance/output
@@ -0,0 +1,2 @@
+e: e
+e1: e1
diff --git a/tests/cxx/parser/name-clash/inheritance/test.xml b/tests/cxx/parser/name-clash/inheritance/test.xml
new file mode 100644
index 0000000..8c17101
--- /dev/null
+++ b/tests/cxx/parser/name-clash/inheritance/test.xml
@@ -0,0 +1,8 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <e>e</e>
+ <e>e1</e>
+
+</t:root>
diff --git a/tests/cxx/parser/name-clash/inheritance/test.xsd b/tests/cxx/parser/name-clash/inheritance/test.xsd
new file mode 100644
index 0000000..62a782e
--- /dev/null
+++ b/tests/cxx/parser/name-clash/inheritance/test.xsd
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="base">
+ <sequence>
+ <element name="e" type="string"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="derived">
+ <complexContent>
+ <extension base="t:base">
+ <sequence>
+ <element name="e" type="string"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <element name="root" type="t:derived"/>
+
+</schema>
diff --git a/tests/cxx/parser/polymorphism/makefile b/tests/cxx/parser/polymorphism/makefile
new file mode 100644
index 0000000..a3c4f3e
--- /dev/null
+++ b/tests/cxx/parser/polymorphism/makefile
@@ -0,0 +1,22 @@
+# file : tests/cxx/parser/polymorphism/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+
+tests := same-type
+
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/parser/polymorphism/same-type/driver.cxx b/tests/cxx/parser/polymorphism/same-type/driver.cxx
new file mode 100644
index 0000000..0607ff9
--- /dev/null
+++ b/tests/cxx/parser/polymorphism/same-type/driver.cxx
@@ -0,0 +1,64 @@
+// file : tests/cxx/parser/polymorphism/same-type/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test substitution group and xsi:type that don't change the type.
+//
+
+#include <string>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace test;
+
+struct base_pimpl: base_pskel
+{
+ virtual void
+ a (string const& v)
+ {
+ cout << v << endl;
+ }
+};
+
+struct type_pimpl: type_pskel
+{
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ xml_schema::string_pimpl string_p;
+ base_pimpl base_p;
+ type_pimpl type_p;
+
+ base_p.parsers (string_p);
+ type_p.parsers (base_p);
+
+ xml_schema::document doc_p (type_p, "test", "root");
+
+ type_p.pre ();
+ doc_p.parse (argv[1]);
+ type_p.post_type ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (std::ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/polymorphism/same-type/makefile b/tests/cxx/parser/polymorphism/same-type/makefile
new file mode 100644
index 0000000..5fb28b1
--- /dev/null
+++ b/tests/cxx/parser/polymorphism/same-type/makefile
@@ -0,0 +1,75 @@
+# file : tests/cxx/parser/polymorphism/same-type/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-polymorphic
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/polymorphism/same-type/output b/tests/cxx/parser/polymorphism/same-type/output
new file mode 100644
index 0000000..d418277
--- /dev/null
+++ b/tests/cxx/parser/polymorphism/same-type/output
@@ -0,0 +1,4 @@
+a1
+a2
+a3
+a4
diff --git a/tests/cxx/parser/polymorphism/same-type/test.xml b/tests/cxx/parser/polymorphism/same-type/test.xml
new file mode 100644
index 0000000..f8b6d1e
--- /dev/null
+++ b/tests/cxx/parser/polymorphism/same-type/test.xml
@@ -0,0 +1,10 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <t:base><a>a1</a></t:base>
+ <t:derived><a>a2</a></t:derived>
+ <t:base xsi:type="t:base"><a>a3</a></t:base>
+ <t:derived xsi:type="t:base"><a>a4</a></t:derived>
+
+</t:root>
diff --git a/tests/cxx/parser/polymorphism/same-type/test.xsd b/tests/cxx/parser/polymorphism/same-type/test.xsd
new file mode 100644
index 0000000..a4157d3
--- /dev/null
+++ b/tests/cxx/parser/polymorphism/same-type/test.xsd
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="base">
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ </complexType>
+
+ <element name="base" type="t:base"/>
+ <element name="derived" type="t:base" substitutionGroup="t:base"/>
+
+ <complexType name="type">
+ <sequence>
+ <element ref="t:base" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/parser/recursive/driver.cxx b/tests/cxx/parser/recursive/driver.cxx
new file mode 100644
index 0000000..db74cc6
--- /dev/null
+++ b/tests/cxx/parser/recursive/driver.cxx
@@ -0,0 +1,141 @@
+// file : tests/cxx/parser/recursive/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test recursive parser invocation.
+//
+
+#include <iostream>
+#include <string>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+
+struct sub_pimpl: sub_type_pskel
+{
+ virtual void
+ pre ()
+ {
+ cout << "sub::pre" << endl;
+ }
+
+ virtual void
+ sub ()
+ {
+ cout << "sub::sub" << endl;
+ }
+
+ virtual void
+ sub2 ()
+ {
+ cout << "sub::sub2" << endl;
+ }
+
+ virtual void
+ name (string const& n)
+ {
+ cout << "sub::name: " << n << endl;
+ }
+
+ virtual void
+ post_sub_type ()
+ {
+ cout << "sub::post" << endl;
+ }
+};
+
+struct indir_pimpl: indir_type_pskel
+{
+ virtual void
+ pre ()
+ {
+ cout << "indir::pre" << endl;
+ }
+
+ virtual void
+ sub ()
+ {
+ cout << "indir::sub" << endl;
+ }
+
+ virtual void
+ name (string const& n)
+ {
+ cout << "indir::name: " << n << endl;
+ }
+
+ virtual void
+ post_indir_type ()
+ {
+ cout << "indir::post" << endl;
+ }
+};
+
+struct test_pimpl: test_type_pskel
+{
+ virtual void
+ pre ()
+ {
+ cout << "test::pre" << endl;
+ }
+
+ virtual void
+ sub ()
+ {
+ cout << "test::sub" << endl;
+ }
+
+ virtual void
+ name (string const& n)
+ {
+ cout << "test::name: " << n << endl;
+ }
+
+ virtual void
+ post_test_type ()
+ {
+ cout << "test::post" << endl;
+ }
+};
+
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ xml_schema::string_pimpl string_p;
+
+ sub_pimpl sub_p;
+ indir_pimpl indir_p;
+ test_pimpl test_p;
+
+ sub_p.parsers (sub_p, indir_p, sub_p, string_p);
+ indir_p.parsers (sub_p, string_p);
+ test_p.parsers (sub_p, string_p);
+
+ xml_schema::document doc_p (test_p, "test");
+
+ test_p.pre ();
+ doc_p.parse (argv[1]);
+ test_p.post_test_type ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/recursive/makefile b/tests/cxx/parser/recursive/makefile
new file mode 100644
index 0000000..20b4599
--- /dev/null
+++ b/tests/cxx/parser/recursive/makefile
@@ -0,0 +1,75 @@
+# file : tests/cxx/parser/recursive/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-validation
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/recursive/output b/tests/cxx/parser/recursive/output
new file mode 100644
index 0000000..f26fb72
--- /dev/null
+++ b/tests/cxx/parser/recursive/output
@@ -0,0 +1,22 @@
+test::pre
+test::name: testName
+sub::pre
+sub::name: subName
+sub::pre
+sub::name: sub-subName
+sub::post
+sub::sub
+indir::pre
+indir::name: sub-indirName
+sub::pre
+sub::name: sub-indir-subName
+sub::post
+indir::sub
+indir::post
+sub::pre
+sub::name: sub-sub2Name
+sub::post
+sub::sub2
+sub::post
+test::sub
+test::post
diff --git a/tests/cxx/parser/recursive/test.xml b/tests/cxx/parser/recursive/test.xml
new file mode 100644
index 0000000..f6c219d
--- /dev/null
+++ b/tests/cxx/parser/recursive/test.xml
@@ -0,0 +1,11 @@
+<test xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="test.xsd"
+ name="testName">
+ <sub name="subName">
+ <sub name="sub-subName"/>
+ <indir name="sub-indirName">
+ <sub name="sub-indir-subName"/>
+ </indir>
+ <sub2 name="sub-sub2Name"/>
+ </sub>
+</test>
diff --git a/tests/cxx/parser/recursive/test.xsd b/tests/cxx/parser/recursive/test.xsd
new file mode 100644
index 0000000..33e1d2d
--- /dev/null
+++ b/tests/cxx/parser/recursive/test.xsd
@@ -0,0 +1,27 @@
+<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
+
+ <xs:complexType name="sub_type">
+ <xs:sequence>
+ <xs:element name="sub" type="sub_type" minOccurs="0"/>
+ <xs:element name="indir" type="indir_type" minOccurs="0"/>
+ <xs:element name="sub2" type="sub_type" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" />
+ </xs:complexType>
+
+ <xs:complexType name="indir_type">
+ <xs:sequence>
+ <xs:element name="sub" type="sub_type" minOccurs="0"/>
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" />
+ </xs:complexType>
+
+ <xs:complexType name="test_type">
+ <xs:sequence>
+ <xs:element name="sub" type="sub_type" />
+ </xs:sequence>
+ <xs:attribute name="name" type="xs:string" />
+ </xs:complexType>
+
+ <xs:element name="test" type="test_type" />
+</xs:schema>
diff --git a/tests/cxx/parser/test-template/driver.cxx b/tests/cxx/parser/test-template/driver.cxx
new file mode 100644
index 0000000..aa14601
--- /dev/null
+++ b/tests/cxx/parser/test-template/driver.cxx
@@ -0,0 +1,68 @@
+// file : tests/cxx/parser/test-template/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Insert test description here.
+//
+
+#include <string>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace test;
+
+struct type_pimpl: type_pskel
+{
+ virtual void
+ pre ()
+ {
+ }
+
+ virtual void
+ a (string const& v)
+ {
+ cout << v << endl;
+ }
+
+ virtual void
+ post_type ()
+ {
+ }
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ xml_schema::string_pimpl string_p;
+ type_pimpl type_p;
+
+ type_p.parsers (string_p);
+
+ xml_schema::document doc_p (type_p, "test", "root");
+
+ type_p.pre ();
+ doc_p.parse (argv[1]);
+ type_p.post_type ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (std::ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/test-template/makefile b/tests/cxx/parser/test-template/makefile
new file mode 100644
index 0000000..3b6855a
--- /dev/null
+++ b/tests/cxx/parser/test-template/makefile
@@ -0,0 +1,74 @@
+# file : tests/cxx/parser/test-template/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/test-template/output b/tests/cxx/parser/test-template/output
new file mode 100644
index 0000000..7898192
--- /dev/null
+++ b/tests/cxx/parser/test-template/output
@@ -0,0 +1 @@
+a
diff --git a/tests/cxx/parser/test-template/test.xml b/tests/cxx/parser/test-template/test.xml
new file mode 100644
index 0000000..624a80c
--- /dev/null
+++ b/tests/cxx/parser/test-template/test.xml
@@ -0,0 +1,7 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <a>a</a>
+
+</t:root>
diff --git a/tests/cxx/parser/test-template/test.xsd b/tests/cxx/parser/test-template/test.xsd
new file mode 100644
index 0000000..07bebc7
--- /dev/null
+++ b/tests/cxx/parser/test-template/test.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="type">
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/parser/union/driver.cxx b/tests/cxx/parser/union/driver.cxx
new file mode 100644
index 0000000..765f06a
--- /dev/null
+++ b/tests/cxx/parser/union/driver.cxx
@@ -0,0 +1,62 @@
+// file : tests/cxx/parser/union/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test xsd:union parsing.
+//
+
+#include <string>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace test;
+
+struct int_string_union_pimpl: int_string_union_pskel
+{
+ virtual void
+ _characters (const xml_schema::ro_string& s)
+ {
+ cout << "'" << s << "'" << endl;
+ }
+};
+
+struct type_pimpl: type_pskel
+{
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ int_string_union_pimpl int_string_union_p;
+ type_pimpl type_p;
+
+ type_p.parsers (int_string_union_p);
+
+ xml_schema::document doc_p (type_p, "test", "root");
+
+ type_p.pre ();
+ doc_p.parse (argv[1]);
+ type_p.post_type ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (std::ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/union/makefile b/tests/cxx/parser/union/makefile
new file mode 100644
index 0000000..0e186b7
--- /dev/null
+++ b/tests/cxx/parser/union/makefile
@@ -0,0 +1,74 @@
+# file : tests/cxx/parser/union/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/union/output b/tests/cxx/parser/union/output
new file mode 100644
index 0000000..a92ffc3
--- /dev/null
+++ b/tests/cxx/parser/union/output
@@ -0,0 +1,2 @@
+'one'
+'1'
diff --git a/tests/cxx/parser/union/test.xml b/tests/cxx/parser/union/test.xml
new file mode 100644
index 0000000..5b3e799
--- /dev/null
+++ b/tests/cxx/parser/union/test.xml
@@ -0,0 +1,10 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <int-string-union/>
+ <int-string-union> </int-string-union>
+ <int-string-union>one</int-string-union>
+ <int-string-union>1</int-string-union>
+
+</t:root>
diff --git a/tests/cxx/parser/union/test.xsd b/tests/cxx/parser/union/test.xsd
new file mode 100644
index 0000000..5bf3d47
--- /dev/null
+++ b/tests/cxx/parser/union/test.xsd
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="int-string-union">
+ <union memberTypes="int string"/>
+ </simpleType>
+
+ <complexType name="type">
+ <choice maxOccurs="unbounded">
+ <element name="int-string-union" type="t:int-string-union"/>
+ </choice>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/parser/validation/all/driver.cxx b/tests/cxx/parser/validation/all/driver.cxx
new file mode 100644
index 0000000..a5ad1cf
--- /dev/null
+++ b/tests/cxx/parser/validation/all/driver.cxx
@@ -0,0 +1,100 @@
+// file : tests/cxx/parser/validation/all/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the all compositor validation.
+//
+
+#include <string>
+#include <fstream>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace test;
+
+struct all_pimpl: all_pskel
+{
+ virtual void
+ pre ()
+ {
+ cout << "{" << endl;
+ }
+
+ virtual void
+ a (string const& v)
+ {
+ cout << " a = " << v << endl;
+ }
+
+ virtual void
+ b (string const& v)
+ {
+ cout << " b = " << v << endl;
+ }
+
+ virtual void
+ c (string const& v)
+ {
+ cout << " c = " << v << endl;
+ }
+
+ virtual void
+ post_all ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct type_pimpl: type_pskel
+{
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ xml_schema::string_pimpl string_p;
+ all_pimpl all_p;
+ type_pimpl type_p;
+
+ all_p.parsers (string_p, string_p, string_p);
+ type_p.parsers (all_p);
+
+ xml_schema::document doc_p (type_p, "test", "root");
+
+ try
+ {
+ ifstream ifs (argv[1]);
+ type_p.pre ();
+ doc_p.parse (ifs, argv[1], "", xml_schema::flags::dont_validate);
+ type_p.post_type ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cout << " " << e << endl
+ << "}" << endl
+ << endl;
+ }
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/validation/all/makefile b/tests/cxx/parser/validation/all/makefile
new file mode 100644
index 0000000..7295256
--- /dev/null
+++ b/tests/cxx/parser/validation/all/makefile
@@ -0,0 +1,85 @@
+# file : tests/cxx/parser/validation/all/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+tests := 000 001 002 003
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-validation
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+test_targets := $(addprefix $(out_base)/.test-,$(tests))
+
+.PHONY: $(test)
+$(test): $(test_targets)
+
+
+$(test_targets): driver := $(driver)
+
+.PHONY: $(out_base)/.test-%
+$(out_base)/.test-%: $(driver) $(src_base)/test.xsd $(src_base)/test-%.xml $(src_base)/test-%.std
+ $(call message,test $(out_base)/$*,$(driver) $(src_base)/test-$*.xml | diff -u $(src_base)/test-$*.std -)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/validation/all/test-000.std b/tests/cxx/parser/validation/all/test-000.std
new file mode 100644
index 0000000..b4445f2
--- /dev/null
+++ b/tests/cxx/parser/validation/all/test-000.std
@@ -0,0 +1,46 @@
+{
+ a = a
+ b = b
+ c = c
+}
+
+{
+ a = a
+ c = c
+ b = b
+}
+
+{
+ b = b
+ a = a
+ c = c
+}
+
+{
+ b = b
+ c = c
+ a = a
+}
+
+{
+ c = c
+ a = a
+ b = b
+}
+
+{
+ c = c
+ b = b
+ a = a
+}
+
+{
+ a = a
+ b = b
+}
+
+{
+ a = a
+ b = b
+}
+
diff --git a/tests/cxx/parser/validation/all/test-000.xml b/tests/cxx/parser/validation/all/test-000.xml
new file mode 100644
index 0000000..6e46fae
--- /dev/null
+++ b/tests/cxx/parser/validation/all/test-000.xml
@@ -0,0 +1,53 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- all combinations -->
+ <all>
+ <a>a</a>
+ <b>b</b>
+ <c>c</c>
+ </all>
+
+ <all>
+ <a>a</a>
+ <c>c</c>
+ <b>b</b>
+ </all>
+
+ <all>
+ <b>b</b>
+ <a>a</a>
+ <c>c</c>
+ </all>
+
+ <all>
+ <b>b</b>
+ <c>c</c>
+ <a>a</a>
+ </all>
+
+ <all>
+ <c>c</c>
+ <a>a</a>
+ <b>b</b>
+ </all>
+
+ <all>
+ <c>c</c>
+ <b>b</b>
+ <a>a</a>
+ </all>
+
+ <!-- optional c is not present -->
+ <all>
+ <a>a</a>
+ <b>b</b>
+ </all>
+
+ <all>
+ <a>a</a>
+ <b>b</b>
+ </all>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/all/test-001.std b/tests/cxx/parser/validation/all/test-001.std
new file mode 100644
index 0000000..0472ad9
--- /dev/null
+++ b/tests/cxx/parser/validation/all/test-001.std
@@ -0,0 +1,6 @@
+{
+ a = a
+ c = c
+ :9:9 error: expected element 'b'
+}
+
diff --git a/tests/cxx/parser/validation/all/test-001.xml b/tests/cxx/parser/validation/all/test-001.xml
new file mode 100644
index 0000000..3df5600
--- /dev/null
+++ b/tests/cxx/parser/validation/all/test-001.xml
@@ -0,0 +1,11 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- required b is not present (invalid) -->
+ <all>
+ <a>a</a>
+ <c>c</c>
+ </all>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/all/test-002.std b/tests/cxx/parser/validation/all/test-002.std
new file mode 100644
index 0000000..c014230
--- /dev/null
+++ b/tests/cxx/parser/validation/all/test-002.std
@@ -0,0 +1,4 @@
+{
+ :7:9 error: expected element 'a'
+}
+
diff --git a/tests/cxx/parser/validation/all/test-002.xml b/tests/cxx/parser/validation/all/test-002.xml
new file mode 100644
index 0000000..aed0c0c
--- /dev/null
+++ b/tests/cxx/parser/validation/all/test-002.xml
@@ -0,0 +1,9 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- invalid -->
+ <all>
+ </all>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/all/test-003.std b/tests/cxx/parser/validation/all/test-003.std
new file mode 100644
index 0000000..dd8c0d3
--- /dev/null
+++ b/tests/cxx/parser/validation/all/test-003.std
@@ -0,0 +1,6 @@
+{
+ a = a
+ b = b
+ :9:7 error: unexpected element 'a'
+}
+
diff --git a/tests/cxx/parser/validation/all/test-003.xml b/tests/cxx/parser/validation/all/test-003.xml
new file mode 100644
index 0000000..b147cba
--- /dev/null
+++ b/tests/cxx/parser/validation/all/test-003.xml
@@ -0,0 +1,12 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- invalid -->
+ <all>
+ <a>a</a>
+ <b>b</b>
+ <a>a</a>
+ </all>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/all/test.xsd b/tests/cxx/parser/validation/all/test.xsd
new file mode 100644
index 0000000..1f670e3
--- /dev/null
+++ b/tests/cxx/parser/validation/all/test.xsd
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="all">
+ <all minOccurs="1">
+ <element name="a" type="string"/>
+ <element name="b" type="string"/>
+ <element name="c" type="string" minOccurs="0"/>
+ </all>
+ </complexType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="all" type="t:all" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/parser/validation/any/driver.cxx b/tests/cxx/parser/validation/any/driver.cxx
new file mode 100644
index 0000000..956bc7a
--- /dev/null
+++ b/tests/cxx/parser/validation/any/driver.cxx
@@ -0,0 +1,123 @@
+// file : tests/cxx/parser/validation/any/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the any particle validation.
+//
+
+#include <string>
+#include <fstream>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace test;
+using xml_schema::ro_string;
+
+struct any_a_pimpl: any_a_pskel
+{
+ virtual void
+ pre ()
+ {
+ cout << "{" << endl;
+ }
+
+ virtual void
+ a (string const& v)
+ {
+ cout << " a = " << v << endl;
+ }
+
+ virtual void
+ x (string const& v)
+ {
+ cout << " x = " << v << endl;
+ }
+
+ virtual void
+ _start_any_element (ro_string const&,
+ ro_string const& n,
+ ro_string const*)
+ {
+ cout << " start any element '" << n << "'" << endl;
+ }
+
+ virtual void
+ _end_any_element (ro_string const&, ro_string const& n)
+ {
+ cout << " end any element '" << n << "'" << endl;
+ }
+
+ virtual void
+ _any_attribute (ro_string const&,
+ ro_string const& n,
+ ro_string const& v)
+ {
+ cout << " any attribute " << n << " = '" << v << "'" << endl;
+ }
+
+ virtual void
+ _any_characters (ro_string const& s)
+ {
+ cout << " any text: '" << s << "'" << endl;
+ }
+
+ virtual void
+ post_any_a ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct type_pimpl: type_pskel
+{
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ xml_schema::string_pimpl string_p;
+ any_a_pimpl any_a_p;
+ type_pimpl type_p;
+
+ any_a_p.parsers (string_p, string_p);
+ type_p.parsers (any_a_p);
+
+ xml_schema::document doc_p (type_p, "test", "root");
+
+ try
+ {
+ ifstream ifs (argv[1]);
+ type_p.pre ();
+ doc_p.parse (ifs, argv[1], "", xml_schema::flags::dont_validate);
+ type_p.post_type ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cout << " " << e << endl
+ << "}" << endl
+ << endl;
+ }
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/validation/any/makefile b/tests/cxx/parser/validation/any/makefile
new file mode 100644
index 0000000..76d8618
--- /dev/null
+++ b/tests/cxx/parser/validation/any/makefile
@@ -0,0 +1,85 @@
+# file : tests/cxx/parser/validation/any/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+tests := 000
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-validation
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+test_targets := $(addprefix $(out_base)/.test-,$(tests))
+
+.PHONY: $(test)
+$(test): $(test_targets)
+
+
+$(test_targets): driver := $(driver)
+
+.PHONY: $(out_base)/.test-%
+$(out_base)/.test-%: $(driver) $(src_base)/test.xsd $(src_base)/test-%.xml $(src_base)/test-%.std
+ $(call message,test $(out_base)/$*,$(driver) $(src_base)/test-$*.xml | diff -u $(src_base)/test-$*.std -)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/validation/any/test-000.std b/tests/cxx/parser/validation/any/test-000.std
new file mode 100644
index 0000000..a1cc6e3
--- /dev/null
+++ b/tests/cxx/parser/validation/any/test-000.std
@@ -0,0 +1,29 @@
+{
+ start any element 'any'
+ end any element 'any'
+}
+
+{
+ start any element 'any'
+ any attribute x = 'xxx'
+ any text: 'aaa'
+ start any element 'a'
+ any text: 'bbb'
+ end any element 'a'
+ any text: 'ccc'
+ end any element 'any'
+}
+
+{
+ x = x
+ a = a
+ start any element 'any'
+ any attribute x = 'xxx'
+ any text: 'aaa'
+ start any element 'a'
+ any text: 'bbb'
+ end any element 'a'
+ any text: 'ccc'
+ end any element 'any'
+}
+
diff --git a/tests/cxx/parser/validation/any/test-000.xml b/tests/cxx/parser/validation/any/test-000.xml
new file mode 100644
index 0000000..f1a0c83
--- /dev/null
+++ b/tests/cxx/parser/validation/any/test-000.xml
@@ -0,0 +1,21 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- test dispatching of any-nested elements and attributes -->
+
+ <any-a>
+ <o:any/>
+ </any-a>
+
+ <any-a>
+ <o:any x="xxx">aaa<a>bbb</a>ccc</o:any>
+ </any-a>
+
+ <any-a x="x">
+ <a>a</a>
+ <o:any x="xxx">aaa<a>bbb</a>ccc</o:any>
+ </any-a>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/any/test.xsd b/tests/cxx/parser/validation/any/test.xsd
new file mode 100644
index 0000000..c05aeb5
--- /dev/null
+++ b/tests/cxx/parser/validation/any/test.xsd
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="any-a">
+ <sequence>
+ <element name="a" type="string" minOccurs="0"/>
+ <any namespace="other" processContents="skip" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="x" type="string"/>
+ </complexType>
+
+ <complexType name="type">
+ <choice maxOccurs="unbounded">
+ <element name="any-a" type="t:any-a"/>
+ </choice>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/parser/validation/attribute/driver.cxx b/tests/cxx/parser/validation/attribute/driver.cxx
new file mode 100644
index 0000000..b49af04
--- /dev/null
+++ b/tests/cxx/parser/validation/attribute/driver.cxx
@@ -0,0 +1,199 @@
+// file : tests/cxx/parser/validation/attribute/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test attribute and attribute wildcard (anyAttribute) validation.
+//
+
+#include <string>
+#include <fstream>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace test;
+using xml_schema::ro_string;
+
+struct pass_a_pimpl: pass_a_pskel
+{
+ virtual void
+ pre ()
+ {
+ cout << "pass-a" << endl
+ << "{" << endl;
+ }
+
+ virtual void
+ a (string const& v)
+ {
+ cout << " a = " << v << endl;
+ }
+
+ virtual void
+ b (string const& v)
+ {
+ cout << " b = " << v << endl;
+ }
+
+ virtual void
+ _any_attribute (ro_string const& ns,
+ ro_string const& name,
+ ro_string const& value)
+ {
+ cout << " any: " << ns << "#" << name << " = " << value << endl;
+ }
+
+ virtual void
+ post_pass_a ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct pass_b_pimpl: pass_b_pskel
+{
+ virtual void
+ pre ()
+ {
+ cout << "pass-b" << endl
+ << "{" << endl;
+ }
+
+ virtual void
+ a (string const& v)
+ {
+ cout << " a = " << v << endl;
+ }
+
+ virtual void
+ b (string const& v)
+ {
+ cout << " b = " << v << endl;
+ }
+
+ virtual void
+ _any_attribute (ro_string const& ns,
+ ro_string const& name,
+ ro_string const& value)
+ {
+ cout << " any: " << ns << "#" << name << " = " << value << endl;
+ }
+
+ virtual void
+ post_pass_b ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct pass_c_pimpl: pass_c_pskel
+{
+ virtual void
+ pre ()
+ {
+ cout << "pass-c" << endl
+ << "{" << endl;
+ }
+
+ virtual void
+ a (string const& v)
+ {
+ cout << " a = " << v << endl;
+ }
+
+ virtual void
+ b (string const& v)
+ {
+ cout << " b = " << v << endl;
+ }
+
+ virtual void
+ post_pass_c ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct fail_pimpl: fail_pskel
+{
+ virtual void
+ pre ()
+ {
+ cout << "fail" << endl
+ << "{" << endl;
+ }
+
+ virtual void
+ a (string const& v)
+ {
+ cout << " a = " << v << endl;
+ }
+
+ virtual void
+ post_fail ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct type_pimpl: type_pskel
+{
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ xml_schema::string_pimpl string_p;
+ pass_a_pimpl pass_a_p;
+ pass_b_pimpl pass_b_p;
+ pass_c_pimpl pass_c_p;
+ fail_pimpl fail_p;
+ type_pimpl type_p;
+
+ pass_a_p.parsers (string_p, string_p);
+ pass_b_p.parsers (string_p, string_p);
+ pass_c_p.parsers (string_p, string_p);
+ fail_p.parsers (string_p);
+ type_p.parsers (pass_a_p, pass_b_p, pass_c_p, fail_p);
+
+ xml_schema::document doc_p (type_p, "test", "root");
+
+ try
+ {
+ ifstream ifs (argv[1]);
+ type_p.pre ();
+ doc_p.parse (ifs, argv[1], "", xml_schema::flags::dont_validate);
+ type_p.post_type ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cout << " " << e << endl
+ << "}" << endl
+ << endl;
+ }
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/validation/attribute/makefile b/tests/cxx/parser/validation/attribute/makefile
new file mode 100644
index 0000000..281d174
--- /dev/null
+++ b/tests/cxx/parser/validation/attribute/makefile
@@ -0,0 +1,85 @@
+# file : tests/cxx/parser/validation/attribute/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+tests := 000
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-validation
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+test_targets := $(addprefix $(out_base)/.test-,$(tests))
+
+.PHONY: $(test)
+$(test): $(test_targets)
+
+
+$(test_targets): driver := $(driver)
+
+.PHONY: $(out_base)/.test-%
+$(out_base)/.test-%: $(driver) $(src_base)/test.xsd $(src_base)/test-%.xml $(src_base)/test-%.std
+ $(call message,test $(out_base)/$*,$(driver) $(src_base)/test-$*.xml | diff -u $(src_base)/test-$*.std -)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/validation/attribute/test-000.std b/tests/cxx/parser/validation/attribute/test-000.std
new file mode 100644
index 0000000..847b054
--- /dev/null
+++ b/tests/cxx/parser/validation/attribute/test-000.std
@@ -0,0 +1,24 @@
+pass-a
+{
+ b = b
+ any: test#foo = foo
+ any: test#bar = bar
+}
+
+pass-b
+{
+ a = a
+ b = b
+}
+
+pass-c
+{
+ a = a
+ b = b
+}
+
+fail
+{
+ :8:10 error: expected attribute 'a'
+}
+
diff --git a/tests/cxx/parser/validation/attribute/test-000.xml b/tests/cxx/parser/validation/attribute/test-000.xml
new file mode 100644
index 0000000..b994d1a
--- /dev/null
+++ b/tests/cxx/parser/validation/attribute/test-000.xml
@@ -0,0 +1,10 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <pass-a b="b" t:foo="foo" t:bar="bar"/>
+ <pass-b a="a" b="b"/>
+ <pass-c a="a" b="b"/>
+ <fail/>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/attribute/test.xsd b/tests/cxx/parser/validation/attribute/test.xsd
new file mode 100644
index 0000000..833eb8e
--- /dev/null
+++ b/tests/cxx/parser/validation/attribute/test.xsd
@@ -0,0 +1,71 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+
+ <!-- Test optional and required attributes as well as a wildcard. -->
+ <complexType name="pass-a">
+ <attribute name="a" type="string" use="optional"/>
+ <attribute name="b" type="string" use="required"/>
+ <anyAttribute namespace="##targetNamespace" processContents="skip"/>
+ </complexType>
+
+
+ <!-- Test that in inheritance attributes are checked before wildcards. -->
+ <complexType name="pass-b-base">
+ <attribute name="a" type="string"/>
+ <anyAttribute namespace="#any" processContents="skip"/>
+ </complexType>
+
+ <complexType name="pass-b">
+ <complexContent>
+ <extension base="t:pass-b-base">
+ <attribute name="b" type="string"/>
+ <anyAttribute namespace="#any" processContents="skip"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+
+ <!-- Test that in inheritance by restriction required attribute is
+ checked for even though it is not explicitly mentioned in
+ derived. -->
+ <complexType name="pass-c-base">
+ <attribute name="a" type="string" use="required"/>
+ <attribute name="b" type="string" use="optional"/>
+ </complexType>
+
+ <complexType name="pass-c">
+ <complexContent>
+ <restriction base="t:pass-c-base">
+ <attribute name="b" type="string" use="required"/>
+ </restriction>
+ </complexContent>
+ </complexType>
+
+
+ <!-- Test detection of missing required attribute. -->
+ <complexType name="fail-base">
+ <attribute name="a" type="string" use="optional"/>
+ </complexType>
+
+ <complexType name="fail">
+ <complexContent>
+ <restriction base="t:fail-base">
+ <attribute name="a" type="string" use="required"/>
+ </restriction>
+ </complexContent>
+ </complexType>
+
+
+ <complexType name="type">
+ <sequence>
+ <element name="pass-a" type="t:pass-a"/>
+ <element name="pass-b" type="t:pass-b"/>
+ <element name="pass-c" type="t:pass-c"/>
+ <element name="fail" type="t:fail"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/parser/validation/built-in/any-type/driver.cxx b/tests/cxx/parser/validation/built-in/any-type/driver.cxx
new file mode 100644
index 0000000..3381d94
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/any-type/driver.cxx
@@ -0,0 +1,156 @@
+// file : tests/cxx/parser/validation/built-in/any-type/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the anyType and anySimpleType validation.
+//
+
+#include <string>
+#include <fstream>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace test;
+using xml_schema::ro_string;
+
+struct any_type_pimpl: xml_schema::any_type_pimpl
+{
+ virtual void
+ pre ()
+ {
+ cout << "{" << endl;
+ }
+
+ virtual void
+ _start_any_element (ro_string const&,
+ ro_string const& n,
+ ro_string const*)
+ {
+ cout << " start any element '" << n << "'" << endl;
+ }
+
+ virtual void
+ _end_any_element (ro_string const&, ro_string const& n)
+ {
+ cout << " end any element '" << n << "'" << endl;
+ }
+
+ virtual void
+ _any_attribute (ro_string const&,
+ ro_string const& n,
+ ro_string const& v)
+ {
+ cout << " any attribute " << n << " = '" << v << "'" << endl;
+ }
+
+ virtual void
+ _any_characters (ro_string const& s)
+ {
+ cout << " any text: '" << s << "'" << endl;
+ }
+
+ virtual void
+ post_any_type ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct any_simple_type_pimpl: xml_schema::any_simple_type_pimpl
+{
+ virtual void
+ pre ()
+ {
+ cout << "{" << endl;
+ }
+
+ virtual void
+ _any_characters (ro_string const& s)
+ {
+ cout << " any text: '" << s << "'" << endl;
+ }
+
+ virtual void
+ post_any_simple_type ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct any_extension_pimpl: virtual any_extension_pskel,
+ any_type_pimpl
+
+{
+ virtual void
+ x (const string& v)
+ {
+ cout << " x = " << v << endl;
+ }
+};
+
+struct any_simple_extension_pimpl: virtual any_simple_extension_pskel,
+ any_simple_type_pimpl
+{
+ virtual void
+ x (const string& v)
+ {
+ cout << " x = " << v << endl;
+ }
+};
+
+struct type_pimpl: type_pskel
+{
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ xml_schema::string_pimpl string_p;
+
+ any_type_pimpl any_type_p;
+ any_simple_type_pimpl any_simple_type_p;
+
+ any_extension_pimpl any_extension_p;
+ any_simple_extension_pimpl any_simple_extension_p;
+
+ type_pimpl type_p;
+
+ any_extension_p.parsers (string_p);
+ any_simple_extension_p.parsers (string_p);
+
+ type_p.parsers (any_type_p,
+ any_extension_p,
+ any_simple_extension_p,
+ any_simple_type_p);
+
+ xml_schema::document doc_p (type_p, "test", "root");
+
+ ifstream ifs (argv[1]);
+ type_p.pre ();
+ doc_p.parse (ifs, argv[1], "", xml_schema::flags::dont_validate);
+ type_p.post_type ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/validation/built-in/any-type/makefile b/tests/cxx/parser/validation/built-in/any-type/makefile
new file mode 100644
index 0000000..613eb35
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/any-type/makefile
@@ -0,0 +1,85 @@
+# file : tests/cxx/parser/validation/built-in/any-type/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+tests := 000
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-validation
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+test_targets := $(addprefix $(out_base)/.test-,$(tests))
+
+.PHONY: $(test)
+$(test): $(test_targets)
+
+
+$(test_targets): driver := $(driver)
+
+.PHONY: $(out_base)/.test-%
+$(out_base)/.test-%: $(driver) $(src_base)/test.xsd $(src_base)/test-%.xml $(src_base)/test-%.std
+ $(call message,test $(out_base)/$*,$(driver) $(src_base)/test-$*.xml | diff -u $(src_base)/test-$*.std -)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/validation/built-in/any-type/test-000.std b/tests/cxx/parser/validation/built-in/any-type/test-000.std
new file mode 100644
index 0000000..84d7b3a
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/any-type/test-000.std
@@ -0,0 +1,99 @@
+{
+ any text: '123abc'
+}
+
+{
+ any text: '
+ '
+ start any element 'any'
+ end any element 'any'
+ any text: '
+ '
+}
+
+{
+ any text: '
+ '
+ start any element 'any'
+ any attribute x = 'xxx'
+ any text: 'aaa'
+ start any element 'a'
+ any text: 'bbb'
+ end any element 'a'
+ any text: 'ccc'
+ end any element 'any'
+ any text: '
+ '
+}
+
+{
+ any attribute x = 'x'
+ any text: '
+ '
+ start any element 'a'
+ any text: 'a'
+ end any element 'a'
+ any text: '
+ '
+ start any element 'any'
+ any attribute x = 'xxx'
+ any text: 'aaa'
+ start any element 'a'
+ any text: 'bbb'
+ end any element 'a'
+ any text: 'ccc'
+ end any element 'any'
+ any text: '
+ '
+}
+
+{
+ any text: '
+ '
+ start any element 'any'
+ end any element 'any'
+ any text: '
+ '
+}
+
+{
+ any text: '
+ '
+ start any element 'any'
+ any attribute x = 'xxx'
+ any text: 'aaa'
+ start any element 'a'
+ any text: 'bbb'
+ end any element 'a'
+ any text: 'ccc'
+ end any element 'any'
+ any text: '
+ '
+}
+
+{
+ x = x
+ any text: '
+ '
+ start any element 'a'
+ any text: 'a'
+ end any element 'a'
+ any text: '
+ '
+ start any element 'any'
+ any attribute x = 'xxx'
+ any text: 'aaa'
+ start any element 'a'
+ any text: 'bbb'
+ end any element 'a'
+ any text: 'ccc'
+ end any element 'any'
+ any text: '
+ '
+}
+
+{
+ x = x
+ any text: 'abc123'
+}
+
diff --git a/tests/cxx/parser/validation/built-in/any-type/test-000.xml b/tests/cxx/parser/validation/built-in/any-type/test-000.xml
new file mode 100644
index 0000000..7875b7e
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/any-type/test-000.xml
@@ -0,0 +1,41 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd"
+ as="123abc">
+
+ <!-- test dispatching of anyType nested elements and attributes -->
+
+ <a>
+ <o:any/>
+ </a>
+
+ <a>
+ <o:any x="xxx">aaa<a>bbb</a>ccc</o:any>
+ </a>
+
+ <a x="x">
+ <a>a</a>
+ <o:any x="xxx">aaa<a>bbb</a>ccc</o:any>
+ </a>
+
+ <!-- anyType extension -->
+
+ <a-extension>
+ <o:any/>
+ </a-extension>
+
+ <a-extension>
+ <o:any x="xxx">aaa<a>bbb</a>ccc</o:any>
+ </a-extension>
+
+ <a-extension x="x">
+ <a>a</a>
+ <o:any x="xxx">aaa<a>bbb</a>ccc</o:any>
+ </a-extension>
+
+ <!-- anySimpleType extension -->
+
+ <as-extension x="x">abc123</as-extension>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/built-in/any-type/test.xsd b/tests/cxx/parser/validation/built-in/any-type/test.xsd
new file mode 100644
index 0000000..86a4e13
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/any-type/test.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="any-extension">
+ <complexContent mixed="true">
+ <extension base="anyType">
+ <attribute name="x" type="string"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="any-simple-extension">
+ <simpleContent>
+ <extension base="anySimpleType">
+ <attribute name="x" type="string"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="type">
+ <choice maxOccurs="unbounded">
+ <element name="a" type="anyType"/>
+ <element name="a-extension" type="t:any-extension"/>
+ <element name="as-extension" type="t:any-simple-extension"/>
+ </choice>
+ <attribute name="as" type="anySimpleType"/>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/parser/validation/built-in/binary/driver.cxx b/tests/cxx/parser/validation/built-in/binary/driver.cxx
new file mode 100644
index 0000000..a3885c8
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/binary/driver.cxx
@@ -0,0 +1,155 @@
+// file : tests/cxx/parser/validation/built-in/binary/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the built-in base64Binary and hexBinary types validation.
+//
+#include <cassert>
+
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>
+
+using namespace xsd::cxx::parser::validating;
+
+template <typename T>
+bool
+test_post_fail (T& p)
+{
+ try
+ {
+ p._post ();
+ }
+ catch (invalid_value<char> const&)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+int
+main ()
+{
+ typedef xsd::cxx::parser::buffer buffer;
+
+ // Good.
+ //
+
+ // hexBinary
+ //
+ {
+ hex_binary_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \t\n ");
+ p._characters (" ");
+ p._post ();
+ assert (*p.post_hex_binary () == buffer ());
+ }
+
+ {
+ hex_binary_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \t\n313");
+ p._characters ("23334356162636a6b ");
+ p._post ();
+ assert (*p.post_hex_binary () == buffer ("12345abcjk", 10));
+ }
+
+ // base64Binary
+ //
+ {
+ base64_binary_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \t\n ");
+ p._characters ("MTIzND ");
+ p._characters ("VhYmNqaw = = ");
+ p._post ();
+ assert (*p.post_base64_binary () == buffer ("12345abcjk", 10));
+ }
+
+ {
+ base64_binary_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("YQ==");
+ p._post ();
+ assert (*p.post_base64_binary () == buffer ("a", 1));
+ }
+
+ {
+ base64_binary_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("YWI=");
+ p._post ();
+ assert (*p.post_base64_binary () == buffer ("ab", 2));
+ }
+
+ {
+ base64_binary_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("YWJj");
+ p._post ();
+ assert (*p.post_base64_binary () == buffer ("abc", 3));
+ }
+
+ // Bad
+ //
+
+ // hexBinary
+ //
+ {
+ hex_binary_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("313");
+ assert (test_post_fail (p));
+ }
+
+ {
+ hex_binary_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("313233343X6162636a6b");
+ assert (test_post_fail (p));
+ }
+
+ // base64Binary
+ //
+ {
+ base64_binary_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ // p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ base64_binary_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("YQ");
+ assert (test_post_fail (p));
+ }
+
+ {
+ base64_binary_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("==");
+ assert (test_post_fail (p));
+ }
+
+ {
+ base64_binary_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("MTIzNDVhYmNqaw=A");
+ assert (test_post_fail (p));
+ }
+}
diff --git a/tests/cxx/parser/validation/built-in/binary/makefile b/tests/cxx/parser/validation/built-in/binary/makefile
new file mode 100644
index 0000000..1a62471
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/binary/makefile
@@ -0,0 +1,60 @@
+# file : tests/cxx/parser/validation/built-in/binary/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
diff --git a/tests/cxx/parser/validation/built-in/boolean/driver.cxx b/tests/cxx/parser/validation/built-in/boolean/driver.cxx
new file mode 100644
index 0000000..72a1356
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/boolean/driver.cxx
@@ -0,0 +1,147 @@
+// file : tests/cxx/parser/validation/built-in/boolean/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the built-in boolean type validation.
+//
+#include <cassert>
+
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>
+
+using namespace xsd::cxx::parser::validating;
+
+bool
+test_post_fail (boolean_pimpl<char>& p)
+{
+ try
+ {
+ p._post ();
+ }
+ catch (invalid_value<char> const&)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+int
+main ()
+{
+ // Good.
+ //
+ {
+ boolean_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("true");
+ p._post ();
+ assert (p.post_boolean ());
+ }
+
+ {
+ boolean_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("1");
+ p._post ();
+ assert (p.post_boolean ());
+ }
+
+ {
+ boolean_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("false");
+ p._post ();
+ assert (!p.post_boolean ());
+ }
+
+ {
+ boolean_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0");
+ p._post ();
+ assert (!p.post_boolean ());
+ }
+
+
+ {
+ boolean_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" true ");
+ p._post ();
+ assert (p.post_boolean ());
+ }
+
+ {
+ boolean_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" ");
+ p._characters (" \n ");
+ p._characters (" fa");
+ p._characters ("l");
+ p._characters ("se ");
+ p._characters (" \n ");
+ p._characters (" ");
+ p._post ();
+ assert (!p.post_boolean ());
+ }
+
+ // Bad
+ //
+ {
+ boolean_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ //p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ boolean_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ boolean_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" ");
+ assert (test_post_fail (p));
+ }
+
+ {
+ boolean_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" ");
+ assert (test_post_fail (p));
+ }
+
+ {
+ boolean_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("fal");
+ p._characters ("s ");
+ p._characters ("e");
+ assert (test_post_fail (p));
+ }
+
+ {
+ boolean_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("01");
+ assert (test_post_fail (p));
+ }
+}
diff --git a/tests/cxx/parser/validation/built-in/boolean/makefile b/tests/cxx/parser/validation/built-in/boolean/makefile
new file mode 100644
index 0000000..bc753b2
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/boolean/makefile
@@ -0,0 +1,60 @@
+# file : tests/cxx/parser/validation/built-in/boolean/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
diff --git a/tests/cxx/parser/validation/built-in/byte/driver.cxx b/tests/cxx/parser/validation/built-in/byte/driver.cxx
new file mode 100644
index 0000000..a7fa905
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/byte/driver.cxx
@@ -0,0 +1,258 @@
+// file : tests/cxx/parser/validation/built-in/byte/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the built-in byte and unsigned byte types validation.
+//
+#include <cassert>
+
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>
+
+using namespace xsd::cxx::parser::validating;
+
+template <typename T>
+bool
+test_post_fail (T& p)
+{
+ try
+ {
+ p._post ();
+ }
+ catch (invalid_value<char> const&)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+int
+main ()
+{
+ // Good.
+ //
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("123");
+ p._post ();
+ assert (p.post_byte () == 123);
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("\t +123 \n ");
+ p._post ();
+ assert (p.post_byte () == 123);
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-123");
+ p._post ();
+ assert (p.post_byte () == -123);
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("+123");
+ p._post ();
+ assert (p.post_byte () == 123);
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0000000000000000123");
+ p._post ();
+ assert (p.post_byte () == 123);
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("+0000000000000000123");
+ p._post ();
+ assert (p.post_byte () == 123);
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-0000000000000000123");
+ p._post ();
+ assert (p.post_byte () == -123);
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("\t \n");
+ p._characters (" -");
+ p._characters ("00000");
+ p._characters ("001");
+ p._characters ("23 \n\t");
+ p._post ();
+ assert (p.post_byte () == -123);
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-128");
+ p._post ();
+ assert (p.post_byte () == -128);
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("127");
+ p._post ();
+ assert (p.post_byte () == 127);
+ }
+
+ {
+ unsigned_byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("+123");
+ p._post ();
+ assert (p.post_unsigned_byte () == 123);
+ }
+
+ {
+ unsigned_byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0");
+ p._post ();
+ assert (p.post_unsigned_byte () == 0);
+ }
+
+ {
+ unsigned_byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("255");
+ p._post ();
+ assert (p.post_unsigned_byte () == 255);
+ }
+
+ // Bad
+ //
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ // p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \n \t ");
+ assert (test_post_fail (p));
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("+");
+ assert (test_post_fail (p));
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-");
+ assert (test_post_fail (p));
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("++01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-01");
+ p._characters (" ");
+ p._characters ("23 ");
+ assert (test_post_fail (p));
+ }
+
+ {
+ unsigned_byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-123");
+ assert (test_post_fail (p));
+ }
+
+ // Ranges
+ //
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-129");
+ assert (test_post_fail (p));
+ }
+
+ {
+ byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("128");
+ assert (test_post_fail (p));
+ }
+
+ {
+ unsigned_byte_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("256");
+ assert (test_post_fail (p));
+ }
+}
diff --git a/tests/cxx/parser/validation/built-in/byte/makefile b/tests/cxx/parser/validation/built-in/byte/makefile
new file mode 100644
index 0000000..7e3655b
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/byte/makefile
@@ -0,0 +1,60 @@
+# file : tests/cxx/parser/validation/built-in/byte/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
diff --git a/tests/cxx/parser/validation/built-in/date-time/driver.cxx b/tests/cxx/parser/validation/built-in/date-time/driver.cxx
new file mode 100644
index 0000000..16d876d
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/date-time/driver.cxx
@@ -0,0 +1,1535 @@
+// file : tests/cxx/parser/validation/built-in/date-time/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the built-in date and time types validation.
+//
+#include <cassert>
+
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>
+
+using namespace xsd::cxx::parser::validating;
+
+template <typename T>
+bool
+test_post_fail (T& p)
+{
+ try
+ {
+ p._post ();
+ }
+ catch (invalid_value<char> const&)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+int
+main ()
+{
+ typedef xsd::cxx::parser::gday gday;
+ typedef xsd::cxx::parser::gmonth gmonth;
+ typedef xsd::cxx::parser::gyear gyear;
+ typedef xsd::cxx::parser::gmonth_day gmonth_day;
+ typedef xsd::cxx::parser::gyear_month gyear_month;
+ typedef xsd::cxx::parser::date date;
+ typedef xsd::cxx::parser::time time;
+ typedef xsd::cxx::parser::date_time date_time;
+ typedef xsd::cxx::parser::duration duration;
+
+ // Good.
+ //
+
+ // gday & time zone parsing
+ //
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \t\n ");
+ p._characters ("---1");
+ p._characters ("2+12:00");
+ p._post ();
+ assert (p.post_gday () == gday (12, 12, 00));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---01");
+ p._post ();
+ assert (p.post_gday () == gday (1));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---31");
+ p._post ();
+ assert (p.post_gday () == gday (31));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---15Z");
+ p._post ();
+ assert (p.post_gday () == gday (15, 0, 0));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---15-14:00");
+ p._post ();
+ assert (p.post_gday () == gday (15, -14, 0));
+ }
+
+ // gmonth
+ //
+ {
+ gmonth_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \t\n ");
+ p._characters ("--1");
+ p._characters ("0+12:00");
+ p._post ();
+ assert (p.post_gmonth () == gmonth (10, 12, 0));
+ }
+
+ {
+ gmonth_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--01");
+ p._post ();
+ assert (p.post_gmonth () == gmonth (1));
+ }
+
+ {
+ gmonth_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--12Z");
+ p._post ();
+ assert (p.post_gmonth () == gmonth (12, 0, 0));
+ }
+
+ // gyear
+ //
+ {
+ gyear_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \t\n ");
+ p._characters ("20");
+ p._characters ("07+12:00");
+ p._post ();
+ assert (p.post_gyear () == gyear (2007, 12, 00));
+ }
+
+ {
+ gyear_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0001");
+ p._post ();
+ assert (p.post_gyear () == gyear (1));
+ }
+
+ {
+ gyear_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-20000Z");
+ p._post ();
+ assert (p.post_gyear () == gyear (-20000, 0, 0));
+ }
+
+ // gmonth_day
+ //
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \t\n ");
+ p._characters ("--1");
+ p._characters ("0-28+12:00 ");
+ p._post ();
+ assert (p.post_gmonth_day () == gmonth_day (10, 28, 12, 00));
+ }
+
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--12-31");
+ p._post ();
+ assert (p.post_gmonth_day () == gmonth_day (12, 31));
+ }
+
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--01-01Z");
+ p._post ();
+ assert (p.post_gmonth_day () == gmonth_day (1, 1, 0, 0));
+ }
+
+ // gyear_month
+ //
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \t\n ");
+ p._characters ("200");
+ p._characters ("7-12+12:00 ");
+ p._post ();
+ assert (p.post_gyear_month () == gyear_month (2007, 12, 12, 00));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-2007-10");
+ p._post ();
+ assert (p.post_gyear_month () == gyear_month (-2007, 10));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("20007-10Z");
+ p._post ();
+ assert (p.post_gyear_month () == gyear_month (20007, 10, 0, 0));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-20007-01");
+ p._post ();
+ assert (p.post_gyear_month () == gyear_month (-20007, 1));
+ }
+
+ // date
+ //
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \t\n ");
+ p._characters ("200");
+ p._characters ("7-12-26+12:00 ");
+ p._post ();
+ assert (p.post_date () == date (2007, 12, 26, 12, 0));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-2007-10-15");
+ p._post ();
+ assert (p.post_date () == date (-2007, 10, 15));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("20007-12-31Z");
+ p._post ();
+ assert (p.post_date () == date (20007, 12, 31, 0, 0));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-20007-01-01");
+ p._post ();
+ assert (p.post_date () == date (-20007, 1, 1));
+ }
+
+ // time
+ //
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \t\n ");
+ p._characters ("12:");
+ p._characters ("46:23.456+12:00 ");
+ p._post ();
+ assert (p.post_time () == time (12, 46, 23.456, 12, 0));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("12:13:14");
+ p._post ();
+ assert (p.post_time () == time (12, 13, 14.0));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("12:13:14Z");
+ p._post ();
+ assert (p.post_time () == time (12, 13, 14.0, 0, 0));
+ }
+
+ // date_time
+ //
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \t\n ");
+ p._characters ("200");
+ p._characters ("7-12-26T12:13:14.123+12:00 ");
+ p._post ();
+ assert (p.post_date_time () ==
+ date_time (2007, 12, 26, 12, 13, 14.123, 12, 0));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-2007-10-15T12:13:14");
+ p._post ();
+ assert (p.post_date_time () == date_time (-2007, 10, 15, 12, 13, 14.0));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("20007-12-31T12:13:14Z");
+ p._post ();
+ assert (p.post_date_time () ==
+ date_time (20007, 12, 31, 12, 13, 14.0, 0, 0));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-20007-01-01T12:13:14");
+ p._post ();
+ assert (p.post_date_time () == date_time (-20007, 1, 1, 12, 13, 14.0));
+ }
+
+ // duration
+ //
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \t\n ");
+ p._characters ("-P200");
+ p._characters ("7Y13M32DT25H61M61.123S ");
+ p._post ();
+ assert (p.post_duration () ==
+ duration (true, 2007, 13, 32, 25, 61, 61.123));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("P1Y");
+ p._post ();
+ assert (p.post_duration () == duration (false, 1, 0, 0, 0, 0, 0.0));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("P1M");
+ p._post ();
+ assert (p.post_duration () == duration (false, 0, 1, 0, 0, 0, 0.0));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("P1D");
+ p._post ();
+ assert (p.post_duration () == duration (false, 0, 0, 1, 0, 0, 0.0));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("PT1H");
+ p._post ();
+ assert (p.post_duration () == duration (false, 0, 0, 0, 1, 0, 0.0));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("PT1M");
+ p._post ();
+ assert (p.post_duration () == duration (false, 0, 0, 0, 0, 1, 0.0));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("PT1.1S");
+ p._post ();
+ assert (p.post_duration () == duration (false, 0, 0, 0, 0, 0, 1.1));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("P1YT1S");
+ p._post ();
+ assert (p.post_duration () == duration (false, 1, 0, 0, 0, 0, 1.0));
+ }
+
+ // Bad
+ //
+
+ // gday & time zone parsing
+ //
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ // p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--12");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---1");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---00");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---32");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---2X");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---12asd");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---12X");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---1212:00");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---12+2:00");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---12+1200");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---12+15:00");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---12+12:60");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gday_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("---12+14:01");
+ assert (test_post_fail (p));
+ }
+
+ // gmonth
+ //
+ {
+ gmonth_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ // p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-12");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--00");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--13");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--1X");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--11+12:3o");
+ assert (test_post_fail (p));
+ }
+
+ // gyear
+ //
+ {
+ gyear_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ // p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("207");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-207");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-0000");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("20X7");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007+12:3o");
+ assert (test_post_fail (p));
+ }
+
+ // gmonth_day
+ //
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ // p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-12-12");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--1212");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--12?12");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--00-12");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--12-00");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--13-23");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--12-32");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--1X-12");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--12-2X");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gmonth_day_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("--11-11+12:3o");
+ assert (test_post_fail (p));
+ }
+
+ // gyear_month
+ //
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ // p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("207-01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-207-01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0000-01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("20X7-01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007?12");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-0");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-00");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-13");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-1X");
+ assert (test_post_fail (p));
+ }
+
+ {
+ gyear_month_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01+12:3o");
+ assert (test_post_fail (p));
+ }
+
+ // date
+ //
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ // p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("207-01-01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-207-01-01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0000-01-01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("20X7-01-01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007?01-01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-0-01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-00-01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-13-01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-1X-01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10?12");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10-");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10-0");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10-00");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10-32");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10-2X");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01+12:3o");
+ assert (test_post_fail (p));
+ }
+
+ // time
+ //
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ // p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("1:01:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2X:01:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23?01:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23:0:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23:60:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23:4X:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23:10");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23:10?12");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23:10:");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23:10:0");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23:10:01.");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23:10:60");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23:10:2X");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("24:01:00");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("24:00:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23:01:01+12:3o");
+ assert (test_post_fail (p));
+ }
+
+ // date_time
+ //
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ // p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("207-01-01T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-207-01-01T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0000-01-01T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("20X7-01-01T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007?01-01T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-0-01T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-00-01T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-13-01T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-1X-01T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10?12T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10-T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10-0T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10-00T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10-32T12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-10-2XT12:13:14");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T1:01:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T2X:01:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T23");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T23?01:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T23:0:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T23:60:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T23:4X:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T23:10");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T23:10?12");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T23:10:");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T23:10:0");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T23:10:01.");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T23:10:60");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T23:10:2X");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T24:01:00");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T24:00:01");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("23:01:01+12:3o");
+ assert (test_post_fail (p));
+ }
+
+ {
+ date_time_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007-01-01T12:13:14+12:3o");
+ assert (test_post_fail (p));
+ }
+
+ // duration
+ //
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ // p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2007Y");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-2007Y");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("P-2007Y");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("P-1M");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("P-1D");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("PT-1H");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("PT-1M");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("PT-1.1S");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("P1H1M1S");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("P1M1Y");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("PT1S1H");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("PT1H1Y");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("P1Ygarbage");
+ assert (test_post_fail (p));
+ }
+
+ {
+ duration_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("P1YT");
+ assert (test_post_fail (p));
+ }
+}
diff --git a/tests/cxx/parser/validation/built-in/date-time/makefile b/tests/cxx/parser/validation/built-in/date-time/makefile
new file mode 100644
index 0000000..1d1dd20
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/date-time/makefile
@@ -0,0 +1,60 @@
+# file : tests/cxx/parser/validation/built-in/date-time/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
diff --git a/tests/cxx/parser/validation/built-in/float/driver.cxx b/tests/cxx/parser/validation/built-in/float/driver.cxx
new file mode 100644
index 0000000..1b8454c
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/float/driver.cxx
@@ -0,0 +1,287 @@
+// file : tests/cxx/parser/validation/built-in/float/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the built-in float, double, and decimal types validation.
+//
+#include <math.h>
+#include <cassert>
+
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>
+
+using namespace xsd::cxx::parser::validating;
+
+template <typename T>
+bool
+test_post_fail (T& p)
+{
+ try
+ {
+ p._post ();
+ }
+ catch (invalid_value<char> const&)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+int
+main ()
+{
+ // Good.
+ //
+
+ // float
+ //
+ {
+ float_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" 0000123.456 ");
+ p._post ();
+ assert (p.post_float () == 123.456F);
+ }
+
+ {
+ float_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-12.345E2");
+ p._post ();
+ assert (p.post_float () == -12.345E2F);
+ }
+
+ {
+ float_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0");
+ p._post ();
+ assert (p.post_float () == 0.0F);
+ }
+
+ {
+ float_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-0");
+ p._post ();
+ assert (p.post_float () == -0.0F);
+ }
+
+ {
+ float_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("INF");
+ p._post ();
+ assert (isinf (p.post_float ()));
+ }
+
+ {
+ float_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-INF");
+ p._post ();
+ assert (isinf (p.post_float ()));
+ }
+
+ {
+ float_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("NaN");
+ p._post ();
+ assert (isnan (p.post_float ()));
+ }
+
+ // double
+ //
+ {
+ double_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" 0000123.456789 ");
+ p._post ();
+ assert (p.post_double () == 123.456789);
+ }
+
+ {
+ double_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-12.3456789E2");
+ p._post ();
+ assert (p.post_double () == -12.3456789E2);
+ }
+
+ {
+ double_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0");
+ p._post ();
+ assert (p.post_double () == 0.0);
+ }
+
+ {
+ double_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-0");
+ p._post ();
+ assert (p.post_double () == -0.0);
+ }
+
+ {
+ double_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("INF");
+ p._post ();
+ assert (isinf (p.post_double ()));
+ }
+
+ {
+ double_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-INF");
+ p._post ();
+ assert (isinf (p.post_double ()));
+ }
+
+ {
+ double_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("NaN");
+ p._post ();
+ assert (isnan (p.post_double ()));
+ }
+
+ // decimal
+ //
+ {
+ decimal_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" 0000123.456789 ");
+ p._post ();
+ assert (p.post_decimal () == 123.456789);
+ }
+
+ {
+ decimal_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-123.45678912345");
+ p._post ();
+ assert (p.post_decimal () == -123.45678912345);
+ }
+
+ {
+ decimal_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0");
+ p._post ();
+ assert (p.post_decimal () == 0.0);
+ }
+
+ {
+ decimal_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-0");
+ p._post ();
+ assert (p.post_decimal () == -0.0);
+ }
+
+
+ // Bad
+ //
+
+ // float
+ //
+ {
+ float_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("+INF");
+ assert (test_post_fail (p));
+ }
+
+ {
+ float_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("1.45 E2");
+ assert (test_post_fail (p));
+ }
+
+ // double
+ //
+ {
+ double_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("+INF");
+ assert (test_post_fail (p));
+ }
+
+ {
+ double_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("1.45 E2");
+ assert (test_post_fail (p));
+ }
+
+ // decimal
+ //
+ {
+ decimal_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("INF");
+ assert (test_post_fail (p));
+ }
+
+ {
+ decimal_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("+INF");
+ assert (test_post_fail (p));
+ }
+
+ {
+ decimal_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-INF");
+ assert (test_post_fail (p));
+ }
+
+ {
+ decimal_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("NaN");
+ assert (test_post_fail (p));
+ }
+
+ {
+ decimal_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("1.45 2");
+ assert (test_post_fail (p));
+ }
+}
diff --git a/tests/cxx/parser/validation/built-in/float/makefile b/tests/cxx/parser/validation/built-in/float/makefile
new file mode 100644
index 0000000..b6c478d
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/float/makefile
@@ -0,0 +1,60 @@
+# file : tests/cxx/parser/validation/built-in/float/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
diff --git a/tests/cxx/parser/validation/built-in/int/driver.cxx b/tests/cxx/parser/validation/built-in/int/driver.cxx
new file mode 100644
index 0000000..682eea9
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/int/driver.cxx
@@ -0,0 +1,118 @@
+// file : tests/cxx/parser/validation/built-in/int/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the built-in int and unsigned int types validation.
+//
+#include <cassert>
+
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>
+
+using namespace xsd::cxx::parser::validating;
+
+template <typename T>
+bool
+test_post_fail (T& p)
+{
+ try
+ {
+ p._post ();
+ }
+ catch (invalid_value<char> const&)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+int
+main ()
+{
+ // Good.
+ //
+ {
+ int_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-2147483648");
+ p._post ();
+ assert (p.post_int () == -2147483648);
+ }
+
+ {
+ int_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0");
+ p._post ();
+ assert (p.post_int () == 0);
+ }
+
+ {
+ int_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2147483647");
+ p._post ();
+ assert (p.post_int () == 2147483647);
+ }
+
+ {
+ unsigned_int_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0");
+ p._post ();
+ assert (p.post_unsigned_int () == 0);
+ }
+
+ {
+ unsigned_int_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("4294967295");
+ p._post ();
+ assert (p.post_unsigned_int () == 4294967295);
+ }
+
+ // Bad
+ //
+
+ {
+ unsigned_int_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-123");
+ assert (test_post_fail (p));
+ }
+
+
+ // Ranges
+ //
+ {
+ int_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-2147483649");
+ assert (test_post_fail (p));
+ }
+
+ {
+ int_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("2147483648");
+ assert (test_post_fail (p));
+ }
+
+ {
+ unsigned_int_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("4294967296");
+ assert (test_post_fail (p));
+ }
+}
diff --git a/tests/cxx/parser/validation/built-in/int/makefile b/tests/cxx/parser/validation/built-in/int/makefile
new file mode 100644
index 0000000..e70782a
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/int/makefile
@@ -0,0 +1,60 @@
+# file : tests/cxx/parser/validation/built-in/int/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
diff --git a/tests/cxx/parser/validation/built-in/integer/driver.cxx b/tests/cxx/parser/validation/built-in/integer/driver.cxx
new file mode 100644
index 0000000..6dd04d2
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/integer/driver.cxx
@@ -0,0 +1,305 @@
+// file : tests/cxx/parser/validation/built-in/int/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the built-in integer & friends types validation.
+//
+#include <limits.h>
+
+#include <string>
+#include <sstream>
+#include <cassert>
+
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>
+
+using namespace std;
+using namespace xsd::cxx::parser::validating;
+
+template <typename T>
+bool
+test_post_fail (T& p)
+{
+ try
+ {
+ p._post ();
+ }
+ catch (invalid_value<char> const&)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+int
+main ()
+{
+ // Good.
+ //
+
+ std::string min;
+ std::string max;
+ std::string umax;
+
+ {
+ ostringstream ostr;
+ ostr << LLONG_MIN;
+ min = ostr.str ();
+ }
+
+ {
+ ostringstream ostr;
+ ostr << LLONG_MAX;
+ max = ostr.str ();
+ }
+
+ {
+ ostringstream ostr;
+ ostr << ULLONG_MAX;
+ umax = ostr.str ();
+ }
+
+ // integer
+ //
+ {
+ integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (min.c_str ());
+ p._post ();
+ assert (p.post_integer () == LLONG_MIN);
+ }
+
+ {
+ integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0");
+ p._post ();
+ assert (p.post_integer () == 0);
+ }
+
+ {
+ integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (max.c_str ());
+ p._post ();
+ assert (p.post_integer () == LLONG_MAX);
+ }
+
+ // negative_integer
+ //
+ {
+ negative_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (min.c_str ());
+ p._post ();
+ assert (p.post_negative_integer () == LLONG_MIN);
+ }
+
+ {
+ negative_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-1");
+ p._post ();
+ assert (p.post_negative_integer () == -1);
+ }
+
+ // non_positive_integer
+ //
+ {
+ non_positive_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (min.c_str ());
+ p._post ();
+ assert (p.post_non_positive_integer () == LLONG_MIN);
+ }
+
+ {
+ non_positive_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("+0");
+ p._post ();
+ assert (p.post_non_positive_integer () == 0);
+ }
+
+ // positive_integer
+ //
+ {
+ positive_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("1");
+ p._post ();
+ assert (p.post_positive_integer () == 1);
+ }
+
+ {
+ positive_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (umax.c_str ());
+ p._post ();
+ assert (p.post_positive_integer () == ULLONG_MAX);
+ }
+
+ // non_negative_integer
+ //
+ /*
+ {
+ non_negative_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-0");
+ p._post ();
+ assert (p.post_non_negative_integer () == 0);
+ }
+ */
+
+ {
+ non_negative_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0");
+ p._post ();
+ assert (p.post_non_negative_integer () == 0);
+ }
+
+ {
+ non_negative_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (umax.c_str ());
+ p._post ();
+ assert (p.post_non_negative_integer () == ULLONG_MAX);
+ }
+
+
+ // Bad
+ //
+
+ std::string past_min (min);
+ std::string past_max (max);
+ std::string past_umax (umax);
+
+ assert (*past_min.rbegin () != '9');
+ assert (*past_max.rbegin () != '9');
+ assert (*past_umax.rbegin () != '9');
+
+ (*past_min.rbegin ())++;
+ (*past_max.rbegin ())++;
+ (*past_umax.rbegin ())++;
+
+ // integer
+ //
+ {
+ integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (past_min.c_str ());
+ assert (test_post_fail (p));
+ }
+
+ {
+ integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (past_max.c_str ());
+ assert (test_post_fail (p));
+ }
+
+ // negative_integer
+ //
+ {
+ negative_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (past_min.c_str ());
+ assert (test_post_fail (p));
+ }
+
+ {
+ negative_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-0");
+ assert (test_post_fail (p));
+ }
+
+ {
+ negative_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("1");
+ assert (test_post_fail (p));
+ }
+
+ // non_positive_integer
+ //
+ {
+ non_positive_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (past_min.c_str ());
+ assert (test_post_fail (p));
+ }
+
+ {
+ non_positive_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("1");
+ assert (test_post_fail (p));
+ }
+
+ // positive_integer
+ //
+ {
+ positive_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-1");
+ assert (test_post_fail (p));
+ }
+
+ {
+ positive_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("+0");
+ assert (test_post_fail (p));
+ }
+
+ {
+ positive_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (past_umax.c_str ());
+ assert (test_post_fail (p));
+ }
+
+ // non_negative_integer
+ //
+ {
+ non_negative_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-1");
+ assert (test_post_fail (p));
+ }
+
+ {
+ non_negative_integer_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (past_umax.c_str ());
+ assert (test_post_fail (p));
+ }
+}
diff --git a/tests/cxx/parser/validation/built-in/integer/makefile b/tests/cxx/parser/validation/built-in/integer/makefile
new file mode 100644
index 0000000..8b0d68c
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/integer/makefile
@@ -0,0 +1,60 @@
+# file : tests/cxx/parser/validation/built-in/integer/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
diff --git a/tests/cxx/parser/validation/built-in/long/driver.cxx b/tests/cxx/parser/validation/built-in/long/driver.cxx
new file mode 100644
index 0000000..462c7e7
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/long/driver.cxx
@@ -0,0 +1,118 @@
+// file : tests/cxx/parser/validation/built-in/long/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the built-in long and unsigned long types validation.
+//
+#include <cassert>
+
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>
+
+using namespace xsd::cxx::parser::validating;
+
+template <typename T>
+bool
+test_post_fail (T& p)
+{
+ try
+ {
+ p._post ();
+ }
+ catch (invalid_value<char> const&)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+int
+main ()
+{
+ // Good.
+ //
+ {
+ long_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-9223372036854775808");
+ p._post ();
+ assert (p.post_long () == (-9223372036854775807LL - 1));
+ }
+
+ {
+ long_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0");
+ p._post ();
+ assert (p.post_long () == 0);
+ }
+
+ {
+ long_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("9223372036854775807");
+ p._post ();
+ assert (p.post_long () == 9223372036854775807LL);
+ }
+
+ {
+ unsigned_long_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0");
+ p._post ();
+ assert (p.post_unsigned_long () == 0);
+ }
+
+ {
+ unsigned_long_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("18446744073709551615");
+ p._post ();
+ assert (p.post_unsigned_long () == 18446744073709551615ULL);
+ }
+
+ // Bad
+ //
+
+ {
+ unsigned_long_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-123");
+ assert (test_post_fail (p));
+ }
+
+
+ // Ranges
+ //
+ {
+ long_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-9223372036854775809");
+ assert (test_post_fail (p));
+ }
+
+ {
+ long_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("9223372036854775808");
+ assert (test_post_fail (p));
+ }
+
+ {
+ unsigned_long_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("18446744073709551616");
+ assert (test_post_fail (p));
+ }
+}
diff --git a/tests/cxx/parser/validation/built-in/long/makefile b/tests/cxx/parser/validation/built-in/long/makefile
new file mode 100644
index 0000000..201a984
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/long/makefile
@@ -0,0 +1,60 @@
+# file : tests/cxx/parser/validation/built-in/long/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
diff --git a/tests/cxx/parser/validation/built-in/makefile b/tests/cxx/parser/validation/built-in/makefile
new file mode 100644
index 0000000..e0728b0
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/makefile
@@ -0,0 +1,21 @@
+# file : tests/cxx/parser/validation/built-in/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+tests := any-type binary boolean byte date-time float int integer long \
+qname short string uri
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/parser/validation/built-in/qname/driver.cxx b/tests/cxx/parser/validation/built-in/qname/driver.cxx
new file mode 100644
index 0000000..3a2f88d
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/qname/driver.cxx
@@ -0,0 +1,107 @@
+// file : tests/cxx/parser/validation/built-in/qname/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the built-in QName type validation.
+//
+#include <cassert>
+
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>
+
+using namespace xsd::cxx::parser::validating;
+
+bool
+test_post_fail (qname_pimpl<char>& p)
+{
+ try
+ {
+ p._post ();
+ }
+ catch (invalid_value<char> const&)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+int
+main ()
+{
+ typedef xsd::cxx::parser::qname<char> qname;
+
+ // Good.
+ //
+ {
+ qname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" xsi");
+ p._characters (":");
+ p._characters ("schemaLocation");
+ p._post ();
+ assert (p.post_qname () == qname ("xsi", "schemaLocation"));
+ }
+
+ {
+ qname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("schemaLocation");
+ p._post ();
+ assert (p.post_qname () == qname ("schemaLocation"));
+ }
+
+
+ // Bad
+ //
+ {
+ qname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ //p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ qname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (":");
+ assert (test_post_fail (p));
+ }
+
+ {
+ qname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("xsi:");
+ assert (test_post_fail (p));
+ }
+
+ {
+ qname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (":schemaLocation");
+ assert (test_post_fail (p));
+ }
+
+ {
+ qname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("x?i:schemaLocation");
+ assert (test_post_fail (p));
+ }
+
+ {
+ qname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("xsi:schema Location");
+ assert (test_post_fail (p));
+ }
+}
diff --git a/tests/cxx/parser/validation/built-in/qname/makefile b/tests/cxx/parser/validation/built-in/qname/makefile
new file mode 100644
index 0000000..496af30
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/qname/makefile
@@ -0,0 +1,60 @@
+# file : tests/cxx/parser/validation/built-in/qname/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
diff --git a/tests/cxx/parser/validation/built-in/short/driver.cxx b/tests/cxx/parser/validation/built-in/short/driver.cxx
new file mode 100644
index 0000000..51eaee3
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/short/driver.cxx
@@ -0,0 +1,118 @@
+// file : tests/cxx/parser/validation/built-in/short/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the built-in short and unsigned short types validation.
+//
+#include <cassert>
+
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>
+
+using namespace xsd::cxx::parser::validating;
+
+template <typename T>
+bool
+test_post_fail (T& p)
+{
+ try
+ {
+ p._post ();
+ }
+ catch (invalid_value<char> const&)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+int
+main ()
+{
+ // Good.
+ //
+ {
+ short_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-32768");
+ p._post ();
+ assert (p.post_short () == -32768);
+ }
+
+ {
+ short_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0");
+ p._post ();
+ assert (p.post_short () == 0);
+ }
+
+ {
+ short_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("32767");
+ p._post ();
+ assert (p.post_short () == 32767);
+ }
+
+ {
+ unsigned_short_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("0");
+ p._post ();
+ assert (p.post_unsigned_short () == 0);
+ }
+
+ {
+ unsigned_short_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("65535");
+ p._post ();
+ assert (p.post_unsigned_short () == 65535);
+ }
+
+ // Bad
+ //
+
+ {
+ unsigned_short_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-1234");
+ assert (test_post_fail (p));
+ }
+
+
+ // Ranges
+ //
+ {
+ short_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-32769");
+ assert (test_post_fail (p));
+ }
+
+ {
+ short_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("32768");
+ assert (test_post_fail (p));
+ }
+
+ {
+ unsigned_short_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("65536");
+ assert (test_post_fail (p));
+ }
+}
diff --git a/tests/cxx/parser/validation/built-in/short/makefile b/tests/cxx/parser/validation/built-in/short/makefile
new file mode 100644
index 0000000..c3916dc
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/short/makefile
@@ -0,0 +1,60 @@
+# file : tests/cxx/parser/validation/built-in/short/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
diff --git a/tests/cxx/parser/validation/built-in/string/driver.cxx b/tests/cxx/parser/validation/built-in/string/driver.cxx
new file mode 100644
index 0000000..a9b552c
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/string/driver.cxx
@@ -0,0 +1,514 @@
+// file : tests/cxx/parser/validation/built-in/string/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the built-in string & friends types validation.
+//
+#include <string>
+#include <cassert>
+
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>
+
+using namespace xsd::cxx::parser::validating;
+
+template <typename T>
+bool
+test_post_fail (T& p)
+{
+ try
+ {
+ p._post_impl (); // List implementation needs this to be post_impl.
+ }
+ catch (invalid_value<char> const&)
+ {
+ return true;
+ }
+
+ return false;
+}
+
+int
+main ()
+{
+ typedef xsd::cxx::parser::string_sequence<char> strings;
+
+ // Good.
+ //
+
+ // string
+ //
+ {
+ string_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \n\t");
+ p._characters (" aaa ");
+ p._characters ("bbb");
+ p._characters (" ");
+ p._post ();
+ assert (p.post_string () == " \n\t aaa bbb ");
+ }
+
+ // normalized_string
+ //
+ {
+ normalized_string_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \n\t");
+ p._characters (" aaa \n\t ");
+ p._characters (" bbb");
+ p._characters (" ");
+ p._post ();
+ assert (p.post_normalized_string () == " aaa bbb ");
+ }
+
+ // token
+ //
+ {
+ token_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \n\t");
+ p._characters (" aaa \n\t ");
+ p._characters (" bbb \n\t");
+ p._characters (" ");
+ p._post ();
+ assert (p.post_token () == "aaa bbb");
+ }
+
+ // name
+ //
+ {
+ name_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \n\t");
+ p._characters (" a:b-c_d123 ");
+ p._characters (" ");
+ p._post ();
+ assert (p.post_name () == "a:b-c_d123");
+ }
+
+ {
+ name_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \n\t");
+ p._characters (" _12 ");
+ p._characters (" ");
+ p._post ();
+ assert (p.post_name () == "_12");
+ }
+
+ {
+ name_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \n\t");
+ p._characters (" :12 ");
+ p._characters (" ");
+ p._post ();
+ assert (p.post_name () == ":12");
+ }
+
+ // nmtoken
+ //
+ {
+ nmtoken_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \n\t");
+ p._characters (" 123a:b-c_d123 ");
+ p._characters (" \n\t");
+ p._characters (" ");
+ p._post ();
+ assert (p.post_nmtoken () == "123a:b-c_d123");
+ }
+
+ // nmtokens
+ //
+ {
+ strings s;
+ s.push_back ("123");
+ s.push_back ("abc");
+
+ nmtokens_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \n\t");
+ p._characters (" 123 ");
+ p._characters (" \n\t abc ");
+ p._characters (" ");
+ p._post ();
+ assert (p.post_nmtokens () == s);
+ }
+
+ // ncname
+ //
+ {
+ ncname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \n\t");
+ p._characters (" a.b-c_d123 ");
+ p._characters (" ");
+ p._post ();
+ assert (p.post_ncname () == "a.b-c_d123");
+ }
+
+ // id
+ //
+ {
+ id_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \n\t");
+ p._characters (" a.b-c_d123 ");
+ p._characters (" ");
+ p._post ();
+ assert (p.post_id () == "a.b-c_d123");
+ }
+
+ // idref
+ //
+ {
+ idref_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \n\t");
+ p._characters (" a.b-c_d123 ");
+ p._characters (" ");
+ p._post ();
+ assert (p.post_idref () == "a.b-c_d123");
+ }
+
+ // idrefs
+ //
+ {
+ strings s;
+ s.push_back ("a123");
+ s.push_back ("abc");
+
+ idrefs_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" \n\t");
+ p._characters (" a123 ");
+ p._characters (" \n\t abc ");
+ p._characters (" ");
+ p._post ();
+ assert (p.post_idrefs () == s);
+ }
+
+ // language
+ //
+ {
+ language_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" x ");
+ p._post ();
+ assert (p.post_language () == "x");
+ }
+
+ {
+ language_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" en ");
+ p._post ();
+ assert (p.post_language () == "en");
+ }
+
+ {
+ language_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" en");
+ p._characters ("-us ");
+ p._post ();
+ assert (p.post_language () == "en-us");
+ }
+
+ {
+ language_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("one-two-three-four44-seven77-eight888");
+ p._post ();
+ assert (p.post_language () == "one-two-three-four44-seven77-eight888");
+ }
+
+
+ // Bad
+ //
+
+ // name
+ //
+ {
+ name_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ name_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (".a");
+ assert (test_post_fail (p));
+ }
+
+ {
+ name_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-a");
+ assert (test_post_fail (p));
+ }
+
+ {
+ name_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("1a");
+ assert (test_post_fail (p));
+ }
+
+ {
+ name_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("a,b");
+ assert (test_post_fail (p));
+ }
+
+ {
+ name_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("a b");
+ assert (test_post_fail (p));
+ }
+
+ {
+ name_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("a<b");
+ assert (test_post_fail (p));
+ }
+
+ // nmtoken
+ //
+ {
+ nmtoken_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ nmtoken_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("a,b");
+ assert (test_post_fail (p));
+ }
+
+ {
+ nmtoken_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("a b");
+ assert (test_post_fail (p));
+ }
+
+ {
+ nmtoken_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("a<b");
+ assert (test_post_fail (p));
+ }
+
+ // nmtokens
+ //
+ {
+ nmtokens_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" ");
+ p._characters (" \t\n ");
+ assert (test_post_fail (p));
+ }
+
+ {
+ nmtokens_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("ab a,b");
+ assert (test_post_fail (p));
+ }
+
+ // ncname
+ //
+ {
+ ncname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("");
+ assert (test_post_fail (p));
+ }
+
+ {
+ ncname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (".a");
+ assert (test_post_fail (p));
+ }
+
+ {
+ ncname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("-a");
+ assert (test_post_fail (p));
+ }
+
+ {
+ ncname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (":a");
+ assert (test_post_fail (p));
+ }
+
+ {
+ ncname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("1a");
+ assert (test_post_fail (p));
+ }
+
+ {
+ ncname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("1:a");
+ assert (test_post_fail (p));
+ }
+
+ {
+ ncname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("a,b");
+ assert (test_post_fail (p));
+ }
+
+ {
+ ncname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("a b");
+ assert (test_post_fail (p));
+ }
+
+ {
+ ncname_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("a<b");
+ assert (test_post_fail (p));
+ }
+
+ // id
+ //
+ {
+ id_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("a b");
+ assert (test_post_fail (p));
+ }
+
+ // idref
+ //
+ {
+ idref_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("a b");
+ assert (test_post_fail (p));
+ }
+
+ // idrefs
+ //
+ {
+ idrefs_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" ");
+ p._characters (" \t\n ");
+ assert (test_post_fail (p));
+ }
+
+ {
+ idrefs_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("ab a<b");
+ assert (test_post_fail (p));
+ }
+
+ // language
+ //
+ {
+ language_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" ");
+ assert (test_post_fail (p));
+ }
+
+ {
+ language_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("en-");
+ assert (test_post_fail (p));
+ }
+
+ {
+ language_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("a1");
+ assert (test_post_fail (p));
+ }
+
+ {
+ language_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("en+us");
+ assert (test_post_fail (p));
+ }
+
+ {
+ language_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("en-nine99999");
+ assert (test_post_fail (p));
+ }
+}
diff --git a/tests/cxx/parser/validation/built-in/string/makefile b/tests/cxx/parser/validation/built-in/string/makefile
new file mode 100644
index 0000000..7ac9c5a
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/string/makefile
@@ -0,0 +1,60 @@
+# file : tests/cxx/parser/validation/built-in/string/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
diff --git a/tests/cxx/parser/validation/built-in/uri/driver.cxx b/tests/cxx/parser/validation/built-in/uri/driver.cxx
new file mode 100644
index 0000000..959e1c1
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/uri/driver.cxx
@@ -0,0 +1,55 @@
+// file : tests/cxx/parser/validation/built-in/uri/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the built-in anyURI type validation.
+//
+#include <cassert>
+
+#include <xsd/cxx/parser/validating/exceptions.hxx>
+#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>
+
+using namespace xsd::cxx::parser::validating;
+
+int
+main ()
+{
+ // Good.
+ //
+ {
+ uri_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters (" ");
+ p._post ();
+ assert (p.post_uri () == "");
+ }
+
+ {
+ uri_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("relative");
+ p._post ();
+ assert (p.post_uri () == "relative");
+ }
+
+ {
+ uri_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("#id");
+ p._post ();
+ assert (p.post_uri () == "#id");
+ }
+
+ {
+ uri_pimpl<char> p;
+ p.pre ();
+ p._pre ();
+ p._characters ("http://www.example.com/foo#bar");
+ p._post ();
+ assert (p.post_uri () == "http://www.example.com/foo#bar");
+ }
+}
diff --git a/tests/cxx/parser/validation/built-in/uri/makefile b/tests/cxx/parser/validation/built-in/uri/makefile
new file mode 100644
index 0000000..b6341b0
--- /dev/null
+++ b/tests/cxx/parser/validation/built-in/uri/makefile
@@ -0,0 +1,60 @@
+# file : tests/cxx/parser/validation/built-in/uri/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
diff --git a/tests/cxx/parser/validation/choice/driver.cxx b/tests/cxx/parser/validation/choice/driver.cxx
new file mode 100644
index 0000000..234bfc2
--- /dev/null
+++ b/tests/cxx/parser/validation/choice/driver.cxx
@@ -0,0 +1,128 @@
+// file : tests/cxx/parser/validation/choice/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the choice compositor validation.
+//
+
+#include <string>
+#include <fstream>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace test;
+using xml_schema::ro_string;
+
+struct choice_pimpl: choice_pskel
+{
+ virtual void
+ pre ()
+ {
+ cout << "{" << endl;
+ }
+
+ virtual void
+ a (string const& v)
+ {
+ cout << " a = " << v << endl;
+ }
+
+ virtual void
+ b (string const& v)
+ {
+ cout << " b = " << v << endl;
+ }
+
+ virtual void
+ c (string const& v)
+ {
+ cout << " c = " << v << endl;
+ }
+
+ virtual void
+ d (string const& v)
+ {
+ cout << " d = " << v << endl;
+ }
+
+ virtual void
+ _start_any_element (ro_string const& ns,
+ ro_string const& name,
+ ro_string const*)
+ {
+ cout << " any: " << ns << "#" << name << endl
+ << " {" << endl;
+ }
+
+ virtual void
+ _any_characters (ro_string const& v)
+ {
+ cout << " chars = " << v << endl;
+ }
+
+ virtual void
+ _end_any_element (ro_string const&, ro_string const&)
+ {
+ cout << " }" << endl;
+ }
+
+ virtual void
+ post_choice ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct type_pimpl: type_pskel
+{
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ xml_schema::string_pimpl string_p;
+ choice_pimpl choice_p;
+ type_pimpl type_p;
+
+ choice_p.parsers (string_p, string_p, string_p, string_p);
+ type_p.parsers (choice_p);
+
+ xml_schema::document doc_p (type_p, "test", "root");
+
+ try
+ {
+ ifstream ifs (argv[1]);
+ type_p.pre ();
+ doc_p.parse (ifs, argv[1], "", xml_schema::flags::dont_validate);
+ type_p.post_type ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cout << " " << e << endl
+ << "}" << endl
+ << endl;
+ }
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/validation/choice/makefile b/tests/cxx/parser/validation/choice/makefile
new file mode 100644
index 0000000..2e957d6
--- /dev/null
+++ b/tests/cxx/parser/validation/choice/makefile
@@ -0,0 +1,85 @@
+# file : tests/cxx/parser/validation/choice/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+tests := 000 001 002 003 004
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-validation
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+test_targets := $(addprefix $(out_base)/.test-,$(tests))
+
+.PHONY: $(test)
+$(test): $(test_targets)
+
+
+$(test_targets): driver := $(driver)
+
+.PHONY: $(out_base)/.test-%
+$(out_base)/.test-%: $(driver) $(src_base)/test.xsd $(src_base)/test-%.xml $(src_base)/test-%.std
+ $(call message,test $(out_base)/$*,$(driver) $(src_base)/test-$*.xml | diff -u $(src_base)/test-$*.std -)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/validation/choice/test-000.std b/tests/cxx/parser/validation/choice/test-000.std
new file mode 100644
index 0000000..856b7f5
--- /dev/null
+++ b/tests/cxx/parser/validation/choice/test-000.std
@@ -0,0 +1,22 @@
+{
+ a = a
+ b = b
+}
+
+{
+ c = c
+ d = d
+ any: other#any
+ {
+ chars = any
+ }
+ a = a
+}
+
+{
+ c = c
+ d = d
+ d = d
+ a = a
+}
+
diff --git a/tests/cxx/parser/validation/choice/test-000.xml b/tests/cxx/parser/validation/choice/test-000.xml
new file mode 100644
index 0000000..39b9614
--- /dev/null
+++ b/tests/cxx/parser/validation/choice/test-000.xml
@@ -0,0 +1,30 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <choice>
+ <a>a</a>
+
+ <b>b</b>
+ </choice>
+
+ <choice>
+ <c>c</c>
+ <d>d</d>
+
+ <o:any>any</o:any>
+
+ <a>a</a>
+ </choice>
+
+ <choice>
+ <c>c</c>
+ <d>d</d>
+
+ <d>d</d>
+
+ <a>a</a>
+ </choice>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/choice/test-001.std b/tests/cxx/parser/validation/choice/test-001.std
new file mode 100644
index 0000000..8a78666
--- /dev/null
+++ b/tests/cxx/parser/validation/choice/test-001.std
@@ -0,0 +1,4 @@
+{
+ :8:12 error: expected element 'a'
+}
+
diff --git a/tests/cxx/parser/validation/choice/test-001.xml b/tests/cxx/parser/validation/choice/test-001.xml
new file mode 100644
index 0000000..c509e0d
--- /dev/null
+++ b/tests/cxx/parser/validation/choice/test-001.xml
@@ -0,0 +1,10 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- invalid -->
+ <choice>
+ </choice>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/choice/test-002.std b/tests/cxx/parser/validation/choice/test-002.std
new file mode 100644
index 0000000..1dc1a3a
--- /dev/null
+++ b/tests/cxx/parser/validation/choice/test-002.std
@@ -0,0 +1,11 @@
+{
+ c = c
+ d = d
+ any: other#any
+ {
+ chars = any
+ }
+ a = a
+ :14:8 error: unexpected element 'b'
+}
+
diff --git a/tests/cxx/parser/validation/choice/test-002.xml b/tests/cxx/parser/validation/choice/test-002.xml
new file mode 100644
index 0000000..3b7e663
--- /dev/null
+++ b/tests/cxx/parser/validation/choice/test-002.xml
@@ -0,0 +1,17 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- invalid -->
+ <choice>
+ <c>c</c>
+ <d>d</d>
+
+ <o:any>any</o:any>
+
+ <a>a</a>
+ <b>b</b>
+ </choice>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/choice/test-003.std b/tests/cxx/parser/validation/choice/test-003.std
new file mode 100644
index 0000000..29d5e44
--- /dev/null
+++ b/tests/cxx/parser/validation/choice/test-003.std
@@ -0,0 +1,5 @@
+{
+ c = c
+ :9:12 error: expected element 'd'
+}
+
diff --git a/tests/cxx/parser/validation/choice/test-003.xml b/tests/cxx/parser/validation/choice/test-003.xml
new file mode 100644
index 0000000..ba15c7e
--- /dev/null
+++ b/tests/cxx/parser/validation/choice/test-003.xml
@@ -0,0 +1,11 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- invalid -->
+ <choice>
+ <c>c</c>
+ </choice>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/choice/test-004.std b/tests/cxx/parser/validation/choice/test-004.std
new file mode 100644
index 0000000..4a7530b
--- /dev/null
+++ b/tests/cxx/parser/validation/choice/test-004.std
@@ -0,0 +1,4 @@
+{
+ :8:8 error: expected element 'a' instead of 'x'
+}
+
diff --git a/tests/cxx/parser/validation/choice/test-004.xml b/tests/cxx/parser/validation/choice/test-004.xml
new file mode 100644
index 0000000..f6960dd
--- /dev/null
+++ b/tests/cxx/parser/validation/choice/test-004.xml
@@ -0,0 +1,11 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- invalid -->
+ <choice>
+ <x>x</x>
+ </choice>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/choice/test.xsd b/tests/cxx/parser/validation/choice/test.xsd
new file mode 100644
index 0000000..8132bbb
--- /dev/null
+++ b/tests/cxx/parser/validation/choice/test.xsd
@@ -0,0 +1,24 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="choice">
+ <choice maxOccurs="3">
+ <element name="a" type="string"/>
+ <element name="b" type="string" maxOccurs="unbounded"/>
+ <sequence>
+ <element name="c" type="string" minOccurs="0"/>
+ <element name="d" type="string"/>
+ </sequence>
+ <any namespace="other" maxOccurs="unbounded"/>
+ </choice>
+ </complexType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="choice" type="t:choice" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/parser/validation/makefile b/tests/cxx/parser/validation/makefile
new file mode 100644
index 0000000..9000e4c
--- /dev/null
+++ b/tests/cxx/parser/validation/makefile
@@ -0,0 +1,22 @@
+# file : tests/cxx/parser/validation/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+
+tests := all any attribute built-in choice restriction sequence
+
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/parser/validation/restriction/driver.cxx b/tests/cxx/parser/validation/restriction/driver.cxx
new file mode 100644
index 0000000..34db4d2
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/driver.cxx
@@ -0,0 +1,109 @@
+// file : tests/cxx/parser/validation/restriction/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the restriction compositor validation.
+//
+
+#include <string>
+#include <fstream>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace test;
+
+struct base_a_pimpl: base_a_pskel
+{
+};
+
+struct restriction_a_pimpl: restriction_a_pskel
+{
+};
+
+struct extension_b_pimpl: extension_b_pskel
+{
+};
+
+struct restriction_b_pimpl: restriction_b_pskel
+{
+};
+
+struct type_b_pimpl: type_b_pskel
+{
+};
+
+struct type_r_pimpl: type_r_pskel
+{
+};
+
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ xml_schema::string_pimpl string_p;
+ base_a_pimpl base_a_p;
+ restriction_a_pimpl restriction_a_p;
+ extension_b_pimpl extension_b_p;
+ restriction_b_pimpl restriction_b_p;
+ type_b_pimpl type_b_p;
+ type_r_pimpl type_r_p;
+
+ base_a_p.parsers (string_p, string_p, string_p,
+ string_p, string_p, string_p);
+
+ restriction_a_p.parsers (string_p, string_p, string_p,
+ string_p, string_p, string_p);
+
+ extension_b_p.parsers (string_p, string_p, string_p,
+ string_p, string_p);
+
+ restriction_b_p.parsers (string_p, string_p, string_p,
+ string_p, string_p);
+
+ type_b_p.parsers (base_a_p, extension_b_p);
+ type_r_p.parsers (restriction_a_p, restriction_b_p);
+
+ xml_schema::document doc_b_p (type_b_p, "test", "root");
+ xml_schema::document doc_r_p (type_r_p, "test", "root");
+
+ {
+ ifstream ifs (argv[1]);
+ type_b_p.pre ();
+ doc_b_p.parse (ifs, argv[1], "", xml_schema::flags::dont_validate);
+ type_b_p.post_type_b ();
+ }
+
+ try
+ {
+ ifstream ifs (argv[1]);
+ type_r_p.pre ();
+ doc_r_p.parse (ifs, argv[1], "", xml_schema::flags::dont_validate);
+ type_r_p.post_type_r ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cout << e << endl;
+ }
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/validation/restriction/makefile b/tests/cxx/parser/validation/restriction/makefile
new file mode 100644
index 0000000..bb78c5e
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/makefile
@@ -0,0 +1,85 @@
+# file : tests/cxx/parser/validation/restriction/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+tests := 000 001 002 003 004 005
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-validation
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+test_targets := $(addprefix $(out_base)/.test-,$(tests))
+
+.PHONY: $(test)
+$(test): $(test_targets)
+
+
+$(test_targets): driver := $(driver)
+
+.PHONY: $(out_base)/.test-%
+$(out_base)/.test-%: $(driver) $(src_base)/test.xsd $(src_base)/test-%.xml $(src_base)/test-%.std
+ $(call message,test $(out_base)/$*,$(driver) $(src_base)/test-$*.xml | diff -u $(src_base)/test-$*.std -)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/validation/restriction/test-000.std b/tests/cxx/parser/validation/restriction/test-000.std
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/test-000.std
diff --git a/tests/cxx/parser/validation/restriction/test-000.xml b/tests/cxx/parser/validation/restriction/test-000.xml
new file mode 100644
index 0000000..21402b4
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/test-000.xml
@@ -0,0 +1,31 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <restriction-a z="z">
+ <a>a</a>
+ <b>b</b>
+ <c>c</c>
+ </restriction-a>
+
+ <restriction-a x="x" y="y" z="z">
+ <a>a</a>
+ <b>b</b>
+ <c>c</c>
+ </restriction-a>
+
+ <restriction-b y="y">
+ <a>a</a>
+ <b>b</b>
+ </restriction-b>
+
+ <restriction-b y="y">
+ <a>a</a>
+ <c>c</c>
+ </restriction-b>
+
+ <restriction-b x="x" y="y">
+ <a>a</a>
+ </restriction-b>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/restriction/test-001.std b/tests/cxx/parser/validation/restriction/test-001.std
new file mode 100644
index 0000000..5077837
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/test-001.std
@@ -0,0 +1 @@
+:7:8 error: expected element 'a' instead of 'b'
diff --git a/tests/cxx/parser/validation/restriction/test-001.xml b/tests/cxx/parser/validation/restriction/test-001.xml
new file mode 100644
index 0000000..4015302
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/test-001.xml
@@ -0,0 +1,11 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- valid base but not restriction: a element -->
+ <restriction-a z="z">
+ <b>b</b>
+ <c>c</c>
+ </restriction-a>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/restriction/test-002.std b/tests/cxx/parser/validation/restriction/test-002.std
new file mode 100644
index 0000000..f12c342
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/test-002.std
@@ -0,0 +1 @@
+:10:19 error: expected attribute 'z'
diff --git a/tests/cxx/parser/validation/restriction/test-002.xml b/tests/cxx/parser/validation/restriction/test-002.xml
new file mode 100644
index 0000000..eb7684c
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/test-002.xml
@@ -0,0 +1,12 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- valid base but not restriction: z attribute -->
+ <restriction-a>
+ <a>a</a>
+ <b>b</b>
+ <c>c</c>
+ </restriction-a>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/restriction/test-003.std b/tests/cxx/parser/validation/restriction/test-003.std
new file mode 100644
index 0000000..0c65175
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/test-003.std
@@ -0,0 +1 @@
+:11:8 error: unexpected element 'a'
diff --git a/tests/cxx/parser/validation/restriction/test-003.xml b/tests/cxx/parser/validation/restriction/test-003.xml
new file mode 100644
index 0000000..49f18c7
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/test-003.xml
@@ -0,0 +1,16 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- valid base but not restriction: sequence maxOccurs="1" -->
+ <restriction-a z="z">
+ <a>a</a>
+ <b>b</b>
+ <c>c</c>
+
+ <a>a</a>
+ <b>b</b>
+ <c>c</c>
+ </restriction-a>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/restriction/test-004.std b/tests/cxx/parser/validation/restriction/test-004.std
new file mode 100644
index 0000000..5077837
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/test-004.std
@@ -0,0 +1 @@
+:7:8 error: expected element 'a' instead of 'b'
diff --git a/tests/cxx/parser/validation/restriction/test-004.xml b/tests/cxx/parser/validation/restriction/test-004.xml
new file mode 100644
index 0000000..115cd38
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/test-004.xml
@@ -0,0 +1,10 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- valid extension but not restriction: a element -->
+ <restriction-b y="y">
+ <b>b</b>
+ </restriction-b>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/restriction/test-005.std b/tests/cxx/parser/validation/restriction/test-005.std
new file mode 100644
index 0000000..e92de14
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/test-005.std
@@ -0,0 +1 @@
+:9:19 error: expected attribute 'y'
diff --git a/tests/cxx/parser/validation/restriction/test-005.xml b/tests/cxx/parser/validation/restriction/test-005.xml
new file mode 100644
index 0000000..e9ab7d9
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/test-005.xml
@@ -0,0 +1,11 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- valid extension but not restriction: y attribute -->
+ <restriction-b>
+ <a>a</a>
+ <b>b</b>
+ </restriction-b>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/restriction/test.xsd b/tests/cxx/parser/validation/restriction/test.xsd
new file mode 100644
index 0000000..158ded5
--- /dev/null
+++ b/tests/cxx/parser/validation/restriction/test.xsd
@@ -0,0 +1,82 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- simple case -->
+ <complexType name="base-a">
+ <sequence minOccurs="1" maxOccurs="2">
+ <element name="a" type="string" minOccurs="0"/>
+ <element name="b" type="string"/>
+ <element name="c" type="string"/>
+ </sequence>
+ <attribute name="x" type="string"/>
+ <attribute name="y" type="string"/>
+ <attribute name="z" type="string"/>
+ </complexType>
+
+ <complexType name="restriction-a">
+ <complexContent>
+ <restriction base="t:base-a">
+ <sequence minOccurs="1" maxOccurs="1">
+ <element name="a" type="string" minOccurs="1"/>
+ <element name="b" type="string"/>
+ <element name="c" type="string"/>
+ </sequence>
+ <!-- Can be ommited if not changed, e.g., 'x'. -->
+ <attribute name="y" type="string"/> <!-- But can also be repeated without change. -->
+ <attribute name="z" type="string" use="required"/>
+ </restriction>
+ </complexContent>
+ </complexType>
+
+ <!-- restriction of an extension -->
+ <complexType name="base-b">
+ <sequence>
+ <element name="a" type="string" minOccurs="0"/>
+ </sequence>
+ <attribute name="x" type="string"/>
+ </complexType>
+
+ <complexType name="extension-b">
+ <complexContent>
+ <extension base="t:base-b">
+ <choice>
+ <element name="b" type="string" minOccurs="0"/>
+ <element name="c" type="string"/>
+ </choice>
+ <attribute name="y" type="string"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="restriction-b">
+ <complexContent>
+ <restriction base="t:extension-b">
+ <sequence>
+ <sequence>
+ <element name="a" type="string" minOccurs="1"/>
+ </sequence>
+ <choice>
+ <element name="b" type="string" minOccurs="0"/>
+ <element name="c" type="string"/>
+ </choice>
+ </sequence>
+ <attribute name="y" type="string" use="required"/>
+ </restriction>
+ </complexContent>
+ </complexType>
+
+ <complexType name="type-b">
+ <choice maxOccurs="unbounded">
+ <element name="restriction-a" type="t:base-a"/>
+ <element name="restriction-b" type="t:extension-b"/>
+ </choice>
+ </complexType>
+
+ <complexType name="type-r">
+ <choice maxOccurs="unbounded">
+ <element name="restriction-a" type="t:restriction-a"/>
+ <element name="restriction-b" type="t:restriction-b"/>
+ </choice>
+ </complexType>
+
+</schema>
diff --git a/tests/cxx/parser/validation/sequence/driver.cxx b/tests/cxx/parser/validation/sequence/driver.cxx
new file mode 100644
index 0000000..a1e1101
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/driver.cxx
@@ -0,0 +1,141 @@
+// file : tests/cxx/parser/validation/sequence/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the sequence compositor validation.
+//
+
+#include <string>
+#include <fstream>
+#include <iostream>
+
+#include "test-pskel.hxx"
+
+using namespace std;
+using namespace test;
+using xml_schema::ro_string;
+
+struct sequence_pimpl: sequence_pskel
+{
+ virtual void
+ pre ()
+ {
+ cout << "{" << endl;
+ }
+
+ virtual void
+ a (string const& v)
+ {
+ cout << " a = " << v << endl;
+ }
+
+ virtual void
+ b (string const& v)
+ {
+ cout << " b = " << v << endl;
+ }
+
+ virtual void
+ c (string const& v)
+ {
+ cout << " c = " << v << endl;
+ }
+
+ virtual void
+ d (string const& v)
+ {
+ cout << " d = " << v << endl;
+ }
+
+ virtual void
+ e (string const& v)
+ {
+ cout << " e = " << v << endl;
+ }
+
+ virtual void
+ f (string const& v)
+ {
+ cout << " f = " << v << endl;
+ }
+
+ virtual void
+ _start_any_element (ro_string const& ns,
+ ro_string const& name,
+ ro_string const*)
+ {
+ cout << " any: " << ns << "#" << name << endl
+ << " {" << endl;
+ }
+
+ virtual void
+ _any_characters (ro_string const& v)
+ {
+ cout << " chars = " << v << endl;
+ }
+
+ virtual void
+ _end_any_element (ro_string const&, ro_string const&)
+ {
+ cout << " }" << endl;
+ }
+
+ virtual void
+ post_sequence ()
+ {
+ cout << "}" << endl
+ << endl;
+ }
+};
+
+struct type_pimpl: type_pskel
+{
+};
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ xml_schema::string_pimpl string_p;
+ sequence_pimpl sequence_p;
+ type_pimpl type_p;
+
+ sequence_p.parsers (string_p, string_p, string_p,
+ string_p, string_p, string_p);
+ type_p.parsers (sequence_p);
+
+ xml_schema::document doc_p (type_p, "test", "root");
+
+ try
+ {
+ ifstream ifs (argv[1]);
+ type_p.pre ();
+ doc_p.parse (ifs, argv[1], "", xml_schema::flags::dont_validate);
+ type_p.post_type ();
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cout << " " << e << endl
+ << "}" << endl
+ << endl;
+ }
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+ catch (ios_base::failure const&)
+ {
+ cerr << "io failure" << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/parser/validation/sequence/makefile b/tests/cxx/parser/validation/sequence/makefile
new file mode 100644
index 0000000..e06b3a0
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/makefile
@@ -0,0 +1,85 @@
+# file : tests/cxx/parser/validation/sequence/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+tests := 000 001 002 003 004 005 006
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=-pskel.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+skel := $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.ixx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx)
+
+$(skel): xsd := $(out_root)/xsd/xsd
+$(skel): xsd_options := --generate-validation
+$(skel): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+test_targets := $(addprefix $(out_base)/.test-,$(tests))
+
+.PHONY: $(test)
+$(test): $(test_targets)
+
+
+$(test_targets): driver := $(driver)
+
+.PHONY: $(out_base)/.test-%
+$(out_base)/.test-%: $(driver) $(src_base)/test.xsd $(src_base)/test-%.xml $(src_base)/test-%.std
+ $(call message,test $(out_base)/$*,$(driver) $(src_base)/test-$*.xml | diff -u $(src_base)/test-$*.std -)
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/parser/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/parser/validation/sequence/test-000.std b/tests/cxx/parser/validation/sequence/test-000.std
new file mode 100644
index 0000000..8a44762
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-000.std
@@ -0,0 +1,56 @@
+{
+ c = c
+ d = d
+ any: test#any
+ {
+ chars = aaa
+ any: #a
+ {
+ chars = bbb
+ }
+ chars = ccc
+ }
+ f = f
+ e = e
+}
+
+{
+ a = a
+ b = b
+ c = c
+ d = d
+ d = d
+ d = d
+ any: other#any
+ {
+ chars = any
+ }
+ f = f
+ e = e
+ e = e
+}
+
+{
+ a = a
+ b = b
+ c = c
+ d = d
+ d = d
+ d = d
+ any: other#any
+ {
+ chars = any
+ }
+ f = f
+ e = e
+ e = e
+ c = c
+ d = d
+ any: test#any
+ {
+ chars = any
+ }
+ f = f
+ e = e
+}
+
diff --git a/tests/cxx/parser/validation/sequence/test-000.xml b/tests/cxx/parser/validation/sequence/test-000.xml
new file mode 100644
index 0000000..9bcbd7e
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-000.xml
@@ -0,0 +1,46 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <sequence>
+ <c>c</c>
+ <d>d</d>
+ <t:any>aaa<a>bbb</a>ccc</t:any>
+ <f>f</f>
+ <e>e</e>
+ </sequence>
+
+ <sequence>
+ <a>a</a>
+ <b>b</b>
+ <c>c</c>
+ <d>d</d>
+ <d>d</d>
+ <d>d</d>
+ <o:any>any</o:any>
+ <f>f</f>
+ <e>e</e>
+ <e>e</e>
+ </sequence>
+
+ <sequence>
+ <a>a</a>
+ <b>b</b>
+ <c>c</c>
+ <d>d</d>
+ <d>d</d>
+ <d>d</d>
+ <o:any>any</o:any>
+ <f>f</f>
+ <e>e</e>
+ <e>e</e>
+
+ <c>c</c>
+ <d>d</d>
+ <t:any>any</t:any>
+ <f>f</f>
+ <e>e</e>
+ </sequence>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/sequence/test-001.std b/tests/cxx/parser/validation/sequence/test-001.std
new file mode 100644
index 0000000..20dea34
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-001.std
@@ -0,0 +1,4 @@
+{
+ :8:14 error: expected element 'a'
+}
+
diff --git a/tests/cxx/parser/validation/sequence/test-001.xml b/tests/cxx/parser/validation/sequence/test-001.xml
new file mode 100644
index 0000000..67d33ce
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-001.xml
@@ -0,0 +1,10 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- fail minOccurs="1" -->
+ <sequence>
+ </sequence>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/sequence/test-002.std b/tests/cxx/parser/validation/sequence/test-002.std
new file mode 100644
index 0000000..61343e7
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-002.std
@@ -0,0 +1,20 @@
+{
+ c = c
+ d = d
+ any: test#any
+ {
+ chars = any
+ }
+ f = f
+ e = e
+ c = c
+ d = d
+ any: test#any
+ {
+ chars = any
+ }
+ f = f
+ e = e
+ :20:8 error: unexpected element 'c'
+}
+
diff --git a/tests/cxx/parser/validation/sequence/test-002.xml b/tests/cxx/parser/validation/sequence/test-002.xml
new file mode 100644
index 0000000..be25fcf
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-002.xml
@@ -0,0 +1,27 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- fail maxOccurs="2" -->
+ <sequence>
+ <c>c</c>
+ <d>d</d>
+ <t:any>any</t:any>
+ <f>f</f>
+ <e>e</e>
+
+ <c>c</c>
+ <d>d</d>
+ <t:any>any</t:any>
+ <f>f</f>
+ <e>e</e>
+
+ <c>c</c>
+ <d>d</d>
+ <t:any>any</t:any>
+ <f>f</f>
+ <e>e</e>
+ </sequence>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/sequence/test-003.std b/tests/cxx/parser/validation/sequence/test-003.std
new file mode 100644
index 0000000..c4e1e46
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-003.std
@@ -0,0 +1,5 @@
+{
+ a = a
+ :9:8 error: expected element 'b' instead of 'a'
+}
+
diff --git a/tests/cxx/parser/validation/sequence/test-003.xml b/tests/cxx/parser/validation/sequence/test-003.xml
new file mode 100644
index 0000000..af7d21d
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-003.xml
@@ -0,0 +1,17 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- fail a maxOccurs="1" -->
+ <sequence>
+ <a>a</a>
+ <a>a</a>
+ <c>c</c>
+ <d>d</d>
+ <t:any>any</t:any>
+ <f>f</f>
+ <e>e</e>
+ </sequence>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/sequence/test-004.std b/tests/cxx/parser/validation/sequence/test-004.std
new file mode 100644
index 0000000..f4c1d4d
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-004.std
@@ -0,0 +1,4 @@
+{
+ :8:8 error: expected element 'a' instead of 'd'
+}
+
diff --git a/tests/cxx/parser/validation/sequence/test-004.xml b/tests/cxx/parser/validation/sequence/test-004.xml
new file mode 100644
index 0000000..a58b6d4
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-004.xml
@@ -0,0 +1,14 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- fail c minOccurs="1" -->
+ <sequence>
+ <d>d</d>
+ <t:any>any</t:any>
+ <f>f</f>
+ <e>e</e>
+ </sequence>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/sequence/test-005.std b/tests/cxx/parser/validation/sequence/test-005.std
new file mode 100644
index 0000000..9fa7904
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-005.std
@@ -0,0 +1,6 @@
+{
+ c = c
+ d = d
+ :10:13 error: expected element '##targetNamespace#*' instead of 'other1#any'
+}
+
diff --git a/tests/cxx/parser/validation/sequence/test-005.xml b/tests/cxx/parser/validation/sequence/test-005.xml
new file mode 100644
index 0000000..e3dd03d
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-005.xml
@@ -0,0 +1,15 @@
+<t:root xmlns:t="test"
+ xmlns:o1="other1"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- fail any namespace="##targetNamespace other" -->
+ <sequence>
+ <c>c</c>
+ <d>d</d>
+ <o1:any>any</o1:any>
+ <f>f</f>
+ <e>e</e>
+ </sequence>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/sequence/test-006.std b/tests/cxx/parser/validation/sequence/test-006.std
new file mode 100644
index 0000000..eb79f47
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-006.std
@@ -0,0 +1,13 @@
+{
+ c = c
+ d = d
+ any: test#any
+ {
+ chars = any
+ }
+ f = f
+ e = e
+ e = e
+ :14:8 error: unexpected element 'e'
+}
+
diff --git a/tests/cxx/parser/validation/sequence/test-006.xml b/tests/cxx/parser/validation/sequence/test-006.xml
new file mode 100644
index 0000000..e1ecd69
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test-006.xml
@@ -0,0 +1,17 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <!-- fail e maxOccurs="2" -->
+ <sequence>
+ <c>c</c>
+ <d>d</d>
+ <t:any>any</t:any>
+ <f>f</f>
+ <e>e</e>
+ <e>e</e>
+ <e>e</e>
+ </sequence>
+
+</t:root>
diff --git a/tests/cxx/parser/validation/sequence/test.xsd b/tests/cxx/parser/validation/sequence/test.xsd
new file mode 100644
index 0000000..8753f54
--- /dev/null
+++ b/tests/cxx/parser/validation/sequence/test.xsd
@@ -0,0 +1,28 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="sequence">
+ <sequence minOccurs="1" maxOccurs="2">
+ <element name="a" type="string" minOccurs="0"/>
+ <sequence>
+ <element name="b" type="string" minOccurs="0"/>
+ <element name="c" type="string"/>
+ </sequence>
+ <element name="d" type="string" maxOccurs="unbounded"/>
+ <sequence>
+ <any namespace="##targetNamespace other"/>
+ <element name="f" type="string"/>
+ </sequence>
+ <element name="e" type="string" maxOccurs="2"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="sequence" type="t:sequence" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/binary/cdr/driver.cxx b/tests/cxx/tree/binary/cdr/driver.cxx
new file mode 100644
index 0000000..40cb799
--- /dev/null
+++ b/tests/cxx/tree/binary/cdr/driver.cxx
@@ -0,0 +1,137 @@
+// file : tests/cxx/tree/binary/cdr/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test non-polymorphic binary serialization to ACE CDR.
+//
+
+#include <memory> // std::auto_ptr
+#include <cassert>
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<type> r (root (argv[1]));
+
+ // Save to a CDR stream.
+ //
+ ACE_OutputCDR ace_ocdr;
+ xml_schema::ostream<ACE_OutputCDR> ocdr (ace_ocdr);
+ ocdr << *r;
+
+ // Load from a CDR stream.
+ //
+ ACE_InputCDR ace_icdr (ace_ocdr);
+ xml_schema::istream<ACE_InputCDR> icdr (ace_icdr);
+ auto_ptr<type> c (new type (icdr));
+
+ // Compare the two.
+ //
+ assert (r->list () == c->list ());
+ assert (r->union_ () == c->union_ ());
+ assert (r->enumeration () == c->enumeration ());
+
+ type::complex_sequence rs (r->complex ()), cs (c->complex ());
+
+ for (type::complex_iterator ri (rs.begin ()), ci (cs.begin ());
+ ri != rs.end () && ci != rs.end (); ++ri, ++ci)
+ {
+ assert (ri->a () == ci->a ());
+ if (ri->b ())
+ assert (ri->b () == ci->b ());
+ assert (ri->c () == ci->c ());
+
+ assert (ri->x () == ci->x ());
+ if (ri->y ())
+ assert (ri->y () == ci->y ());
+ }
+
+ // integers
+ //
+ assert (r->byte () == c->byte ());
+ assert (r->unsigned_byte () == c->unsigned_byte ());
+ assert (r->short_ () == c->short_ ());
+ assert (r->unsigned_short () == c->unsigned_short ());
+ assert (r->int_ () == c->int_ ());
+ assert (r->unsigned_int () == c->unsigned_int ());
+ assert (r->long_ () == c->long_ ());
+ assert (r->unsigned_long () == c->unsigned_long ());
+ assert (r->integer () == c->integer ());
+ assert (r->non_positive_integer () == c->non_positive_integer ());
+ assert (r->non_negative_integer () == c->non_negative_integer ());
+ assert (r->positive_integer () == c->positive_integer ());
+ assert (r->negative_integer () == c->negative_integer ());
+
+ // boolean
+ //
+ assert (r->boolean () == c->boolean ());
+
+ // floats
+ //
+ assert (r->float_ () == c->float_ ());
+ assert (r->double_ () == c->double_ ());
+ assert (r->decimal () == c->decimal ());
+
+ // strings
+ //
+ assert (r->string () == c->string ());
+ assert (r->normalized_string () == c->normalized_string ());
+ assert (r->token () == c->token ());
+ assert (r->name () == c->name ());
+ assert (r->name_token () == c->name_token ());
+ assert (r->name_tokens () == c->name_tokens ());
+ assert (r->ncname () == c->ncname ());
+ assert (r->language () == c->language ());
+
+ // qualified name
+ //
+ assert (r->qname () == c->qname ());
+
+ // ID/IDREF
+ //
+ assert (r->id () == c->id ());
+ assert (r->id_ref () == c->id_ref ());
+ assert (r->id_refs () == c->id_refs ());
+
+ // URI
+ //
+ assert (r->any_uri () == c->any_uri ());
+
+ // binary
+ //
+ assert (r->base64_binary () == c->base64_binary ());
+ assert (r->hex_binary () == c->hex_binary ());
+
+ // date/time
+ //
+ assert (r->day () == c->day ());
+ assert (r->month () == c->month ());
+ assert (r->year () == c->year ());
+ assert (r->month_day () == c->month_day ());
+ assert (r->year_month () == c->year_month ());
+ assert (r->date () == c->date ());
+ assert (r->time () == c->time ());
+ assert (r->date_time () == c->date_time ());
+ assert (r->duration () == c->duration ());
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/binary/cdr/makefile b/tests/cxx/tree/binary/cdr/makefile
new file mode 100644
index 0000000..3298f18
--- /dev/null
+++ b/tests/cxx/tree/binary/cdr/makefile
@@ -0,0 +1,86 @@
+# file : tests/cxx/tree/binary/cdr/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+$(call import,\
+ $(scf_root)/import/libace/stub.make,\
+ l: ace.l,cpp-options: ace.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l) $(ace.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options) $(ace.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--generate-insertion ACE_OutputCDR \
+--generate-extraction ACE_InputCDR
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml
+ $(call message,test $$1,$$1 $(src_base)/test.xml,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/binary/cdr/test.xml b/tests/cxx/tree/binary/cdr/test.xml
new file mode 100644
index 0000000..928b4cf
--- /dev/null
+++ b/tests/cxx/tree/binary/cdr/test.xml
@@ -0,0 +1,91 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <list>1 2 3</list>
+
+ <union>abc</union>
+
+ <enumeration>left</enumeration>
+
+ <complex x="1">
+ <a>aaa</a>
+ </complex>
+ <complex x="1" y="2">
+ <a>aaa</a>
+ <b>bbb</b>
+ <c>c</c>
+ <c>cc</c>
+ <c>ccc</c>
+ </complex>
+
+
+ <!-- integers -->
+ <byte>65</byte>
+ <unsigned_byte>66</unsigned_byte>
+ <short>-222</short>
+ <unsigned_short>57005</unsigned_short>
+ <int>-57005</int>
+ <unsigned_int>3735928559</unsigned_int>
+ <long>-3735928559</long>
+ <unsigned_long>16045690984833335023</unsigned_long>
+ <integer>-3735928559</integer>
+ <non_positive_integer>-3735928559</non_positive_integer>
+ <non_negative_integer>3735928559</non_negative_integer>
+ <positive_integer>3735928559</positive_integer>
+ <negative_integer>-3735928559</negative_integer>
+
+
+ <!-- boolean -->
+ <boolean>true</boolean>
+
+
+ <!-- floats -->
+ <float>1234.1234</float>
+ <double>12345678.12345678</double>
+ <decimal>1234567812345678.1234567812345678</decimal>
+
+
+ <!-- strings -->
+ <string>string</string>
+ <normalized_string>normalized string</normalized_string>
+ <token>one two three</token>
+ <name>name</name>
+ <name_token>name-token</name_token>
+ <name_tokens>name tokens</name_tokens>
+ <ncname>ncname</ncname>
+ <language>en-us</language>
+
+ <!-- qualified name -->
+ <qname>xsi:schemaLocation</qname>
+
+
+ <!-- ID/IDREF -->
+ <id>elements1</id>
+ <id>elements2</id>
+ <id_ref>elements1</id_ref>
+ <id_refs>elements1 elements2</id_refs>
+
+
+ <!-- URI -->
+ <any_uri>http://www.codesynthesis.com</any_uri>
+
+
+ <!-- binary -->
+ <base64_binary>YmFzZTY0IGJpbmFyeQ==</base64_binary>
+ <hex_binary>6865782052696E617279</hex_binary>
+
+
+ <!-- date/time -->
+ <date>2001-10-26+02:00</date>
+ <date_time>2001-10-26T21:32:52+02:00</date_time>
+ <duration>P1Y2M3DT5H20M30S</duration>
+ <day>---01+02:00</day>
+ <month>--11+02:00</month>
+ <month_day>--11-02+02:00</month_day>
+ <year>2001+02:00</year>
+ <year_month>2001-11+02:00</year_month>
+ <time>21:32:52+02:00</time>
+
+
+</t:root>
diff --git a/tests/cxx/tree/binary/cdr/test.xsd b/tests/cxx/tree/binary/cdr/test.xsd
new file mode 100644
index 0000000..e593f64
--- /dev/null
+++ b/tests/cxx/tree/binary/cdr/test.xsd
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:t="test"
+ targetNamespace="test">
+
+ <simpleType name="list">
+ <list itemType="int"/>
+ </simpleType>
+
+ <simpleType name="union">
+ <union memberTypes="int string"/>
+ </simpleType>
+
+ <simpleType name="enumeration">
+ <restriction base="string">
+ <enumeration value="top"/>
+ <enumeration value="left"/>
+ <enumeration value="bottom"/>
+ <enumeration value="right"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="base">
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ <attribute name="x" type="int" use="required"/>
+ </complexType>
+
+ <complexType name="complex">
+ <complexContent>
+ <extension base="t:base">
+ <sequence>
+ <element name="b" type="string" minOccurs="0"/>
+ <element name="c" type="string" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="y" type="int"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+
+ <complexType name="type">
+ <sequence>
+ <element name="list" type="t:list"/>
+ <element name="union" type="t:union"/>
+ <element name="enumeration" type="t:enumeration"/>
+ <element name="complex" type="t:complex" maxOccurs="unbounded"/>
+
+ <!-- integers -->
+ <element name="byte" type="byte"/>
+ <element name="unsigned_byte" type="unsignedByte"/>
+ <element name="short" type="short"/>
+ <element name="unsigned_short" type="unsignedShort"/>
+ <element name="int" type="int"/>
+ <element name="unsigned_int" type="unsignedInt"/>
+ <element name="long" type="long"/>
+ <element name="unsigned_long" type="unsignedLong"/>
+ <element name="integer" type="integer"/>
+ <element name="non_positive_integer" type="nonPositiveInteger"/>
+ <element name="non_negative_integer" type="nonNegativeInteger"/>
+ <element name="positive_integer" type="positiveInteger"/>
+ <element name="negative_integer" type="negativeInteger"/>
+
+
+ <!-- boolean -->
+ <element name="boolean" type="boolean"/>
+
+
+ <!-- floats -->
+ <element name="float" type="float"/>
+ <element name="double" type="double"/>
+ <element name="decimal" type="decimal"/>
+
+
+ <!-- strings -->
+ <element name="string" type="string"/>
+ <element name="normalized_string" type="normalizedString"/>
+ <element name="token" type="token"/>
+ <element name="name" type="Name"/>
+ <element name="name_token" type="NMTOKEN"/>
+ <element name="name_tokens" type="NMTOKENS"/>
+ <element name="ncname" type="NCName"/>
+ <element name="language" type="language"/>
+
+ <!-- qualified name -->
+ <element name="qname" type="QName"/>
+
+
+ <!-- ID/IDREF -->
+ <element name="id" maxOccurs="2" type="ID"/>
+ <element name="id_ref" type="IDREF"/>
+ <element name="id_refs" type="IDREFS"/>
+
+
+ <!-- URI -->
+ <element name="any_uri" type="anyURI"/>
+
+
+ <!-- binary -->
+ <element name="base64_binary" type="base64Binary"/>
+ <element name="hex_binary" type="hexBinary"/>
+
+
+ <!-- date/time -->
+ <element name="date" type="date"/>
+ <element name="date_time" type="dateTime"/>
+ <element name="duration" type="duration"/>
+ <element name="day" type="gDay"/>
+ <element name="month" type="gMonth"/>
+ <element name="month_day" type="gMonthDay"/>
+ <element name="year" type="gYear"/>
+ <element name="year_month" type="gYearMonth"/>
+ <element name="time" type="time"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/binary/makefile b/tests/cxx/tree/binary/makefile
new file mode 100644
index 0000000..9d57c0c
--- /dev/null
+++ b/tests/cxx/tree/binary/makefile
@@ -0,0 +1,20 @@
+# file : tests/cxx/tree/binary/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+tests := cdr polymorphic xdr
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/tree/binary/polymorphic/driver.cxx b/tests/cxx/tree/binary/polymorphic/driver.cxx
new file mode 100644
index 0000000..bd2b0cf
--- /dev/null
+++ b/tests/cxx/tree/binary/polymorphic/driver.cxx
@@ -0,0 +1,151 @@
+// file : tests/cxx/tree/binary/polymorphic/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test polymorphic binary serialization.
+//
+
+#include <memory> // std::auto_ptr
+#include <cassert>
+#include <iostream>
+#include <typeinfo>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<type> r (root (argv[1]));
+
+ // Save to a CDR stream.
+ //
+ ACE_OutputCDR ace_ocdr;
+ xml_schema::ostream<ACE_OutputCDR> ocdr (ace_ocdr);
+ ocdr << *r;
+
+ // Load from a CDR stream.
+ //
+ ACE_InputCDR ace_icdr (ace_ocdr);
+ xml_schema::istream<ACE_InputCDR> icdr (ace_icdr);
+ auto_ptr<type> c (new type (icdr));
+
+ // Compare the two.
+ //
+ assert (r->list () == c->list ());
+ assert (r->union_ () == c->union_ ());
+ assert (r->enumeration () == c->enumeration ());
+
+ {
+ complex& rc (dynamic_cast<complex&> (r->base ()));
+ complex& cc (dynamic_cast<complex&> (c->base ()));
+
+ assert (rc.a () == cc.a ());
+ if (rc.b ())
+ assert (rc.b () == cc.b ());
+ assert (rc.c () == cc.c ());
+
+ assert (rc.x () == cc.x ());
+ if (rc.y ())
+ assert (rc.y () == cc.y ());
+ }
+
+ {
+ complex& rc (dynamic_cast<complex&> (r->sbase ()));
+ complex& cc (dynamic_cast<complex&> (c->sbase ()));
+
+ assert (rc.a () == cc.a ());
+ if (rc.b ())
+ assert (rc.b () == cc.b ());
+ assert (rc.c () == cc.c ());
+
+ assert (rc.x () == cc.x ());
+ if (rc.y ())
+ assert (rc.y () == cc.y ());
+ }
+
+ // integers
+ //
+ assert (r->byte () == c->byte ());
+ assert (r->unsigned_byte () == c->unsigned_byte ());
+ assert (r->short_ () == c->short_ ());
+ assert (r->unsigned_short () == c->unsigned_short ());
+ assert (r->int_ () == c->int_ ());
+ assert (r->unsigned_int () == c->unsigned_int ());
+ assert (r->long_ () == c->long_ ());
+ assert (r->unsigned_long () == c->unsigned_long ());
+ assert (r->integer () == c->integer ());
+ assert (r->non_positive_integer () == c->non_positive_integer ());
+ assert (r->non_negative_integer () == c->non_negative_integer ());
+ assert (r->positive_integer () == c->positive_integer ());
+ assert (r->negative_integer () == c->negative_integer ());
+
+ // boolean
+ //
+ assert (r->boolean () == c->boolean ());
+
+ // floats
+ //
+ assert (r->float_ () == c->float_ ());
+ assert (r->double_ () == c->double_ ());
+ assert (r->decimal () == c->decimal ());
+
+ // strings
+ //
+ assert (r->string () == c->string ());
+ assert (r->normalized_string () == c->normalized_string ());
+ assert (r->token () == c->token ());
+ assert (r->name () == c->name ());
+ assert (r->name_token () == c->name_token ());
+ assert (r->name_tokens () == c->name_tokens ());
+ assert (r->ncname () == c->ncname ());
+ assert (r->language () == c->language ());
+
+ // qualified name
+ //
+ assert (r->qname () == c->qname ());
+
+ // ID/IDREF
+ //
+ assert (r->id () == c->id ());
+ assert (r->id_ref () == c->id_ref ());
+ assert (r->id_refs () == c->id_refs ());
+
+ // URI
+ //
+ assert (r->any_uri () == c->any_uri ());
+
+ // binary
+ //
+ assert (r->base64_binary () == c->base64_binary ());
+ assert (r->hex_binary () == c->hex_binary ());
+
+ // date/time
+ //
+ assert (r->date () == c->date ());
+ assert (r->date_time () == c->date_time ());
+ assert (r->duration () == c->duration ());
+ assert (r->day () == c->day ());
+ assert (r->month () == c->month ());
+ assert (r->month_day () == c->month_day ());
+ assert (r->year () == c->year ());
+ assert (r->year_month () == c->year_month ());
+ assert (r->time () == c->time ());
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/binary/polymorphic/makefile b/tests/cxx/tree/binary/polymorphic/makefile
new file mode 100644
index 0000000..7a4c667
--- /dev/null
+++ b/tests/cxx/tree/binary/polymorphic/makefile
@@ -0,0 +1,87 @@
+# file : tests/cxx/tree/binary/polymorphic/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+$(call import,\
+ $(scf_root)/import/libace/stub.make,\
+ l: ace.l,cpp-options: ace.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l) $(ace.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options) $(ace.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--generate-insertion ACE_OutputCDR \
+--generate-extraction ACE_InputCDR \
+--generate-polymorphic --root-element-last
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml
+ $(call message,test $$1,$$1 $(src_base)/test.xml,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/binary/polymorphic/test.xml b/tests/cxx/tree/binary/polymorphic/test.xml
new file mode 100644
index 0000000..ad3a403
--- /dev/null
+++ b/tests/cxx/tree/binary/polymorphic/test.xml
@@ -0,0 +1,92 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <list>1 2 3</list>
+
+ <union>abc</union>
+
+ <enumeration>left</enumeration>
+
+ <base x="1" xsi:type="t:complex">
+ <a>aaa</a>
+ </base>
+
+ <t:scomplex x="1" y="2">
+ <a>aaa</a>
+ <b>bbb</b>
+ <c>c</c>
+ <c>cc</c>
+ <c>ccc</c>
+ </t:scomplex>
+
+
+ <!-- integers -->
+ <byte>65</byte>
+ <unsigned_byte>66</unsigned_byte>
+ <short>-222</short>
+ <unsigned_short>57005</unsigned_short>
+ <int>-57005</int>
+ <unsigned_int>3735928559</unsigned_int>
+ <long>-3735928559</long>
+ <unsigned_long>16045690984833335023</unsigned_long>
+ <integer>-3735928559</integer>
+ <non_positive_integer>-3735928559</non_positive_integer>
+ <non_negative_integer>3735928559</non_negative_integer>
+ <positive_integer>3735928559</positive_integer>
+ <negative_integer>-3735928559</negative_integer>
+
+
+ <!-- boolean -->
+ <boolean>true</boolean>
+
+
+ <!-- floats -->
+ <float>1234.1234</float>
+ <double>12345678.12345678</double>
+ <decimal>1234567812345678.1234567812345678</decimal>
+
+
+ <!-- strings -->
+ <string>string</string>
+ <normalized_string>normalized string</normalized_string>
+ <token>one two three</token>
+ <name>name</name>
+ <name_token>name-token</name_token>
+ <name_tokens>name tokens</name_tokens>
+ <ncname>ncname</ncname>
+ <language>en-us</language>
+
+ <!-- qualified name -->
+ <qname>xsi:schemaLocation</qname>
+
+
+ <!-- ID/IDREF -->
+ <id>elements1</id>
+ <id>elements2</id>
+ <id_ref>elements1</id_ref>
+ <id_refs>elements1 elements2</id_refs>
+
+
+ <!-- URI -->
+ <any_uri>http://www.codesynthesis.com</any_uri>
+
+
+ <!-- binary -->
+ <base64_binary>YmFzZTY0IGJpbmFyeQ==</base64_binary>
+ <hex_binary>6865782052696E617279</hex_binary>
+
+
+ <!-- date/time -->
+ <date>2001-10-26+02:00</date>
+ <date_time>2001-10-26T21:32:52+02:00</date_time>
+ <duration>P1Y2M3DT5H20M30S</duration>
+ <day>---01+02:00</day>
+ <month>--11+02:00</month>
+ <month_day>--11-02+02:00</month_day>
+ <year>2001+02:00</year>
+ <year_month>2001-11+02:00</year_month>
+ <time>21:32:52+02:00</time>
+
+
+</t:root>
diff --git a/tests/cxx/tree/binary/polymorphic/test.xsd b/tests/cxx/tree/binary/polymorphic/test.xsd
new file mode 100644
index 0000000..8c214e5
--- /dev/null
+++ b/tests/cxx/tree/binary/polymorphic/test.xsd
@@ -0,0 +1,125 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:t="test"
+ targetNamespace="test">
+
+ <simpleType name="list">
+ <list itemType="int"/>
+ </simpleType>
+
+ <simpleType name="union">
+ <union memberTypes="int string"/>
+ </simpleType>
+
+ <simpleType name="enumeration">
+ <restriction base="string">
+ <enumeration value="top"/>
+ <enumeration value="left"/>
+ <enumeration value="bottom"/>
+ <enumeration value="right"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="base">
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ <attribute name="x" type="int" use="required"/>
+ </complexType>
+
+ <element name="sbase" type="t:base"/>
+
+ <complexType name="complex">
+ <complexContent>
+ <extension base="t:base">
+ <sequence>
+ <element name="b" type="string" minOccurs="0"/>
+ <element name="c" type="string" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="y" type="int"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <element name="scomplex" type="t:complex" substitutionGroup="t:sbase"/>
+
+ <complexType name="type">
+ <sequence>
+ <element name="list" type="t:list"/>
+ <element name="union" type="t:union"/>
+ <element name="enumeration" type="t:enumeration"/>
+
+ <element name="base" type="t:base"/>
+ <element ref="t:sbase"/>
+
+ <!-- integers -->
+ <element name="byte" type="byte"/>
+ <element name="unsigned_byte" type="unsignedByte"/>
+ <element name="short" type="short"/>
+ <element name="unsigned_short" type="unsignedShort"/>
+ <element name="int" type="int"/>
+ <element name="unsigned_int" type="unsignedInt"/>
+ <element name="long" type="long"/>
+ <element name="unsigned_long" type="unsignedLong"/>
+ <element name="integer" type="integer"/>
+ <element name="non_positive_integer" type="nonPositiveInteger"/>
+ <element name="non_negative_integer" type="nonNegativeInteger"/>
+ <element name="positive_integer" type="positiveInteger"/>
+ <element name="negative_integer" type="negativeInteger"/>
+
+
+ <!-- boolean -->
+ <element name="boolean" type="boolean"/>
+
+
+ <!-- floats -->
+ <element name="float" type="float"/>
+ <element name="double" type="double"/>
+ <element name="decimal" type="decimal"/>
+
+
+ <!-- strings -->
+ <element name="string" type="string"/>
+ <element name="normalized_string" type="normalizedString"/>
+ <element name="token" type="token"/>
+ <element name="name" type="Name"/>
+ <element name="name_token" type="NMTOKEN"/>
+ <element name="name_tokens" type="NMTOKENS"/>
+ <element name="ncname" type="NCName"/>
+ <element name="language" type="language"/>
+
+ <!-- qualified name -->
+ <element name="qname" type="QName"/>
+
+
+ <!-- ID/IDREF -->
+ <element name="id" maxOccurs="2" type="ID"/>
+ <element name="id_ref" type="IDREF"/>
+ <element name="id_refs" type="IDREFS"/>
+
+
+ <!-- URI -->
+ <element name="any_uri" type="anyURI"/>
+
+
+ <!-- binary -->
+ <element name="base64_binary" type="base64Binary"/>
+ <element name="hex_binary" type="hexBinary"/>
+
+
+ <!-- date/time -->
+ <element name="date" type="date"/>
+ <element name="date_time" type="dateTime"/>
+ <element name="duration" type="duration"/>
+ <element name="day" type="gDay"/>
+ <element name="month" type="gMonth"/>
+ <element name="month_day" type="gMonthDay"/>
+ <element name="year" type="gYear"/>
+ <element name="year_month" type="gYearMonth"/>
+ <element name="time" type="time"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/binary/xdr/driver.cxx b/tests/cxx/tree/binary/xdr/driver.cxx
new file mode 100644
index 0000000..787cfaf
--- /dev/null
+++ b/tests/cxx/tree/binary/xdr/driver.cxx
@@ -0,0 +1,181 @@
+// file : tests/cxx/tree/binary/xdr/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test non-polymorphic binary serialization to XDR.
+//
+
+#include <memory> // std::auto_ptr
+#include <cstring> // std::memcpy
+#include <cassert>
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+extern "C" int
+overflow (char* p, char* buf, int n)
+{
+ xml_schema::buffer* dst (reinterpret_cast<xml_schema::buffer*> (p));
+
+ std::size_t size (dst->size ());
+ dst->size (size + n);
+ memcpy (dst->data () + size, buf, n);
+
+ return n;
+}
+
+struct underflow_info
+{
+ xml_schema::buffer* buf;
+ std::size_t pos;
+};
+
+extern "C" int
+underflow (char* p, char* buf, int n)
+{
+ underflow_info* ui (reinterpret_cast<underflow_info*> (p));
+
+ std::size_t size (ui->buf->size () - ui->pos);
+ n = size > n ? n : size;
+
+ memcpy (buf, ui->buf->data () + ui->pos, n);
+ ui->pos += n;
+
+ return n;
+}
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<type> r (root (argv[1]));
+
+ // 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;
+ xsd::cxx::tree::ostream<XDR> oxdr (xdr);
+ oxdr << *r;
+ xdrrec_endofrecord (&xdr, true); // flush the data
+ xdr_destroy (&xdr);
+
+ // 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);
+ xsd::cxx::tree::istream<XDR> ixdr (xdr);
+ auto_ptr<type> c (new type (ixdr));
+ xdr_destroy (&xdr);
+
+ // Compare the two.
+ //
+ assert (r->list () == c->list ());
+ assert (r->union_ () == c->union_ ());
+ assert (r->enumeration () == c->enumeration ());
+
+ type::complex_sequence rs (r->complex ()), cs (c->complex ());
+
+ for (type::complex_iterator ri (rs.begin ()), ci (cs.begin ());
+ ri != rs.end () && ci != rs.end (); ++ri, ++ci)
+ {
+ assert (ri->a () == ci->a ());
+ if (ri->b ())
+ assert (ri->b () == ci->b ());
+ assert (ri->c () == ci->c ());
+
+ assert (ri->x () == ci->x ());
+ if (ri->y ())
+ assert (ri->y () == ci->y ());
+ }
+
+ // integers
+ //
+ assert (r->byte () == c->byte ());
+ assert (r->unsigned_byte () == c->unsigned_byte ());
+ assert (r->short_ () == c->short_ ());
+ assert (r->unsigned_short () == c->unsigned_short ());
+ assert (r->int_ () == c->int_ ());
+ assert (r->unsigned_int () == c->unsigned_int ());
+ assert (r->long_ () == c->long_ ());
+ assert (r->unsigned_long () == c->unsigned_long ());
+ assert (r->integer () == c->integer ());
+ assert (r->non_positive_integer () == c->non_positive_integer ());
+ assert (r->non_negative_integer () == c->non_negative_integer ());
+ assert (r->positive_integer () == c->positive_integer ());
+ assert (r->negative_integer () == c->negative_integer ());
+
+ // boolean
+ //
+ assert (r->boolean () == c->boolean ());
+
+ // floats
+ //
+ assert (r->float_ () == c->float_ ());
+ assert (r->double_ () == c->double_ ());
+ assert (r->decimal () == c->decimal ());
+
+ // strings
+ //
+ assert (r->string () == c->string ());
+ assert (r->normalized_string () == c->normalized_string ());
+ assert (r->token () == c->token ());
+ assert (r->name () == c->name ());
+ assert (r->name_token () == c->name_token ());
+ assert (r->name_tokens () == c->name_tokens ());
+ assert (r->ncname () == c->ncname ());
+ assert (r->language () == c->language ());
+
+ // qualified name
+ //
+ assert (r->qname () == c->qname ());
+
+ // ID/IDREF
+ //
+ assert (r->id () == c->id ());
+ assert (r->id_ref () == c->id_ref ());
+ assert (r->id_refs () == c->id_refs ());
+
+ // URI
+ //
+ assert (r->any_uri () == c->any_uri ());
+
+ // binary
+ //
+ assert (r->base64_binary () == c->base64_binary ());
+ assert (r->hex_binary () == c->hex_binary ());
+
+ // date/time
+ //
+ assert (r->date () == c->date ());
+ assert (r->date_time () == c->date_time ());
+ assert (r->duration () == c->duration ());
+ assert (r->day () == c->day ());
+ assert (r->month () == c->month ());
+ assert (r->month_day () == c->month_day ());
+ assert (r->year () == c->year ());
+ assert (r->year_month () == c->year_month ());
+ assert (r->time () == c->time ());
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/binary/xdr/makefile b/tests/cxx/tree/binary/xdr/makefile
new file mode 100644
index 0000000..23cde6b
--- /dev/null
+++ b/tests/cxx/tree/binary/xdr/makefile
@@ -0,0 +1,81 @@
+# file : tests/cxx/tree/binary/xdr/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--generate-insertion XDR --generate-extraction XDR
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml
+ $(call message,test $$1,$$1 $(src_base)/test.xml,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/binary/xdr/test.xml b/tests/cxx/tree/binary/xdr/test.xml
new file mode 100644
index 0000000..928b4cf
--- /dev/null
+++ b/tests/cxx/tree/binary/xdr/test.xml
@@ -0,0 +1,91 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <list>1 2 3</list>
+
+ <union>abc</union>
+
+ <enumeration>left</enumeration>
+
+ <complex x="1">
+ <a>aaa</a>
+ </complex>
+ <complex x="1" y="2">
+ <a>aaa</a>
+ <b>bbb</b>
+ <c>c</c>
+ <c>cc</c>
+ <c>ccc</c>
+ </complex>
+
+
+ <!-- integers -->
+ <byte>65</byte>
+ <unsigned_byte>66</unsigned_byte>
+ <short>-222</short>
+ <unsigned_short>57005</unsigned_short>
+ <int>-57005</int>
+ <unsigned_int>3735928559</unsigned_int>
+ <long>-3735928559</long>
+ <unsigned_long>16045690984833335023</unsigned_long>
+ <integer>-3735928559</integer>
+ <non_positive_integer>-3735928559</non_positive_integer>
+ <non_negative_integer>3735928559</non_negative_integer>
+ <positive_integer>3735928559</positive_integer>
+ <negative_integer>-3735928559</negative_integer>
+
+
+ <!-- boolean -->
+ <boolean>true</boolean>
+
+
+ <!-- floats -->
+ <float>1234.1234</float>
+ <double>12345678.12345678</double>
+ <decimal>1234567812345678.1234567812345678</decimal>
+
+
+ <!-- strings -->
+ <string>string</string>
+ <normalized_string>normalized string</normalized_string>
+ <token>one two three</token>
+ <name>name</name>
+ <name_token>name-token</name_token>
+ <name_tokens>name tokens</name_tokens>
+ <ncname>ncname</ncname>
+ <language>en-us</language>
+
+ <!-- qualified name -->
+ <qname>xsi:schemaLocation</qname>
+
+
+ <!-- ID/IDREF -->
+ <id>elements1</id>
+ <id>elements2</id>
+ <id_ref>elements1</id_ref>
+ <id_refs>elements1 elements2</id_refs>
+
+
+ <!-- URI -->
+ <any_uri>http://www.codesynthesis.com</any_uri>
+
+
+ <!-- binary -->
+ <base64_binary>YmFzZTY0IGJpbmFyeQ==</base64_binary>
+ <hex_binary>6865782052696E617279</hex_binary>
+
+
+ <!-- date/time -->
+ <date>2001-10-26+02:00</date>
+ <date_time>2001-10-26T21:32:52+02:00</date_time>
+ <duration>P1Y2M3DT5H20M30S</duration>
+ <day>---01+02:00</day>
+ <month>--11+02:00</month>
+ <month_day>--11-02+02:00</month_day>
+ <year>2001+02:00</year>
+ <year_month>2001-11+02:00</year_month>
+ <time>21:32:52+02:00</time>
+
+
+</t:root>
diff --git a/tests/cxx/tree/binary/xdr/test.xsd b/tests/cxx/tree/binary/xdr/test.xsd
new file mode 100644
index 0000000..e593f64
--- /dev/null
+++ b/tests/cxx/tree/binary/xdr/test.xsd
@@ -0,0 +1,120 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:t="test"
+ targetNamespace="test">
+
+ <simpleType name="list">
+ <list itemType="int"/>
+ </simpleType>
+
+ <simpleType name="union">
+ <union memberTypes="int string"/>
+ </simpleType>
+
+ <simpleType name="enumeration">
+ <restriction base="string">
+ <enumeration value="top"/>
+ <enumeration value="left"/>
+ <enumeration value="bottom"/>
+ <enumeration value="right"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="base">
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ <attribute name="x" type="int" use="required"/>
+ </complexType>
+
+ <complexType name="complex">
+ <complexContent>
+ <extension base="t:base">
+ <sequence>
+ <element name="b" type="string" minOccurs="0"/>
+ <element name="c" type="string" minOccurs="0" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="y" type="int"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+
+ <complexType name="type">
+ <sequence>
+ <element name="list" type="t:list"/>
+ <element name="union" type="t:union"/>
+ <element name="enumeration" type="t:enumeration"/>
+ <element name="complex" type="t:complex" maxOccurs="unbounded"/>
+
+ <!-- integers -->
+ <element name="byte" type="byte"/>
+ <element name="unsigned_byte" type="unsignedByte"/>
+ <element name="short" type="short"/>
+ <element name="unsigned_short" type="unsignedShort"/>
+ <element name="int" type="int"/>
+ <element name="unsigned_int" type="unsignedInt"/>
+ <element name="long" type="long"/>
+ <element name="unsigned_long" type="unsignedLong"/>
+ <element name="integer" type="integer"/>
+ <element name="non_positive_integer" type="nonPositiveInteger"/>
+ <element name="non_negative_integer" type="nonNegativeInteger"/>
+ <element name="positive_integer" type="positiveInteger"/>
+ <element name="negative_integer" type="negativeInteger"/>
+
+
+ <!-- boolean -->
+ <element name="boolean" type="boolean"/>
+
+
+ <!-- floats -->
+ <element name="float" type="float"/>
+ <element name="double" type="double"/>
+ <element name="decimal" type="decimal"/>
+
+
+ <!-- strings -->
+ <element name="string" type="string"/>
+ <element name="normalized_string" type="normalizedString"/>
+ <element name="token" type="token"/>
+ <element name="name" type="Name"/>
+ <element name="name_token" type="NMTOKEN"/>
+ <element name="name_tokens" type="NMTOKENS"/>
+ <element name="ncname" type="NCName"/>
+ <element name="language" type="language"/>
+
+ <!-- qualified name -->
+ <element name="qname" type="QName"/>
+
+
+ <!-- ID/IDREF -->
+ <element name="id" maxOccurs="2" type="ID"/>
+ <element name="id_ref" type="IDREF"/>
+ <element name="id_refs" type="IDREFS"/>
+
+
+ <!-- URI -->
+ <element name="any_uri" type="anyURI"/>
+
+
+ <!-- binary -->
+ <element name="base64_binary" type="base64Binary"/>
+ <element name="hex_binary" type="hexBinary"/>
+
+
+ <!-- date/time -->
+ <element name="date" type="date"/>
+ <element name="date_time" type="dateTime"/>
+ <element name="duration" type="duration"/>
+ <element name="day" type="gDay"/>
+ <element name="month" type="gMonth"/>
+ <element name="month_day" type="gMonthDay"/>
+ <element name="year" type="gYear"/>
+ <element name="year_month" type="gYearMonth"/>
+ <element name="time" type="time"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/built-in/attributes.xml b/tests/cxx/tree/built-in/attributes.xml
new file mode 100644
index 0000000..609a757
--- /dev/null
+++ b/tests/cxx/tree/built-in/attributes.xml
@@ -0,0 +1,73 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<test:attributes
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/xmlns/test types.xsd"
+
+
+ byte="65"
+ unsigned_byte="66"
+ short="-222"
+ unsigned_short="57005"
+ int="-57005"
+ unsigned_int="3735928559"
+ long="-3735928559"
+ unsigned_long="16045690984833335023"
+ integer="-3735928559"
+ non_positive_integer="-3735928559"
+ non_negative_integer="3735928559"
+ positive_integer="3735928559"
+ negative_integer="-3735928559"
+
+
+
+ boolean="false"
+
+
+
+ float="1234.1234"
+ double="12345678.12345678"
+ decimal="12345678.12345678"
+
+
+
+ string="string"
+ normalized_string="normalized string"
+ token=" one two three "
+ name="name"
+ name_token="name-token"
+ name_tokens="name tokens"
+ ncname="ncname"
+ language="en-us"
+
+
+ qname="xsi:schemaLocation"
+
+
+
+ id="attributes"
+ id_ref="attributes"
+ id_refs="attributes"
+
+
+
+ any_uri="http://www.codesynthesis.com"
+
+
+
+ base64_binary="YmFzZTY0IGJpbmFyeQ=="
+ hex_binary="6865782052696E617279"
+
+
+
+ date="2001-10-26+02:00"
+ date_time="2001-10-26T21:32:52+02:00"
+ duration="P1Y2M3DT5H20M30S"
+ day="---01+02:00"
+ month="--11+02:00"
+ month_day="--11-02+02:00"
+ year="2001+02:00"
+ year_month="2001-11+02:00"
+ time="21:32:52+02:00"
+
+/>
diff --git a/tests/cxx/tree/built-in/driver.cxx b/tests/cxx/tree/built-in/driver.cxx
new file mode 100644
index 0000000..f3138aa
--- /dev/null
+++ b/tests/cxx/tree/built-in/driver.cxx
@@ -0,0 +1,94 @@
+// file : tests/cxx/tree/built-in/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test built-in type mapping.
+//
+
+#include <memory> // std::auto_ptr
+#include <sstream>
+#include <iostream>
+
+
+#include "types.hxx"
+
+using std::cerr;
+using std::endl;
+using std::auto_ptr;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 4)
+ {
+ cerr << "usage: " << argv[0] << " elements.xml attributes.xml inherited.xml" << endl;
+ return 1;
+ }
+
+ auto_ptr<xmlns::test::Elements> elements (xmlns::test::elements (argv[1]));
+
+ auto_ptr<xmlns::test::Attributes> attributes (
+ xmlns::test::attributes (argv[2]));
+
+ auto_ptr<xmlns::test::Inherited> inherited (
+ xmlns::test::inherited (argv[3]));
+
+ cerr << "elements: " << *elements << endl
+ << endl
+ << "attributes: " << *attributes << endl
+ << endl
+ << "inherited: " << *inherited << endl;
+
+ // Test parsing/serialization.
+ //
+
+ xml_schema::namespace_infomap map;
+
+ map["test"].name = "http://www.codesynthesis.com/xmlns/test";
+ map["test"].schema = "types.xsd";
+
+ {
+ std::ostringstream ostr;
+ xmlns::test::elements (ostr, *elements, map);
+
+ std::istringstream istr (ostr.str ());
+ auto_ptr<xmlns::test::Elements> elements1 (xmlns::test::elements (istr));
+
+ std::ostringstream ostr1;
+ xmlns::test::elements (ostr1, *elements1, map);
+
+ if (ostr.str () != ostr1.str ())
+ return 1;
+ }
+
+ {
+ std::ostringstream ostr;
+ xmlns::test::attributes (ostr, *attributes, map);
+
+ std::istringstream istr (ostr.str ());
+ auto_ptr<xmlns::test::Attributes> attributes1 (
+ xmlns::test::attributes (istr));
+
+ std::ostringstream ostr1;
+ xmlns::test::attributes (ostr1, *attributes1, map);
+
+ if (ostr.str () != ostr1.str ())
+ return 1;
+ }
+
+ {
+ std::ostringstream ostr;
+ xmlns::test::inherited (ostr, *inherited, map);
+
+ std::istringstream istr (ostr.str ());
+ auto_ptr<xmlns::test::Inherited> inherited1 (
+ xmlns::test::inherited (istr));
+
+ std::ostringstream ostr1;
+ xmlns::test::inherited (ostr1, *inherited1, map);
+
+ if (ostr.str () != ostr1.str ())
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/built-in/elements.xml b/tests/cxx/tree/built-in/elements.xml
new file mode 100644
index 0000000..f76f019
--- /dev/null
+++ b/tests/cxx/tree/built-in/elements.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<test:elements
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/xmlns/test types.xsd">
+
+ <!-- integers -->
+ <byte>65</byte>
+ <unsigned_byte>66</unsigned_byte>
+ <short>-222</short>
+ <unsigned_short>57005</unsigned_short>
+ <int>-57005</int>
+ <unsigned_int>3735928559</unsigned_int>
+ <long>-3735928559</long>
+ <unsigned_long>16045690984833335023</unsigned_long>
+ <integer>-3735928559</integer>
+ <non_positive_integer>-3735928559</non_positive_integer>
+ <non_negative_integer>3735928559</non_negative_integer>
+ <positive_integer>3735928559</positive_integer>
+ <negative_integer>-3735928559</negative_integer>
+
+
+ <!-- boolean -->
+ <boolean>true</boolean>
+
+
+ <!-- floats -->
+ <float>1234.1234</float>
+ <double>12345678.12345678</double>
+ <decimal>12345678.12345678</decimal>
+
+
+ <!-- strings -->
+ <string>string</string>
+ <normalized_string>normalized
+string</normalized_string>
+ <token>
+ one
+ two three </token>
+ <name>name</name>
+ <name_token>name-token</name_token>
+ <name_tokens>name tokens</name_tokens>
+ <ncname>ncname</ncname>
+ <language>en-us</language>
+
+ <!-- qualified name -->
+ <qname>xsi:schemaLocation</qname>
+
+
+ <!-- ID/IDREF -->
+ <id>elements1</id>
+ <id>elements2</id>
+ <id_ref>elements1</id_ref>
+ <id_refs>elements1 elements2</id_refs>
+
+
+ <!-- URI -->
+ <any_uri>http://www.codesynthesis.com</any_uri>
+
+
+ <!-- binary -->
+ <base64_binary>YmFzZTY0IGJpbmFyeQ==</base64_binary>
+ <hex_binary>6865782052696E617279</hex_binary>
+
+
+ <!-- date/time -->
+ <date>2001-10-26+02:00</date>
+ <date_time>2001-10-26T21:32:52+02:00</date_time>
+ <duration>P1Y2M3DT5H20M30S</duration>
+ <day>---01+02:00</day>
+ <month>--11+02:00</month>
+ <month_day>--11-02+02:00</month_day>
+ <year>2001+02:00</year>
+ <year_month>2001-11+02:00</year_month>
+ <time>21:32:52+02:00</time>
+
+
+ <!-- entity -->
+ <!--
+ <entity>foo</entity>
+ <entities>foo bar</entities>
+ -->
+
+</test:elements>
diff --git a/tests/cxx/tree/built-in/inherited.xml b/tests/cxx/tree/built-in/inherited.xml
new file mode 100644
index 0000000..1781a69
--- /dev/null
+++ b/tests/cxx/tree/built-in/inherited.xml
@@ -0,0 +1,84 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<test:inherited
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.codesynthesis.com/xmlns/test types.xsd">
+
+ <!-- integers -->
+ <byte>65</byte>
+ <unsigned_byte>66</unsigned_byte>
+ <short>-222</short>
+ <unsigned_short>57005</unsigned_short>
+ <int>-57005</int>
+ <unsigned_int>3735928559</unsigned_int>
+ <long>-3735928559</long>
+ <unsigned_long>16045690984833335023</unsigned_long>
+ <integer>-3735928559</integer>
+ <non_positive_integer>-3735928559</non_positive_integer>
+ <non_negative_integer>3735928559</non_negative_integer>
+ <positive_integer>3735928559</positive_integer>
+ <negative_integer>-3735928559</negative_integer>
+
+
+ <!-- boolean -->
+ <boolean>true</boolean>
+
+
+ <!-- floats -->
+ <float>1234.1234</float>
+ <double>12345678.12345678</double>
+ <decimal>12345678.12345678</decimal>
+
+
+ <!-- strings -->
+ <string>string</string>
+ <normalized_string>normalized
+string</normalized_string>
+ <token>
+ one
+ two three </token>
+ <name>name</name>
+ <name_token>name-token</name_token>
+ <name_tokens>name tokens</name_tokens>
+ <ncname>ncname</ncname>
+ <language>en-us</language>
+
+ <!-- qualified name -->
+ <qname>xsi:schemaLocation</qname>
+
+
+ <!-- ID/IDREF -->
+ <id>elements1</id>
+ <id>elements2</id>
+ <id_ref>elements1</id_ref>
+ <id_refs>elements1 elements2</id_refs>
+
+
+ <!-- URI -->
+ <any_uri>http://www.codesynthesis.com</any_uri>
+
+
+ <!-- binary -->
+ <base64_binary>YmFzZTY0IGJpbmFyeQ==</base64_binary>
+ <hex_binary>6865782052696E617279</hex_binary>
+
+
+ <!-- date/time -->
+ <date>2001-10-26+02:00</date>
+ <date_time>2001-10-26T21:32:52+02:00</date_time>
+ <duration>P1Y2M3DT5H20M30S</duration>
+ <day>---01+02:00</day>
+ <month>--11+02:00</month>
+ <month_day>--11-02+02:00</month_day>
+ <year>2001+02:00</year>
+ <year_month>2001-11+02:00</year_month>
+ <time>21:32:52+02:00</time>
+
+
+ <!-- entity -->
+ <!--
+ <entity>foo</entity>
+ <entities>foo bar</entities>
+ -->
+
+</test:inherited>
diff --git a/tests/cxx/tree/built-in/makefile b/tests/cxx/tree/built-in/makefile
new file mode 100644
index 0000000..028d18d
--- /dev/null
+++ b/tests/cxx/tree/built-in/makefile
@@ -0,0 +1,93 @@
+# file : tests/cxx/tree/built-in/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := types.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --char-type char \
+ --generate-inline \
+ --generate-ostream \
+ --generate-serialization \
+ --generate-default-ctor \
+ --generate-from-base-ctor \
+ --root-element-all
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(src_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+# We need to cd to src_base in order to have the schema in the working
+# directory.
+#
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/elements.xml $(src_base)/attributes.xml \
+$(src_base)/inherited.xml
+ cd $(src_base) && $(driver) $(src_base)/elements.xml \
+$(src_base)/attributes.xml $(src_base)/inherited.xml
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/built-in/types.xsd b/tests/cxx/tree/built-in/types.xsd
new file mode 100644
index 0000000..22582cb
--- /dev/null
+++ b/tests/cxx/tree/built-in/types.xsd
@@ -0,0 +1,460 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- elements -->
+
+ <xsd:complexType name="Elements">
+ <xsd:sequence>
+
+ <!-- integers -->
+ <xsd:element name="byte" type="xsd:byte"/>
+ <xsd:element name="unsigned_byte" type="xsd:unsignedByte"/>
+ <xsd:element name="short" type="xsd:short"/>
+ <xsd:element name="unsigned_short" type="xsd:unsignedShort"/>
+ <xsd:element name="int" type="xsd:int"/>
+ <xsd:element name="unsigned_int" type="xsd:unsignedInt"/>
+ <xsd:element name="long" type="xsd:long"/>
+ <xsd:element name="unsigned_long" type="xsd:unsignedLong"/>
+ <xsd:element name="integer" type="xsd:integer"/>
+ <xsd:element name="non_positive_integer" type="xsd:nonPositiveInteger"/>
+ <xsd:element name="non_negative_integer" type="xsd:nonNegativeInteger"/>
+ <xsd:element name="positive_integer" type="xsd:positiveInteger"/>
+ <xsd:element name="negative_integer" type="xsd:negativeInteger"/>
+
+
+ <!-- boolean -->
+ <xsd:element name="boolean" type="xsd:boolean"/>
+
+
+ <!-- floats -->
+ <xsd:element name="float" type="xsd:float"/>
+ <xsd:element name="double" type="xsd:double"/>
+ <xsd:element name="decimal" type="xsd:decimal"/>
+
+
+ <!-- strings -->
+ <xsd:element name="string" type="xsd:string"/>
+ <xsd:element name="normalized_string" type="xsd:normalizedString"/>
+ <xsd:element name="token" type="xsd:token"/>
+ <xsd:element name="name" type="xsd:Name"/>
+ <xsd:element name="name_token" type="xsd:NMTOKEN"/>
+ <xsd:element name="name_tokens" type="xsd:NMTOKENS"/>
+ <xsd:element name="ncname" type="xsd:NCName"/>
+ <xsd:element name="language" type="xsd:language"/>
+
+ <!-- qualified name -->
+ <xsd:element name="qname" type="xsd:QName"/>
+
+
+ <!-- ID/IDREF -->
+ <xsd:element name="id" maxOccurs="2" type="xsd:ID"/>
+ <xsd:element name="id_ref" type="xsd:IDREF"/>
+ <xsd:element name="id_refs" type="xsd:IDREFS"/>
+
+
+ <!-- URI -->
+ <xsd:element name="any_uri" type="xsd:anyURI"/>
+
+
+ <!-- binary -->
+ <xsd:element name="base64_binary" type="xsd:base64Binary"/>
+ <xsd:element name="hex_binary" type="xsd:hexBinary"/>
+
+
+ <!-- date/time -->
+ <xsd:element name="date" type="xsd:date"/>
+ <xsd:element name="date_time" type="xsd:dateTime"/>
+ <xsd:element name="duration" type="xsd:duration"/>
+ <xsd:element name="day" type="xsd:gDay"/>
+ <xsd:element name="month" type="xsd:gMonth"/>
+ <xsd:element name="month_day" type="xsd:gMonthDay"/>
+ <xsd:element name="year" type="xsd:gYear"/>
+ <xsd:element name="year_month" type="xsd:gYearMonth"/>
+ <xsd:element name="time" type="xsd:time"/>
+
+
+ <!-- entity -->
+ <!--
+ <xsd:element name="entity" type="xsd:ENTITY"/>
+ <xsd:element name="entities" type="xsd:ENTITIES"/>
+ -->
+
+
+ <!-- notation -->
+ <!-- xsd:element name="notation" type="xsd:NOTATION"/ -->
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="elements" type="Elements"/>
+
+
+
+ <!-- attributes -->
+
+ <xsd:complexType name="Attributes">
+ <!-- integers -->
+ <xsd:attribute name="byte" type="xsd:byte"/>
+ <xsd:attribute name="unsigned_byte" type="xsd:unsignedByte"/>
+ <xsd:attribute name="short" type="xsd:short"/>
+ <xsd:attribute name="unsigned_short" type="xsd:unsignedShort"/>
+ <xsd:attribute name="int" type="xsd:int"/>
+ <xsd:attribute name="unsigned_int" type="xsd:unsignedInt"/>
+ <xsd:attribute name="long" type="xsd:long"/>
+ <xsd:attribute name="unsigned_long" type="xsd:unsignedLong"/>
+ <xsd:attribute name="integer" type="xsd:integer"/>
+ <xsd:attribute name="non_positive_integer" type="xsd:nonPositiveInteger"/>
+ <xsd:attribute name="non_negative_integer" type="xsd:nonNegativeInteger"/>
+ <xsd:attribute name="positive_integer" type="xsd:positiveInteger"/>
+ <xsd:attribute name="negative_integer" type="xsd:negativeInteger"/>
+
+
+ <!-- boolean -->
+ <xsd:attribute name="boolean" type="xsd:boolean"/>
+
+
+ <!-- floats -->
+ <xsd:attribute name="float" type="xsd:float"/>
+ <xsd:attribute name="double" type="xsd:double"/>
+ <xsd:attribute name="decimal" type="xsd:decimal"/>
+
+
+ <!-- strings -->
+ <xsd:attribute name="string" type="xsd:string"/>
+ <xsd:attribute name="normalized_string" type="xsd:normalizedString"/>
+ <xsd:attribute name="token" type="xsd:token"/>
+ <xsd:attribute name="name" type="xsd:Name"/>
+ <xsd:attribute name="name_token" type="xsd:NMTOKEN"/>
+ <xsd:attribute name="name_tokens" type="xsd:NMTOKENS"/>
+ <xsd:attribute name="ncname" type="xsd:NCName"/>
+ <xsd:attribute name="language" type="xsd:language"/>
+
+ <!-- qualified name -->
+ <xsd:attribute name="qname" type="xsd:QName"/>
+
+
+ <!-- ID/IDREF -->
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:attribute name="id_ref" type="xsd:IDREF"/>
+ <xsd:attribute name="id_refs" type="xsd:IDREFS"/>
+
+
+ <!-- URI -->
+ <xsd:attribute name="any_uri" type="xsd:anyURI"/>
+
+
+ <!-- binary -->
+ <xsd:attribute name="base64_binary" type="xsd:base64Binary"/>
+ <xsd:attribute name="hex_binary" type="xsd:hexBinary"/>
+
+
+ <!-- date/time -->
+ <xsd:attribute name="date" type="xsd:date"/>
+ <xsd:attribute name="date_time" type="xsd:dateTime"/>
+ <xsd:attribute name="duration" type="xsd:duration"/>
+ <xsd:attribute name="day" type="xsd:gDay"/>
+ <xsd:attribute name="month" type="xsd:gMonth"/>
+ <xsd:attribute name="month_day" type="xsd:gMonthDay"/>
+ <xsd:attribute name="year" type="xsd:gYear"/>
+ <xsd:attribute name="year_month" type="xsd:gYearMonth"/>
+ <xsd:attribute name="time" type="xsd:time"/>
+
+
+ <!-- entity -->
+ <!--
+ <xsd:attribute name="entity" type="xsd:ENTITY"/>
+ <xsd:attribute name="entities" type="xsd:ENTITIES"/>
+ -->
+
+
+ <!-- notation -->
+ <!-- xsd:element name="notation" type="xsd:NOTATION"/ -->
+ </xsd:complexType>
+
+ <xsd:element name="attributes" type="Attributes"/>
+
+
+ <!-- inheritance -->
+
+ <!-- integers -->
+ <xsd:simpleType name="Byte">
+ <xsd:restriction base="xsd:byte"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="UnsignedByte">
+ <xsd:restriction base="xsd:unsignedByte"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Short">
+ <xsd:restriction base="xsd:short"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="UnsignedShort">
+ <xsd:restriction base="xsd:unsignedShort"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Int">
+ <xsd:restriction base="xsd:int"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="UnsignedInt">
+ <xsd:restriction base="xsd:unsignedInt"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Long">
+ <xsd:restriction base="xsd:long"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="UnsignedLong">
+ <xsd:restriction base="xsd:unsignedLong"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Integer">
+ <xsd:restriction base="xsd:integer"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="NonPositiveInteger">
+ <xsd:restriction base="xsd:nonPositiveInteger"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="NonNegativeInteger">
+ <xsd:restriction base="xsd:nonNegativeInteger"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="PositiveInteger">
+ <xsd:restriction base="xsd:positiveInteger"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="NegativeInteger">
+ <xsd:restriction base="xsd:negativeInteger"/>
+ </xsd:simpleType>
+
+
+ <!-- boolean -->
+ <xsd:simpleType name="Boolean">
+ <xsd:restriction base="xsd:boolean"/>
+ </xsd:simpleType>
+
+
+ <!-- floats -->
+ <xsd:simpleType name="Float">
+ <xsd:restriction base="xsd:float"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Double">
+ <xsd:restriction base="xsd:double"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Decimal">
+ <xsd:restriction base="xsd:decimal"/>
+ </xsd:simpleType>
+
+
+ <!-- strings -->
+ <xsd:simpleType name="String">
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="NormalizedString">
+ <xsd:restriction base="xsd:normalizedString"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Token">
+ <xsd:restriction base="xsd:token"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Name">
+ <xsd:restriction base="xsd:Name"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="NameToken">
+ <xsd:restriction base="xsd:NMTOKEN"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="NameTokens">
+ <xsd:restriction base="xsd:NMTOKENS"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="NCName">
+ <xsd:restriction base="xsd:NCName"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Language">
+ <xsd:restriction base="xsd:language"/>
+ </xsd:simpleType>
+
+
+ <!-- qualified name -->
+ <xsd:simpleType name="QName">
+ <xsd:restriction base="xsd:QName"/>
+ </xsd:simpleType>
+
+
+ <!-- ID/IDREF -->
+ <xsd:simpleType name="Id">
+ <xsd:restriction base="xsd:ID"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="IdRef">
+ <xsd:restriction base="xsd:IDREF"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="IdRefs">
+ <xsd:restriction base="xsd:IDREFS"/>
+ </xsd:simpleType>
+
+
+ <!-- URI -->
+ <xsd:simpleType name="URI">
+ <xsd:restriction base="xsd:anyURI"/>
+ </xsd:simpleType>
+
+
+ <!-- binary -->
+ <xsd:simpleType name="Base64Binary">
+ <xsd:restriction base="xsd:base64Binary"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="HexBinary">
+ <xsd:restriction base="xsd:hexBinary"/>
+ </xsd:simpleType>
+
+
+ <!-- date/time -->
+ <xsd:simpleType name="Date">
+ <xsd:restriction base="xsd:date"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="DateTime">
+ <xsd:restriction base="xsd:dateTime"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Duration">
+ <xsd:restriction base="xsd:duration"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Day">
+ <xsd:restriction base="xsd:gDay"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Month">
+ <xsd:restriction base="xsd:gMonth"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="MonthDay">
+ <xsd:restriction base="xsd:gMonthDay"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Year">
+ <xsd:restriction base="xsd:gYear"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="YearMonth">
+ <xsd:restriction base="xsd:gYearMonth"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="Time">
+ <xsd:restriction base="xsd:time"/>
+ </xsd:simpleType>
+
+
+ <!-- entity -->
+ <!--
+ <xsd:element name="entity" type="xsd:ENTITY"/>
+ <xsd:element name="entities" type="xsd:ENTITIES"/>
+ -->
+
+
+ <!-- notation -->
+ <!-- xsd:element name="notation" type="xsd:NOTATION"/ -->
+
+ <!-- elements -->
+
+ <xsd:complexType name="Inherited">
+ <xsd:sequence>
+
+ <!-- integers -->
+ <xsd:element name="byte" type="Byte"/>
+ <xsd:element name="unsigned_byte" type="UnsignedByte"/>
+ <xsd:element name="short" type="Short"/>
+ <xsd:element name="unsigned_short" type="UnsignedShort"/>
+ <xsd:element name="int" type="Int"/>
+ <xsd:element name="unsigned_int" type="UnsignedInt"/>
+ <xsd:element name="long" type="Long"/>
+ <xsd:element name="unsigned_long" type="UnsignedLong"/>
+ <xsd:element name="integer" type="Integer"/>
+ <xsd:element name="non_positive_integer" type="NonPositiveInteger"/>
+ <xsd:element name="non_negative_integer" type="NonNegativeInteger"/>
+ <xsd:element name="positive_integer" type="PositiveInteger"/>
+ <xsd:element name="negative_integer" type="NegativeInteger"/>
+
+
+ <!-- boolean -->
+ <xsd:element name="boolean" type="Boolean"/>
+
+
+ <!-- floats -->
+ <xsd:element name="float" type="Float"/>
+ <xsd:element name="double" type="Double"/>
+ <xsd:element name="decimal" type="Decimal"/>
+
+
+ <!-- strings -->
+ <xsd:element name="string" type="String"/>
+ <xsd:element name="normalized_string" type="NormalizedString"/>
+ <xsd:element name="token" type="Token"/>
+ <xsd:element name="name" type="Name"/>
+ <xsd:element name="name_token" type="NameToken"/>
+ <xsd:element name="name_tokens" type="NameTokens"/>
+ <xsd:element name="ncname" type="NCName"/>
+ <xsd:element name="language" type="Language"/>
+
+ <!-- qualified name -->
+ <xsd:element name="qname" type="QName"/>
+
+
+ <!-- ID/IDREF -->
+ <xsd:element name="id" maxOccurs="2" type="Id"/>
+ <xsd:element name="id_ref" type="IdRef"/>
+ <xsd:element name="id_refs" type="IdRefs"/>
+
+
+ <!-- URI -->
+ <xsd:element name="any_uri" type="URI"/>
+
+
+ <!-- binary -->
+ <xsd:element name="base64_binary" type="Base64Binary"/>
+ <xsd:element name="hex_binary" type="HexBinary"/>
+
+
+ <!-- date/time -->
+ <xsd:element name="date" type="Date"/>
+ <xsd:element name="date_time" type="DateTime"/>
+ <xsd:element name="duration" type="Duration"/>
+ <xsd:element name="day" type="Day"/>
+ <xsd:element name="month" type="Month"/>
+ <xsd:element name="month_day" type="MonthDay"/>
+ <xsd:element name="year" type="Year"/>
+ <xsd:element name="year_month" type="YearMonth"/>
+ <xsd:element name="time" type="Time"/>
+
+
+ <!-- entity -->
+ <!--
+ <xsd:element name="entity" type="xsd:ENTITY"/>
+ <xsd:element name="entities" type="xsd:ENTITIES"/>
+ -->
+
+
+ <!-- notation -->
+ <!-- xsd:element name="notation" type="xsd:NOTATION"/ -->
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="inherited" type="Inherited"/>
+
+</xsd:schema>
diff --git a/tests/cxx/tree/chameleon/driver.cxx b/tests/cxx/tree/chameleon/driver.cxx
new file mode 100644
index 0000000..944b486
--- /dev/null
+++ b/tests/cxx/tree/chameleon/driver.cxx
@@ -0,0 +1,37 @@
+// file : tests/cxx/tree/chameleon/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test chameleon inclusion.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "includer.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<root_t> r (root (argv[1]));
+
+ cout << *r << endl;
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/chameleon/includee.xsd b/tests/cxx/tree/chameleon/includee.xsd
new file mode 100644
index 0000000..531a7d0
--- /dev/null
+++ b/tests/cxx/tree/chameleon/includee.xsd
@@ -0,0 +1,13 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <xsd:complexType name="root_t">
+ <xsd:sequence>
+ <xsd:element name="a" type="type"/>
+ <xsd:element ref="b"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="root" type="root_t"/>
+
+</xsd:schema>
diff --git a/tests/cxx/tree/chameleon/includer.xsd b/tests/cxx/tree/chameleon/includer.xsd
new file mode 100644
index 0000000..a1c850a
--- /dev/null
+++ b/tests/cxx/tree/chameleon/includer.xsd
@@ -0,0 +1,12 @@
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns="test" targetNamespace="test">
+
+ <xsd:include schemaLocation="includee.xsd"/>
+
+ <xsd:simpleType name="type">
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+ <xsd:element name="b" type="xsd:string"/>
+
+</xsd:schema>
diff --git a/tests/cxx/tree/chameleon/makefile b/tests/cxx/tree/chameleon/makefile
new file mode 100644
index 0000000..bd7aa2c
--- /dev/null
+++ b/tests/cxx/tree/chameleon/makefile
@@ -0,0 +1,82 @@
+# file : tests/cxx/tree/chameleon/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := includer.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --root-element root \
+--generate-ostream
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/chameleon/output b/tests/cxx/tree/chameleon/output
new file mode 100644
index 0000000..c40f715
--- /dev/null
+++ b/tests/cxx/tree/chameleon/output
@@ -0,0 +1,3 @@
+
+a: a
+b: b
diff --git a/tests/cxx/tree/chameleon/test.xml b/tests/cxx/tree/chameleon/test.xml
new file mode 100644
index 0000000..12ff279
--- /dev/null
+++ b/tests/cxx/tree/chameleon/test.xml
@@ -0,0 +1,8 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test includer.xsd">
+
+ <a>a</a>
+ <t:b>b</t:b>
+
+</t:root>
diff --git a/tests/cxx/tree/comparison/driver.cxx b/tests/cxx/tree/comparison/driver.cxx
new file mode 100644
index 0000000..eda2b59
--- /dev/null
+++ b/tests/cxx/tree/comparison/driver.cxx
@@ -0,0 +1,40 @@
+// file : tests/cxx/tree/comparison/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test generated comparison operators.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<type> r (root (argv[1]));
+
+ type::complex_sequence s (r->complex ());
+
+ assert (s[0] == s[0]);
+ assert (s[0] != s[1]);
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/comparison/makefile b/tests/cxx/tree/comparison/makefile
new file mode 100644
index 0000000..ac4ad8c
--- /dev/null
+++ b/tests/cxx/tree/comparison/makefile
@@ -0,0 +1,81 @@
+# file : tests/cxx/tree/comparison/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-comparison
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml
+ $(call message,test $$1,$$1 $(src_base)/test.xml,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/comparison/test.xml b/tests/cxx/tree/comparison/test.xml
new file mode 100644
index 0000000..b5d8158
--- /dev/null
+++ b/tests/cxx/tree/comparison/test.xml
@@ -0,0 +1,19 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <complex x="123" y="abc">
+ <a>123</a>
+ <b>abc</b>
+ <c x="123">abc</c>
+ <c x="456">def</c>
+ </complex>
+
+ <complex x="123" y="abc">
+ <a>123</a>
+ <b>abc</b>
+ <c x="123">abc</c>
+ <c x="456">xyz</c>
+ </complex>
+
+</t:root>
diff --git a/tests/cxx/tree/comparison/test.xsd b/tests/cxx/tree/comparison/test.xsd
new file mode 100644
index 0000000..c234add
--- /dev/null
+++ b/tests/cxx/tree/comparison/test.xsd
@@ -0,0 +1,30 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="member">
+ <simpleContent>
+ <extension base="string">
+ <attribute name="x" type="int" use="required"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="complex">
+ <sequence>
+ <element name="a" type="int"/>
+ <element name="b" type="string" minOccurs="0"/>
+ <element name="c" type="t:member" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="x" type="int"/>
+ <attribute name="y" type="string" use="required"/>
+ </complexType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="complex" type="t:complex" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/compilation/driver.cxx b/tests/cxx/tree/compilation/driver.cxx
new file mode 100644
index 0000000..bb9f8cb
--- /dev/null
+++ b/tests/cxx/tree/compilation/driver.cxx
@@ -0,0 +1,119 @@
+// file : tests/cxx/tree/compilation/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Make sure the runtime library compiles by explicitly instantiating
+// all the types.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+template class xsd::cxx::tree::simple_type<xml_schema::type>;
+
+// String types.
+//
+template class xsd::cxx::tree::string< char, xml_schema::simple_type >;
+template class xsd::cxx::tree::normalized_string< char, xml_schema::string >;
+template class xsd::cxx::tree::token< char, xml_schema::normalized_string >;
+template class xsd::cxx::tree::name< char, xml_schema::token >;
+template class xsd::cxx::tree::nmtoken< char, xml_schema::token >;
+template class xsd::cxx::tree::nmtokens< char, xml_schema::simple_type, xml_schema::nmtoken >;
+template class xsd::cxx::tree::ncname< char, xml_schema::name >;
+template class xsd::cxx::tree::language< char, xml_schema::token >;
+
+// ID/IDREF.
+//
+template class xsd::cxx::tree::id< char, xml_schema::ncname >;
+template class xsd::cxx::tree::idref< xml_schema::type, char, xml_schema::ncname >;
+template class xsd::cxx::tree::idrefs< char, xml_schema::simple_type, xml_schema::idref >;
+
+// URI.
+//
+template class xsd::cxx::tree::uri< char, xml_schema::simple_type >;
+
+// Qualified name.
+//
+template class xsd::cxx::tree::qname< char, xml_schema::simple_type, xml_schema::uri, xml_schema::ncname >;
+
+// Binary.
+//
+template class xsd::cxx::tree::buffer< char >;
+template class xsd::cxx::tree::base64_binary< char, xml_schema::simple_type >;
+template class xsd::cxx::tree::hex_binary< char, xml_schema::simple_type >;
+
+// Date/time.
+//
+template class xsd::cxx::tree::date< char, xml_schema::simple_type >;
+template class xsd::cxx::tree::date_time< char, xml_schema::simple_type >;
+template class xsd::cxx::tree::duration< char, xml_schema::simple_type >;
+template class xsd::cxx::tree::gday< char, xml_schema::simple_type >;
+template class xsd::cxx::tree::gmonth< char, xml_schema::simple_type >;
+template class xsd::cxx::tree::gmonth_day< char, xml_schema::simple_type >;
+template class xsd::cxx::tree::gyear< char, xml_schema::simple_type >;
+template class xsd::cxx::tree::gyear_month< char, xml_schema::simple_type >;
+template class xsd::cxx::tree::time< char, xml_schema::simple_type >;
+
+// Entity.
+//
+template class xsd::cxx::tree::entity< char, xml_schema::ncname >;
+template class xsd::cxx::tree::entities< char, xml_schema::simple_type, xml_schema::entity >;
+
+// Namespace information and list stream. Used in
+// serialization functions.
+//
+template class xsd::cxx::xml::dom::namespace_info < char >;
+template class xsd::cxx::xml::dom::namespace_infomap < char >;
+template class xsd::cxx::tree::list_stream < char >;
+
+// Flags and properties.
+//
+template class xsd::cxx::tree::properties< char >;
+
+// Exceptions.
+//
+template class xsd::cxx::tree::exception< char >;
+template class xsd::cxx::tree::parsing< char >;
+template class xsd::cxx::tree::expected_element< char >;
+template class xsd::cxx::tree::unexpected_element< char >;
+template class xsd::cxx::tree::expected_attribute< char >;
+template class xsd::cxx::tree::unexpected_enumerator< char >;
+template class xsd::cxx::tree::expected_text_content< char >;
+template class xsd::cxx::tree::no_type_info< char >;
+template class xsd::cxx::tree::not_derived< char >;
+template class xsd::cxx::tree::duplicate_id< char >;
+template class xsd::cxx::tree::serialization< char >;
+template class xsd::cxx::tree::no_prefix_mapping< char >;
+template class xsd::cxx::tree::bounds< char >;
+
+// Parsing/serialization diagnostics.
+//
+template class xsd::cxx::tree::error< char >;
+template class xsd::cxx::tree::diagnostics< char >;
+
+// Error handler interface.
+//
+template class xsd::cxx::xml::error_handler< char >;
+
+
+//
+//
+template class xsd::cxx::tree::fundamental_base<int, char, xml_schema::type>;
+template class xsd::cxx::tree::one<int>;
+template class xsd::cxx::tree::one<xml_schema::string>;
+template class xsd::cxx::tree::optional<int>;
+template class xsd::cxx::tree::optional<xml_schema::string>;
+template class xsd::cxx::tree::sequence<int>;
+template class xsd::cxx::tree::sequence<xml_schema::string>;
+
+
+int
+main ()
+{
+}
diff --git a/tests/cxx/tree/compilation/makefile b/tests/cxx/tree/compilation/makefile
new file mode 100644
index 0000000..fcb6e15
--- /dev/null
+++ b/tests/cxx/tree/compilation/makefile
@@ -0,0 +1,81 @@
+# file : tests/cxx/tree/compilation/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-serialization
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/compilation/test.xsd b/tests/cxx/tree/compilation/test.xsd
new file mode 100644
index 0000000..07bebc7
--- /dev/null
+++ b/tests/cxx/tree/compilation/test.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="type">
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/complex/ctor/driver.cxx b/tests/cxx/tree/complex/ctor/driver.cxx
new file mode 100644
index 0000000..a46bac8
--- /dev/null
+++ b/tests/cxx/tree/complex/ctor/driver.cxx
@@ -0,0 +1,112 @@
+// file : tests/cxx/tree/complex/ctor/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test generation of varous complex type constructors.
+//
+
+#include <cassert>
+#include <memory>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main ()
+{
+ // Test case A.
+ //
+ {
+ a_base b1;
+ a_base b2 ("abc"); // empty ultimate base + required
+ a_base b3 ("abc", "foo"); // ultimate base + required
+
+ a_derived a1;
+ a_derived a2 ("foo", "bar"); // empty ultimate base + required
+ a_derived a3 (b3, "bar"); // base + required
+ a_derived a4 ("abc", "foo", "bar"); // ultimate base + required
+ }
+
+ // Test case B.
+ //
+ {
+ b_simple s ("base");
+ b_base b ("base", "foo");
+ b_derived d ("base", "foo", "bar");
+ b_type t ("base");
+ }
+
+ // Test case C.
+ //
+ {
+ c_simple s (c_enum::a);
+ c_base b (c_enum::a, "foo");
+ c_derived d (c_enum::a, "foo", "bar");
+ c_type t (c_enum::a);
+ }
+
+ // Test case D.
+ //
+ {
+ d_simple s (1);
+ d_base b (1, "foo");
+ d_derived d (1, "foo", "bar");
+ d_type t (1);
+ }
+
+ // Test case E.
+ //
+ {
+ // e_base
+ //
+ e_base b1 (1, "foo", e_complex_type ("bar"));
+
+ auto_ptr<e_complex_type> c2 (new e_complex_type ("bar"));
+ e_base b2 (1, "foo", c2);
+
+ auto_ptr<e_simple_type> s3 (new e_simple_type ("foo"));
+ auto_ptr<e_complex_type> c3 (new e_complex_type ("bar"));
+ e_base b3 (1, s3, c3);
+
+ assert (b1 == b2);
+ assert (b1 == b3);
+
+ // e_derived
+ //
+ e_derived d1 (1, "foo", e_complex_type ("bar"),
+ true, "baz", e_complex_type ("biz"));
+
+ auto_ptr<e_complex_type> c2a (new e_complex_type ("bar"));
+ auto_ptr<e_complex_type> c2b (new e_complex_type ("biz"));
+ e_derived d2 (1, "foo", c2a, true, "baz", c2b);
+
+ auto_ptr<e_simple_type> s3a (new e_simple_type ("foo"));
+ auto_ptr<xml_schema::string> s3b (new xml_schema::string ("baz"));
+ auto_ptr<e_complex_type> c3a (new e_complex_type ("bar"));
+ auto_ptr<e_complex_type> c3b (new e_complex_type ("biz"));
+ e_derived d3 (1, s3a, c3a, true, s3b, c3b);
+
+ assert (d1 == d2);
+ assert (d1 == d3);
+
+ }
+
+ // Test case F.
+ //
+ {
+ f_type f1 (xml_schema::type (), 1, "foo", f_complex_type ("bar"));
+
+ auto_ptr<f_complex_type> c2 (new f_complex_type ("bar"));
+ f_type f2 (1, "foo", c2);
+
+ auto_ptr<f_simple_type> s3 (new f_simple_type ("foo"));
+ auto_ptr<f_complex_type> c3 (new f_complex_type ("bar"));
+ f_type f3 (1, s3, c3);
+
+ assert (f1 == f2);
+ assert (f1 == f3);
+ }
+}
diff --git a/tests/cxx/tree/complex/ctor/makefile b/tests/cxx/tree/complex/ctor/makefile
new file mode 100644
index 0000000..4894a6f
--- /dev/null
+++ b/tests/cxx/tree/complex/ctor/makefile
@@ -0,0 +1,83 @@
+# file : tests/cxx/tree/complex/ctor/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-default-ctor \
+--generate-from-base-ctor --generate-doxygen --generate-polymorphic \
+--generate-comparison
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/complex/ctor/test.xsd b/tests/cxx/tree/complex/ctor/test.xsd
new file mode 100644
index 0000000..b8dd95e
--- /dev/null
+++ b/tests/cxx/tree/complex/ctor/test.xsd
@@ -0,0 +1,182 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- Test case A: several levels of inheritance with ultimate base. -->
+
+ <complexType name="a_base">
+ <simpleContent>
+ <extension base="string">
+ <attribute name="foo" type="string" use="required"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="a_derived">
+ <simpleContent>
+ <extension base="t:a_base">
+ <attribute name="bar" type="string" use="required"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <!-- Test case B: string-based c-tors. -->
+
+ <simpleType name="b_simple">
+ <restriction base="string">
+ </restriction>
+ </simpleType>
+
+ <complexType name="b_base">
+ <simpleContent>
+ <extension base="t:b_simple">
+ <attribute name="foo" type="string" use="required"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="b_derived">
+ <simpleContent>
+ <extension base="t:b_base">
+ <attribute name="bar" type="string" use="required"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="b_type">
+ <sequence>
+ <element name="a" type="t:b_simple"/>
+ </sequence>
+ </complexType>
+
+ <!-- Test case C: enum-based c-tors. -->
+
+ <simpleType name="c_enum_base">
+ <restriction base="string">
+ <enumeration value="a"/>
+ <enumeration value="b"/>
+ <enumeration value="c"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="c_enum">
+ <restriction base="t:c_enum_base">
+ <enumeration value="a"/>
+ <enumeration value="c"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="c_simple">
+ <restriction base="t:c_enum">
+ </restriction>
+ </simpleType>
+
+ <complexType name="c_base">
+ <simpleContent>
+ <extension base="t:c_simple">
+ <attribute name="foo" type="string" use="required"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="c_derived">
+ <simpleContent>
+ <extension base="t:c_base">
+ <attribute name="bar" type="string" use="required"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="c_type">
+ <sequence>
+ <element name="a" type="t:c_simple"/>
+ </sequence>
+ </complexType>
+
+ <!-- Test case D: fundamental type c-tors. -->
+
+ <simpleType name="d_simple">
+ <restriction base="int">
+ </restriction>
+ </simpleType>
+
+ <complexType name="d_base">
+ <simpleContent>
+ <extension base="t:d_simple">
+ <attribute name="foo" type="string" use="required"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="d_derived">
+ <simpleContent>
+ <extension base="t:d_base">
+ <attribute name="bar" type="string" use="required"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="d_type">
+ <sequence>
+ <element name="a" type="t:d_simple"/>
+ </sequence>
+ </complexType>
+
+ <!-- Test case E: auto_ptr ctors. -->
+
+ <simpleType name="e_simple_type">
+ <restriction base="string">
+ </restriction>
+ </simpleType>
+
+ <complexType name="e_complex_type">
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="e_base">
+ <sequence>
+ <element name="fund" type="int"/>
+ <element name="simple" type="t:e_simple_type"/>
+ <element name="complex" type="t:e_complex_type"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="e_derived">
+ <complexContent>
+ <extension base="t:e_base">
+ <sequence>
+ <element name="fund1" type="boolean"/>
+ <element name="simple1" type="string"/>
+ <element name="complex1" type="t:e_complex_type"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <!-- Test case F: auto_ptr args in c-tor (all-non-optional-members) -->
+
+ <simpleType name="f_simple_type">
+ <restriction base="string">
+ </restriction>
+ </simpleType>
+
+ <complexType name="f_complex_type">
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="f_type">
+ <complexContent>
+ <restriction base="anyType">
+ <sequence>
+ <element name="fund" type="int"/>
+ <element name="simple" type="t:f_simple_type"/>
+ <element name="complex" type="t:f_complex_type"/>
+ </sequence>
+ </restriction>
+ </complexContent>
+ </complexType>
+
+</schema>
diff --git a/tests/cxx/tree/complex/makefile b/tests/cxx/tree/complex/makefile
new file mode 100644
index 0000000..ed6e5de
--- /dev/null
+++ b/tests/cxx/tree/complex/makefile
@@ -0,0 +1,20 @@
+# file : tests/cxx/tree/complex/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+tests := ctor
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/tree/containment/driver.cxx b/tests/cxx/tree/containment/driver.cxx
new file mode 100644
index 0000000..bd9aa24
--- /dev/null
+++ b/tests/cxx/tree/containment/driver.cxx
@@ -0,0 +1,77 @@
+// file : tests/cxx/tree/test-template/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test tree node containment.
+//
+
+#include <memory> // std::auto_ptr
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main ()
+{
+ // Change of a container in a sub-tree without ID.
+ //
+ {
+ auto_ptr<inner> i (new inner ());
+ i->ref ("foo");
+
+ outer o;
+ o.i (i);
+ o.ref ("foo");
+
+ assert (o.i ()->ref ()->get () == 0);
+ assert (o.ref ()->get () == 0);
+ }
+
+ // Change of container in a sub-tree with ID inside.
+ //
+ {
+ auto_ptr<inner> i (new inner ());
+ inner* p (i.get ());
+ i->id ("foo");
+ i->ref ("foo");
+ assert (i->ref ()->get () == p);
+
+ outer o;
+ o.i (i);
+ o.ref ("foo");
+
+ assert (o.i ()->ref ()->get () == p);
+ assert (o.ref ()->get () == p);
+ }
+
+ // Change of a container in ID.
+ //
+ {
+ auto_ptr<xml_schema::id> id (new xml_schema::id ("foo"));
+
+ inner i;
+ i.id (id);
+ i.ref ("foo");
+ assert (i.ref ()->get () == &i);
+ }
+
+ // Change of a container in a type derived from ID with ID inside.
+ //
+ {
+ auto_ptr<id_ex> id (new id_ex ("foo"));
+ id_ex* p (id.get ());
+ id->id ("bar");
+
+ inner i;
+ i.id_ex (id);
+
+ i.ref ("foo");
+ assert (i.ref ()->get () == &i);
+
+ i.ref ("bar");
+ assert (i.ref ()->get () == p);
+ }
+}
diff --git a/tests/cxx/tree/containment/makefile b/tests/cxx/tree/containment/makefile
new file mode 100644
index 0000000..e29e93a
--- /dev/null
+++ b/tests/cxx/tree/containment/makefile
@@ -0,0 +1,81 @@
+# file : tests/cxx/tree/containment/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options :=
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/containment/test.xsd b/tests/cxx/tree/containment/test.xsd
new file mode 100644
index 0000000..002bdda
--- /dev/null
+++ b/tests/cxx/tree/containment/test.xsd
@@ -0,0 +1,27 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="id-ex">
+ <simpleContent>
+ <extension base="ID">
+ <attribute name="id" type="ID"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="inner">
+ <sequence>
+ <element name="id" type="ID" minOccurs="0"/>
+ <element name="id-ex" type="t:id-ex" minOccurs="0"/>
+ <element name="ref" type="IDREF" minOccurs="0"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="outer">
+ <sequence>
+ <element name="i" type="t:inner" minOccurs="0"/>
+ <element name="ref" type="IDREF" minOccurs="0"/>
+ </sequence>
+ </complexType>
+
+</schema>
diff --git a/tests/cxx/tree/default/driver.cxx b/tests/cxx/tree/default/driver.cxx
new file mode 100644
index 0000000..3c71222
--- /dev/null
+++ b/tests/cxx/tree/default/driver.cxx
@@ -0,0 +1,48 @@
+// file : tests/cxx/tree/default/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test default attribute/element values.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<type> r (root (argv[1], xml_schema::flags::dont_validate));
+
+ cout << *r << endl
+ << "default x: " << derived::x_default_value () << endl
+ << "default y: " << derived::y_default_value () << endl
+ << "fixed p: " << derived::p_default_value () << endl
+ << "fixed q1: " << derived::q1_default_value () << endl
+ << "fixed q2: " << derived::q2_default_value () << endl;
+
+ // Serialize.
+ //
+ xml_schema::namespace_infomap map;
+ map["t"].name = "test";
+ root (cout, *r, map);
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/default/makefile b/tests/cxx/tree/default/makefile
new file mode 100644
index 0000000..209c283
--- /dev/null
+++ b/tests/cxx/tree/default/makefile
@@ -0,0 +1,83 @@
+# file : tests/cxx/tree/default/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-ostream \
+--generate-serialization --generate-default-ctor --generate-from-base-ctor \
+--omit-default-attributes
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/default/output b/tests/cxx/tree/default/output
new file mode 100644
index 0000000..1259952
--- /dev/null
+++ b/tests/cxx/tree/default/output
@@ -0,0 +1,26 @@
+
+derived:
+a: a
+x: foo
+q1: 1
+y: -20
+p: bar
+q2: 2
+qname:
+x: x
+y: y
+default x: foo
+default y: -20
+fixed p: bar
+fixed q1: 1
+fixed q2: 2
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<t:root xmlns:t="test">
+
+ <derived q1="1" q2="2">
+ <a>a</a>
+ </derived>
+
+ <qname x="x" y="y"/>
+
+</t:root>
diff --git a/tests/cxx/tree/default/test.xml b/tests/cxx/tree/default/test.xml
new file mode 100644
index 0000000..d568ac9
--- /dev/null
+++ b/tests/cxx/tree/default/test.xml
@@ -0,0 +1,11 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <derived q1="1" q2="2">
+ <a>a</a>
+ </derived>
+
+ <qname y="y"><!--a></a--></qname>
+
+</t:root>
diff --git a/tests/cxx/tree/default/test.xsd b/tests/cxx/tree/default/test.xsd
new file mode 100644
index 0000000..aa9ac66
--- /dev/null
+++ b/tests/cxx/tree/default/test.xsd
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="base">
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ <attribute name="x" type="string" default="foo"/>
+ <attribute name="q1" type="int" fixed="1" use="required"/>
+ </complexType>
+
+ <complexType name="derived">
+ <complexContent>
+ <extension base="t:base">
+ <attribute name="y" type="int" default="-20"/>
+ <attribute name="p" type="string" fixed="bar"/>
+ <attribute name="q2" type="int" fixed="2" use="required"/>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="qname">
+ <sequence>
+ <!--element name="a" type="QName" default="a"/-->
+ </sequence>
+ <attribute name="x" type="QName" default="x"/>
+ <attribute name="y" type="QName" fixed="y" use="required"/>
+ </complexType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="derived" type="t:derived"/>
+ <element name="qname" type="t:qname"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/encoding/char/lcp/driver.cxx b/tests/cxx/tree/encoding/char/lcp/driver.cxx
new file mode 100644
index 0000000..3d30aa9
--- /dev/null
+++ b/tests/cxx/tree/encoding/char/lcp/driver.cxx
@@ -0,0 +1,42 @@
+// file : tests/cxx/tree/encoding/char/lcp/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test local code page encoding (XSD_USE_LCP defined).
+// The test just makes sure it still compiles and works.
+//
+
+#include <memory> // std::auto_ptr
+#include <fstream>
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<type> r (root (argv[1]));
+
+ xml_schema::namespace_infomap map;
+ map["t"].name = "test";
+
+ root (std::cout, *r, map);
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << "xml_schema::exception: " << e.what () << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/encoding/char/lcp/makefile b/tests/cxx/tree/encoding/char/lcp/makefile
new file mode 100644
index 0000000..8560e92
--- /dev/null
+++ b/tests/cxx/tree/encoding/char/lcp/makefile
@@ -0,0 +1,81 @@
+# file : tests/cxx/tree/encoding/char/lcp/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd -DXSD_USE_LCP
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-serialization
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/test.std
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/test.std -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/encoding/char/lcp/test.std b/tests/cxx/tree/encoding/char/lcp/test.std
new file mode 100644
index 0000000..cc20ef7
--- /dev/null
+++ b/tests/cxx/tree/encoding/char/lcp/test.std
@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<t:root xmlns:t="test">
+
+ <a>abcd</a>
+
+</t:root>
diff --git a/tests/cxx/tree/encoding/char/lcp/test.xml b/tests/cxx/tree/encoding/char/lcp/test.xml
new file mode 100644
index 0000000..772512e
--- /dev/null
+++ b/tests/cxx/tree/encoding/char/lcp/test.xml
@@ -0,0 +1,7 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <a>abcd</a>
+
+</t:root>
diff --git a/tests/cxx/tree/encoding/char/lcp/test.xsd b/tests/cxx/tree/encoding/char/lcp/test.xsd
new file mode 100644
index 0000000..1e264e3
--- /dev/null
+++ b/tests/cxx/tree/encoding/char/lcp/test.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="type">
+ <sequence>
+ <element name="a" type="string" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/encoding/char/makefile b/tests/cxx/tree/encoding/char/makefile
new file mode 100644
index 0000000..c69fc44
--- /dev/null
+++ b/tests/cxx/tree/encoding/char/makefile
@@ -0,0 +1,22 @@
+# file : tests/cxx/tree/encoding/char/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+
+tests := lcp utf-8
+
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/tree/encoding/char/utf-8/driver.cxx b/tests/cxx/tree/encoding/char/utf-8/driver.cxx
new file mode 100644
index 0000000..45a5fd1
--- /dev/null
+++ b/tests/cxx/tree/encoding/char/utf-8/driver.cxx
@@ -0,0 +1,67 @@
+// file : tests/cxx/tree/encoding/char/utf-8/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test UTF-8 encoding.
+//
+
+#include <memory> // std::auto_ptr
+#include <fstream>
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<type> r (root (argv[1]));
+
+ {
+ type::a_sequence const& s (r->a ());
+
+ if (s[0] != "abc" ||
+ s[1] != "\xD5\x95" ||
+ s[2] != "\xEA\xAA\xAA" ||
+ s[3] != "\xF2\xAA\xAA\xAA")
+ {
+ cerr << "invalid encoding" << endl;
+ return 1;
+ }
+ }
+
+ {
+ type::b_sequence const& s (r->b ());
+
+ if (s[0] != strenum::abc ||
+ s[1] != strenum::a_c ||
+ s[2] != strenum::cxx_bc ||
+ s[3] != strenum::ab_)
+ {
+ cerr << "invalid encoding" << endl;
+ return 1;
+ }
+ }
+
+ xml_schema::namespace_infomap map;
+ map["t"].name = "test";
+
+ root (std::cout, *r, map, "UCS-4LE");
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << "xml_schema::exception: " << e.what () << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/encoding/char/utf-8/makefile b/tests/cxx/tree/encoding/char/utf-8/makefile
new file mode 100644
index 0000000..0aa5884
--- /dev/null
+++ b/tests/cxx/tree/encoding/char/utf-8/makefile
@@ -0,0 +1,82 @@
+# file : tests/cxx/tree/encoding/char/lcp/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-serialization \
+--generate-doxygen
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/test.std
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/test.std -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/encoding/char/utf-8/test.std b/tests/cxx/tree/encoding/char/utf-8/test.std
new file mode 100644
index 0000000..328fe6d
--- /dev/null
+++ b/tests/cxx/tree/encoding/char/utf-8/test.std
Binary files differ
diff --git a/tests/cxx/tree/encoding/char/utf-8/test.xml b/tests/cxx/tree/encoding/char/utf-8/test.xml
new file mode 100644
index 0000000..a6e5d99
--- /dev/null
+++ b/tests/cxx/tree/encoding/char/utf-8/test.xml
@@ -0,0 +1,15 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <a>abc</a>
+ <a>&#x555;</a>
+ <a>&#xAAAA;</a>
+ <a>&#xAAAAA;</a>
+
+ <b>abc</b>
+ <b>a&#x555;c</b>
+ <b>&#xAAAA;bc</b>
+ <b>ab&#xAAAAA;</b>
+
+</t:root>
diff --git a/tests/cxx/tree/encoding/char/utf-8/test.xsd b/tests/cxx/tree/encoding/char/utf-8/test.xsd
new file mode 100644
index 0000000..6c32a32
--- /dev/null
+++ b/tests/cxx/tree/encoding/char/utf-8/test.xsd
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="strenum">
+
+ <annotation>
+ <documentation>
+ Test enum. Valid values are:
+ abc
+ a&#x555;c
+ &#xAAAA;bc
+ ab&#xAAAAA;
+ </documentation>
+ </annotation>
+
+ <restriction base="string">
+ <enumeration value="abc"/>
+ <enumeration value="a&#x555;c"/>
+ <enumeration value="&#xAAAA;bc"/>
+ <enumeration value="ab&#xAAAAA;"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="a" type="string" maxOccurs="unbounded"/>
+ <element name="b" type="t:strenum" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/encoding/makefile b/tests/cxx/tree/encoding/makefile
new file mode 100644
index 0000000..5e0803e
--- /dev/null
+++ b/tests/cxx/tree/encoding/makefile
@@ -0,0 +1,22 @@
+# file : tests/cxx/tree/encoding/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+
+tests := char wchar
+
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/tree/encoding/wchar/driver.cxx b/tests/cxx/tree/encoding/wchar/driver.cxx
new file mode 100644
index 0000000..0707cc3
--- /dev/null
+++ b/tests/cxx/tree/encoding/wchar/driver.cxx
@@ -0,0 +1,57 @@
+// file : tests/cxx/tree/encoding/wchar/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test the wide character mapping.
+//
+
+#include <memory> // std::auto_ptr
+#include <fstream>
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ // Use dont_validate because we do not have instance's system id (path).
+ //
+ std::ifstream ifs (argv[1]);
+ auto_ptr<type> r (root (ifs, xml_schema::flags::dont_validate));
+
+ {
+ type::b_sequence const& s (r->b ());
+
+ if (s[0] != strenum::abc ||
+ s[1] != strenum::a__c ||
+ s[2] != strenum::cxx__bc ||
+ s[3] != strenum::ab__)
+ {
+ cerr << "invalid encoding" << endl;
+ return 1;
+ }
+ }
+
+ xml_schema::namespace_infomap map;
+ map[L"t"].name = L"test";
+
+ root (std::cout, *r, map, L"UCS-4LE");
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << "xml_schema::exception: " << e.what () << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/encoding/wchar/makefile b/tests/cxx/tree/encoding/wchar/makefile
new file mode 100644
index 0000000..bf2e57d
--- /dev/null
+++ b/tests/cxx/tree/encoding/wchar/makefile
@@ -0,0 +1,82 @@
+# file : tests/cxx/tree/encoding/wchar/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-serialization \
+--generate-doxygen --char-type wchar_t
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/test.std
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/test.std -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/encoding/wchar/test.std b/tests/cxx/tree/encoding/wchar/test.std
new file mode 100644
index 0000000..93d4561
--- /dev/null
+++ b/tests/cxx/tree/encoding/wchar/test.std
Binary files differ
diff --git a/tests/cxx/tree/encoding/wchar/test.xml b/tests/cxx/tree/encoding/wchar/test.xml
new file mode 100644
index 0000000..c6ec850
--- /dev/null
+++ b/tests/cxx/tree/encoding/wchar/test.xml
@@ -0,0 +1,14 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <a>abc</a>
+ <a>&#x1FFF;&#xD7FF;</a>
+ <a>&#x10000;&#x10FFFD;</a>
+
+ <b>abc</b>
+ <b>a&#x1FFF;&#xD7FF;c</b>
+ <b>&#x10000;&#x10FFFD;bc</b>
+ <b>ab&#x10000;&#x10FFFD;</b>
+
+</t:root>
diff --git a/tests/cxx/tree/encoding/wchar/test.xsd b/tests/cxx/tree/encoding/wchar/test.xsd
new file mode 100644
index 0000000..0bf4bdd
--- /dev/null
+++ b/tests/cxx/tree/encoding/wchar/test.xsd
@@ -0,0 +1,33 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="strenum">
+
+ <annotation>
+ <documentation>
+ Test enum. Valid values are:
+ abc
+ a&#x1FFF;&#xD7FF;c
+ &#x10000;&#x10FFFD;bc
+ ab&#x10000;&#x10FFFD;
+ </documentation>
+ </annotation>
+
+ <restriction base="string">
+ <enumeration value="abc"/>
+ <enumeration value="a&#x1FFF;&#xD7FF;c"/>
+ <enumeration value="&#x10000;&#x10FFFD;bc"/>
+ <enumeration value="ab&#x10000;&#x10FFFD;"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="a" type="string" maxOccurs="unbounded"/>
+ <element name="b" type="t:strenum" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/enumeration/ctor/driver.cxx b/tests/cxx/tree/enumeration/ctor/driver.cxx
new file mode 100644
index 0000000..238d446
--- /dev/null
+++ b/tests/cxx/tree/enumeration/ctor/driver.cxx
@@ -0,0 +1,32 @@
+// file : tests/cxx/tree/enumeration/ctor/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test enumeration constructors.
+//
+#include <string>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main ()
+{
+ // Test ctor(const char*).
+ //
+ {
+ string_enum se ("a");
+ type t ("a", 1);
+ }
+
+ // Test ctor(const std::string&)
+ //
+ {
+ string const s ("c");
+ string_enum se (s);
+ type t (s, 3);
+ }
+}
diff --git a/tests/cxx/tree/enumeration/ctor/makefile b/tests/cxx/tree/enumeration/ctor/makefile
new file mode 100644
index 0000000..3ea7b8e
--- /dev/null
+++ b/tests/cxx/tree/enumeration/ctor/makefile
@@ -0,0 +1,82 @@
+# file : tests/cxx/tree/enumeration/ctor/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-default-ctor \
+--generate-from-base-ctor --generate-doxygen
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/enumeration/ctor/test.xsd b/tests/cxx/tree/enumeration/ctor/test.xsd
new file mode 100644
index 0000000..c5d625a
--- /dev/null
+++ b/tests/cxx/tree/enumeration/ctor/test.xsd
@@ -0,0 +1,41 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="string-enum-base">
+ <restriction base="string">
+ <enumeration value="a"/>
+ <enumeration value="b"/>
+ <enumeration value="c"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="string-enum">
+ <restriction base="t:string-enum-base">
+ <enumeration value="a"/>
+ <enumeration value="c"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="int-enum-base">
+ <restriction base="int">
+ <enumeration value="1"/>
+ <enumeration value="2"/>
+ <enumeration value="3"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="int-enum">
+ <restriction base="t:int-enum-base">
+ <enumeration value="1"/>
+ <enumeration value="3"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="a" type="t:string-enum"/>
+ <element name="b" type="t:int-enum"/>
+ </sequence>
+ </complexType>
+
+</schema>
diff --git a/tests/cxx/tree/enumeration/inheritance/driver.cxx b/tests/cxx/tree/enumeration/inheritance/driver.cxx
new file mode 100644
index 0000000..af67afb
--- /dev/null
+++ b/tests/cxx/tree/enumeration/inheritance/driver.cxx
@@ -0,0 +1,49 @@
+// file : tests/cxx/tree/enumeration/inheritance/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Insert test description here.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<top_bottom> r (root (argv[1]));
+
+ switch (*r)
+ {
+ case top_bottom::top:
+ {
+ cout << "top" << endl;
+ break;
+ }
+ case top_bottom::bottom:
+ {
+ cout << "bottom" << endl;
+ break;
+ }
+ }
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/enumeration/inheritance/makefile b/tests/cxx/tree/enumeration/inheritance/makefile
new file mode 100644
index 0000000..0af9733
--- /dev/null
+++ b/tests/cxx/tree/enumeration/inheritance/makefile
@@ -0,0 +1,81 @@
+# file : tests/cxx/tree/enumeration/inheritance/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-ostream
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/enumeration/inheritance/output b/tests/cxx/tree/enumeration/inheritance/output
new file mode 100644
index 0000000..fef12e2
--- /dev/null
+++ b/tests/cxx/tree/enumeration/inheritance/output
@@ -0,0 +1 @@
+bottom
diff --git a/tests/cxx/tree/enumeration/inheritance/test.xml b/tests/cxx/tree/enumeration/inheritance/test.xml
new file mode 100644
index 0000000..1de9043
--- /dev/null
+++ b/tests/cxx/tree/enumeration/inheritance/test.xml
@@ -0,0 +1,3 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">bottom</t:root>
diff --git a/tests/cxx/tree/enumeration/inheritance/test.xsd b/tests/cxx/tree/enumeration/inheritance/test.xsd
new file mode 100644
index 0000000..cf2eeb1
--- /dev/null
+++ b/tests/cxx/tree/enumeration/inheritance/test.xsd
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="side">
+ <restriction base="string">
+ <enumeration value="top"/>
+ <enumeration value="left"/>
+ <enumeration value="bottom"/>
+ <enumeration value="right"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="top-bottom">
+ <restriction base="t:side">
+ <enumeration value="top"/>
+ <enumeration value="bottom"/>
+ </restriction>
+ </simpleType>
+
+ <element name="root" type="t:top-bottom"/>
+
+</schema>
diff --git a/tests/cxx/tree/enumeration/makefile b/tests/cxx/tree/enumeration/makefile
new file mode 100644
index 0000000..87cab57
--- /dev/null
+++ b/tests/cxx/tree/enumeration/makefile
@@ -0,0 +1,20 @@
+# file : tests/cxx/tree/enumeration/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+tests := ctor inheritance
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/tree/float/driver.cxx b/tests/cxx/tree/float/driver.cxx
new file mode 100644
index 0000000..336c731
--- /dev/null
+++ b/tests/cxx/tree/float/driver.cxx
@@ -0,0 +1,55 @@
+// file : tests/cxx/tree/float/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test floating point (xsd:{float, double, decimal}) type parsing
+// and serialization.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<type> r (root (argv[1]));
+
+ r->simple ().push_back (12.129456);
+ r->simple ().push_back (123.129456);
+ r->simple ().push_back (1234.129456);
+
+ r->s (12.129456);
+
+ r->complex ().push_back (12.129456);
+ r->complex ().push_back (123.129456);
+ r->complex ().push_back (1234.129456);
+ r->complex ().push_back (-12.12);
+ r->complex ().push_back (-123.12);
+
+ r->s (12.129456);
+
+ xml_schema::namespace_infomap map;
+
+ map["t"].name = "test";
+ root (cout, *r, map);
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/float/makefile b/tests/cxx/tree/float/makefile
new file mode 100644
index 0000000..a847ad5
--- /dev/null
+++ b/tests/cxx/tree/float/makefile
@@ -0,0 +1,81 @@
+# file : tests/cxx/tree/float/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-serialization --root-element-all
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/test.std
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/test.std -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/float/test.std b/tests/cxx/tree/float/test.std
new file mode 100644
index 0000000..44264c2
--- /dev/null
+++ b/tests/cxx/tree/float/test.std
@@ -0,0 +1,68 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<t:root xmlns:t="test" de="0" do="0" f="0" s="12.13">
+
+ <float>0</float>
+
+ <float>1</float>
+
+ <float>1e+06</float>
+
+ <float>1e-07</float>
+
+ <float-list>0 1 1e+06 1e-07</float-list>
+
+ <double>0</double>
+
+ <double>1</double>
+
+ <double>100000000000000</double>
+
+ <double>1e-15</double>
+
+ <double-list>0 1 100000000000000 1e-15</double-list>
+
+ <decimal>0</decimal>
+
+ <decimal>1</decimal>
+
+ <decimal>10000</decimal>
+
+ <decimal>100000000000000</decimal>
+
+ <decimal>0.000000000000001</decimal>
+
+ <decimal-list>0 1 100000000000000 0.000000000000001</decimal-list>
+
+ <simple>0</simple>
+
+ <simple>1</simple>
+
+ <simple>12.34</simple>
+
+ <simple>0.12</simple>
+
+ <simple>12.13</simple>
+
+ <simple>123.1</simple>
+
+ <simple>1234</simple>
+
+ <complex>0</complex>
+
+ <complex>1</complex>
+
+ <complex>12.34</complex>
+
+ <complex>0.12</complex>
+
+ <complex>12.13</complex>
+
+ <complex>123.1</complex>
+
+ <complex>1234</complex>
+
+ <complex>-12.12</complex>
+
+ <complex>-123.1</complex>
+
+</t:root>
diff --git a/tests/cxx/tree/float/test.xml b/tests/cxx/tree/float/test.xml
new file mode 100644
index 0000000..e5124a4
--- /dev/null
+++ b/tests/cxx/tree/float/test.xml
@@ -0,0 +1,35 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd"
+ f="0.0" do="0.0" de="0.0">
+
+ <float>0.0</float>
+ <float>1.0</float>
+ <float>1000000.0</float>
+ <float>0.0000001</float>
+ <float-list>0.0 1.0 1000000.0 0.0000001</float-list>
+
+ <double>0.0</double>
+ <double>1.0</double>
+ <double>100000000000000.0</double>
+ <double>0.000000000000001</double>
+ <double-list>0.0 1.0 100000000000000.0 0.000000000000001</double-list>
+
+ <decimal>0.0</decimal>
+ <decimal>1.0</decimal>
+ <decimal>10000</decimal>
+ <decimal>100000000000000.0</decimal>
+ <decimal>0.000000000000001</decimal>
+ <decimal-list>0.0 1.0 100000000000000.0 0.000000000000001</decimal-list>
+
+ <simple>0.0</simple>
+ <simple>1.0</simple>
+ <simple>12.34</simple>
+ <simple>0.12</simple>
+
+ <complex>0.0</complex>
+ <complex>1.0</complex>
+ <complex>12.34</complex>
+ <complex>0.12</complex>
+
+</t:root>
diff --git a/tests/cxx/tree/float/test.xsd b/tests/cxx/tree/float/test.xsd
new file mode 100644
index 0000000..c02678d
--- /dev/null
+++ b/tests/cxx/tree/float/test.xsd
@@ -0,0 +1,74 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="float-list">
+ <list itemType="float"/>
+ </simpleType>
+
+ <simpleType name="double-list">
+ <list itemType="double"/>
+ </simpleType>
+
+ <simpleType name="decimal-list">
+ <list itemType="decimal"/>
+ </simpleType>
+
+ <!-- decimal facets -->
+
+ <simpleType name="simple">
+ <restriction base="t:base-simple">
+ <fractionDigits value="2"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="base-simple">
+ <restriction base="decimal">
+ <totalDigits value="4"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="complex">
+ <simpleContent>
+ <restriction base="t:base-complex">
+ <fractionDigits value="2"/>
+ <totalDigits value="4"/>
+ <attribute name="x" type="int"/>
+ </restriction>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="base-complex">
+ <simpleContent>
+ <extension base="decimal">
+ <attribute name="x" type="int"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+
+ <complexType name="type">
+ <sequence>
+ <element name="float" type="float" maxOccurs="unbounded"/>
+ <element name="float-list" type="t:float-list"/>
+ <element name="double" type="double" maxOccurs="unbounded"/>
+ <element name="double-list" type="t:double-list"/>
+ <element name="decimal" type="decimal" maxOccurs="unbounded"/>
+ <element name="decimal-list" type="t:decimal-list"/>
+
+ <element name="simple" type="t:simple" maxOccurs="unbounded"/>
+ <element name="complex" type="t:complex" maxOccurs="unbounded"/>
+
+ </sequence>
+ <attribute name="f" type="float" default="12.34"/>
+ <attribute name="do" type="double" default="1234.1234"/>
+ <attribute name="de" type="decimal" default="1234.1234"/>
+
+ <attribute name="s" type="t:simple"/>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+ <element name="double" type="double"/>
+ <element name="decimal" type="decimal"/>
+
+</schema>
diff --git a/tests/cxx/tree/list/ctor/driver.cxx b/tests/cxx/tree/list/ctor/driver.cxx
new file mode 100644
index 0000000..0cac51c
--- /dev/null
+++ b/tests/cxx/tree/list/ctor/driver.cxx
@@ -0,0 +1,52 @@
+// file : tests/cxx/tree/list/ctor/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test list constructors.
+//
+#include <string>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main ()
+{
+ // Test ctor()
+ //
+ {
+ string_list sl;
+
+ xml_schema::nmtokens nt;
+ xml_schema::idrefs id;
+ }
+
+ // Test ctor(size_type, const X&)
+ //
+ {
+ string_list sl (10, "abc");
+ size_type st (10, 123);
+
+ xml_schema::nmtokens nt (10, "abc");
+ xml_schema::idrefs id (10, "abc");
+ }
+
+ // Test ctor(const I& begin, const I& end)
+ //
+ {
+ string_list sl1 (10, "abc");
+ string_list sl2 (sl1.begin (), sl1.end ());
+
+ I i1 (10, 123);
+ I i2 (i1.begin (), i1.end ());
+
+ xml_schema::nmtokens nt1 (10, "abc");
+ xml_schema::nmtokens nt2 (nt1.begin (), nt1.end ());
+
+ xml_schema::idrefs id1 (10, "abc");
+ xml_schema::idrefs id2 (id1.begin (), id1.end ());
+ }
+}
diff --git a/tests/cxx/tree/list/ctor/makefile b/tests/cxx/tree/list/ctor/makefile
new file mode 100644
index 0000000..1a002ae
--- /dev/null
+++ b/tests/cxx/tree/list/ctor/makefile
@@ -0,0 +1,82 @@
+# file : tests/cxx/tree/list/ctor/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-default-ctor \
+--generate-from-base-ctor --generate-doxygen
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/list/ctor/test.xsd b/tests/cxx/tree/list/ctor/test.xsd
new file mode 100644
index 0000000..f090bb8
--- /dev/null
+++ b/tests/cxx/tree/list/ctor/test.xsd
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="string-list">
+ <list itemType="string"/>
+ </simpleType>
+
+ <!-- Test name conflict resolution. -->
+
+ <simpleType name="size_type">
+ <list itemType="int"/>
+ </simpleType>
+
+ <simpleType name="I">
+ <list itemType="int"/>
+ </simpleType>
+
+</schema>
diff --git a/tests/cxx/tree/list/makefile b/tests/cxx/tree/list/makefile
new file mode 100644
index 0000000..9d03a72
--- /dev/null
+++ b/tests/cxx/tree/list/makefile
@@ -0,0 +1,20 @@
+# file : tests/cxx/tree/list/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+tests := ctor
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/tree/makefile b/tests/cxx/tree/makefile
new file mode 100644
index 0000000..2d41e54
--- /dev/null
+++ b/tests/cxx/tree/makefile
@@ -0,0 +1,43 @@
+# file : tests/cxx/tree/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../build/bootstrap.make
+
+tests := \
+built-in \
+chameleon \
+comparison \
+compilation \
+complex \
+containment \
+default \
+encoding \
+enumeration \
+float \
+list \
+name-clash \
+naming \
+polymorphism \
+prefix \
+test-template \
+types-only \
+union \
+wildcard
+
+ifeq ($(xsd_with_ace),y)
+tests += binary
+endif
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/tree/name-clash/inheritance/driver.cxx b/tests/cxx/tree/name-clash/inheritance/driver.cxx
new file mode 100644
index 0000000..47f70b7
--- /dev/null
+++ b/tests/cxx/tree/name-clash/inheritance/driver.cxx
@@ -0,0 +1,37 @@
+// file : tests/cxx/tree/name-clash/inheritance/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test for name clashes across inheritance hierarchy.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<derived> r (root (argv[1]));
+
+ cout << *r << endl;
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/name-clash/inheritance/makefile b/tests/cxx/tree/name-clash/inheritance/makefile
new file mode 100644
index 0000000..aea6a21
--- /dev/null
+++ b/tests/cxx/tree/name-clash/inheritance/makefile
@@ -0,0 +1,81 @@
+# file : tests/cxx/tree/name-clash/inheritance/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-ostream
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/name-clash/inheritance/output b/tests/cxx/tree/name-clash/inheritance/output
new file mode 100644
index 0000000..54565bb
--- /dev/null
+++ b/tests/cxx/tree/name-clash/inheritance/output
@@ -0,0 +1,3 @@
+
+e: e
+e: e1
diff --git a/tests/cxx/tree/name-clash/inheritance/test.xml b/tests/cxx/tree/name-clash/inheritance/test.xml
new file mode 100644
index 0000000..8c17101
--- /dev/null
+++ b/tests/cxx/tree/name-clash/inheritance/test.xml
@@ -0,0 +1,8 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <e>e</e>
+ <e>e1</e>
+
+</t:root>
diff --git a/tests/cxx/tree/name-clash/inheritance/test.xsd b/tests/cxx/tree/name-clash/inheritance/test.xsd
new file mode 100644
index 0000000..b83d7df
--- /dev/null
+++ b/tests/cxx/tree/name-clash/inheritance/test.xsd
@@ -0,0 +1,53 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- same member name in base and derived -->
+
+ <complexType name="base">
+ <sequence>
+ <element name="e" type="string"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="derived">
+ <complexContent>
+ <extension base="t:base">
+ <sequence>
+ <element name="e" type="string"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <element name="root" type="t:derived"/>
+
+ <!-- same c-tor argument names (compilation only) -->
+
+ <complexType name="ctor-args">
+ <simpleContent>
+ <extension base="string">
+ <attribute name="string" type="string" use="required"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+
+ <!-- same c-tor argument names (compilation only) -->
+
+ <complexType name="ctor-args-base">
+ <simpleContent>
+ <extension base="string">
+ <attribute name="ctor-args-derived" type="string" use="required"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+ <complexType name="ctor-args-derived">
+ <simpleContent>
+ <extension base="t:ctor-args-base">
+ <attribute name="foo" type="string" use="required"/>
+ </extension>
+ </simpleContent>
+ </complexType>
+
+</schema>
diff --git a/tests/cxx/tree/name-clash/makefile b/tests/cxx/tree/name-clash/makefile
new file mode 100644
index 0000000..5ba6f26
--- /dev/null
+++ b/tests/cxx/tree/name-clash/makefile
@@ -0,0 +1,20 @@
+# file : tests/cxx/tree/name-clash/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+tests := inheritance
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/tree/naming/camel/driver.cxx b/tests/cxx/tree/naming/camel/driver.cxx
new file mode 100644
index 0000000..4958e32
--- /dev/null
+++ b/tests/cxx/tree/naming/camel/driver.cxx
@@ -0,0 +1,145 @@
+// file : tests/cxx/tree/naming/camel/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test camel case (upper for types, lower for functions) naming style.
+//
+
+#include <memory> // std::auto_ptr
+#include <sstream>
+#include <iostream>
+
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main ()
+{
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ // Enum 'value' type.
+ //
+ {
+ Gender::Value v;
+ v = Gender::female;
+ }
+
+ // Anonymous type.
+ //
+ {
+ Foo f ("a", "b");
+
+ if (f.a () != "a" || f.b () != "b")
+ return 1;
+ }
+
+ // Type name and accessors/modifiers.
+ //
+ {
+ Type t ("bar");
+
+ // foo
+ //
+ {
+ Type::FooType* p = 0;
+ Type::FooOptional o;
+
+ if (t.foo ().present ())
+ return 1;
+
+ t.foo (o);
+ }
+
+ // bar
+ //
+ {
+ Type::BarType* p = 0;
+
+ if (t.bar () != "bar")
+ return 1;
+
+ t.bar ("barbar");
+ }
+
+ // baz
+ //
+ {
+ Type::BazType* p = 0;
+ Type::BazSequence s;
+ Type::BazIterator i (s.begin ());
+ Type::BazConstIterator ci (s.begin ());
+
+ if (t.baz () != s)
+ return 1;
+
+ t.baz (s);
+ }
+
+ // any
+ //
+ {
+ Type::AnySequence s (t.domDocument ());
+ Type::AnyIterator i (s.begin ());
+ Type::AnyConstIterator ci (s.begin ());
+
+ if (t.any () != s)
+ return 1;
+
+ t.any (s);
+ }
+
+ // foo
+ //
+ {
+ Type::FoxType x = Type::foxDefaultValue ();
+
+ if (t.fox () != x)
+ return 1;
+
+ t.fox ("fox");
+ }
+
+ // any_attribute
+ //
+ {
+ Type::AnyAttributeSet s (t.domDocument ());
+ Type::AnyAttributeIterator i (s.begin ());
+ Type::AnyAttributeConstIterator ci (s.begin ());
+
+ if (t.anyAttribute () != s)
+ return 1;
+
+ t.anyAttribute (s);
+ }
+ }
+
+ // Parsing/serialization functions.
+ //
+ {
+ istringstream is ("<t:Root xmlns:t='test'>foo</t:Root>");
+ root (is, xml_schema::Flags::dont_validate);
+ }
+
+ {
+ ostringstream os;
+ xml_schema::NamespaceInfomap m;
+ m["t"].name = "test";
+
+ root (os, "foo", m);
+ }
+ }
+ catch (xml_schema::Exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+}
diff --git a/tests/cxx/tree/naming/camel/makefile b/tests/cxx/tree/naming/camel/makefile
new file mode 100644
index 0000000..c308a41
--- /dev/null
+++ b/tests/cxx/tree/naming/camel/makefile
@@ -0,0 +1,87 @@
+# file : tests/cxx/tree/naming/camel/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--type-naming ucc \
+--function-naming lcc \
+--generate-ostream \
+--generate-serialization \
+--generate-comparison \
+--generate-wildcard
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/naming/camel/test.xsd b/tests/cxx/tree/naming/camel/test.xsd
new file mode 100644
index 0000000..7d0a745
--- /dev/null
+++ b/tests/cxx/tree/naming/camel/test.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="gender">
+ <restriction base="string">
+ <enumeration value="male"/>
+ <enumeration value="female"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="foo" minOccurs="0">
+ <complexType>
+ <sequence>
+ <element name="a" type="string"/>
+ <element name="b" type="string"/>
+ </sequence>
+ </complexType>
+ </element>
+ <element name="Bar" type="string"/>
+ <element name="Baz" type="string" maxOccurs="unbounded"/>
+ <any namespace="other" processContents="skip" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Fox" type="string" default="hello"/>
+ <anyAttribute namespace="##other" processContents="skip"/>
+ </complexType>
+
+ <element name="Root" type="string"/>
+
+</schema>
diff --git a/tests/cxx/tree/naming/java/driver.cxx b/tests/cxx/tree/naming/java/driver.cxx
new file mode 100644
index 0000000..413ef70
--- /dev/null
+++ b/tests/cxx/tree/naming/java/driver.cxx
@@ -0,0 +1,145 @@
+// file : tests/cxx/tree/naming/java/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test Java naming style.
+//
+
+#include <memory> // std::auto_ptr
+#include <sstream>
+#include <iostream>
+
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main ()
+{
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ // Enum 'value' type.
+ //
+ {
+ Gender::Value v;
+ v = Gender::female;
+ }
+
+ // Anonymous type.
+ //
+ {
+ Foo f ("a", "b");
+
+ if (f.getA () != "a" || f.getB () != "b")
+ return 1;
+ }
+
+ // Type name and accessors/modifiers.
+ //
+ {
+ Type t ("bar");
+
+ // foo
+ //
+ {
+ Type::FooType* p = 0;
+ Type::FooOptional o;
+
+ if (t.getFoo ().present ())
+ return 1;
+
+ t.setFoo (o);
+ }
+
+ // bar
+ //
+ {
+ Type::BarType* p = 0;
+
+ if (t.getBar () != "bar")
+ return 1;
+
+ t.setBar ("barbar");
+ }
+
+ // baz
+ //
+ {
+ Type::BazType* p = 0;
+ Type::BazSequence s;
+ Type::BazIterator i (s.begin ());
+ Type::BazConstIterator ci (s.begin ());
+
+ if (t.getBaz () != s)
+ return 1;
+
+ t.setBaz (s);
+ }
+
+ // any
+ //
+ {
+ Type::AnySequence s (t.getDomDocument ());
+ Type::AnyIterator i (s.begin ());
+ Type::AnyConstIterator ci (s.begin ());
+
+ if (t.getAny () != s)
+ return 1;
+
+ t.setAny (s);
+ }
+
+ // foo
+ //
+ {
+ Type::FoxType x = Type::getFoxDefaultValue ();
+
+ if (t.getFox () != x)
+ return 1;
+
+ t.setFox ("fox");
+ }
+
+ // any_attribute
+ //
+ {
+ Type::AnyAttributeSet s (t.getDomDocument ());
+ Type::AnyAttributeIterator i (s.begin ());
+ Type::AnyAttributeConstIterator ci (s.begin ());
+
+ if (t.getAnyAttribute () != s)
+ return 1;
+
+ t.setAnyAttribute (s);
+ }
+ }
+
+ // Parsing/serialization functions.
+ //
+ {
+ istringstream is ("<t:root xmlns:t='test'>foo</t:root>");
+ parseRoot (is, xml_schema::Flags::dont_validate);
+ }
+
+ {
+ ostringstream os;
+ xml_schema::NamespaceInfomap m;
+ m["t"].name = "test";
+
+ serializeRoot (os, "foo", m);
+ }
+ }
+ catch (xml_schema::Exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+}
diff --git a/tests/cxx/tree/naming/java/makefile b/tests/cxx/tree/naming/java/makefile
new file mode 100644
index 0000000..d9258c7
--- /dev/null
+++ b/tests/cxx/tree/naming/java/makefile
@@ -0,0 +1,87 @@
+# file : tests/cxx/tree/naming/java/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--type-naming java \
+--function-naming java \
+--generate-ostream \
+--generate-serialization \
+--generate-comparison \
+--generate-wildcard
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/naming/java/test.xsd b/tests/cxx/tree/naming/java/test.xsd
new file mode 100644
index 0000000..f525534
--- /dev/null
+++ b/tests/cxx/tree/naming/java/test.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="gender">
+ <restriction base="string">
+ <enumeration value="male"/>
+ <enumeration value="female"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="foo" minOccurs="0">
+ <complexType>
+ <sequence>
+ <element name="a" type="string"/>
+ <element name="b" type="string"/>
+ </sequence>
+ </complexType>
+ </element>
+ <element name="bar" type="string"/>
+ <element name="Baz" type="string" maxOccurs="unbounded"/>
+ <any namespace="other" processContents="skip" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="Fox" type="string" default="hello"/>
+ <anyAttribute namespace="##other" processContents="skip"/>
+ </complexType>
+
+ <element name="root" type="string"/>
+
+</schema>
diff --git a/tests/cxx/tree/naming/knr/driver.cxx b/tests/cxx/tree/naming/knr/driver.cxx
new file mode 100644
index 0000000..5db744b
--- /dev/null
+++ b/tests/cxx/tree/naming/knr/driver.cxx
@@ -0,0 +1,145 @@
+// file : tests/cxx/tree/naming/knr/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test K&R naming style.
+//
+
+#include <memory> // std::auto_ptr
+#include <sstream>
+#include <iostream>
+
+#include <xercesc/util/PlatformUtils.hpp>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main ()
+{
+ xercesc::XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ // Enum 'value' type.
+ //
+ {
+ gender::value v;
+ v = gender::female;
+ }
+
+ // Anonymous type.
+ //
+ {
+ foo f ("a", "b");
+
+ if (f.a () != "a" || f.b () != "b")
+ return 1;
+ }
+
+ // Type name and accessors/modifiers.
+ //
+ {
+ type t ("bar");
+
+ // foo
+ //
+ {
+ type::foo_type* p = 0;
+ type::foo_optional o;
+
+ if (t.foo ().present ())
+ return 1;
+
+ t.foo (o);
+ }
+
+ // bar
+ //
+ {
+ type::bar_type* p = 0;
+
+ if (t.bar () != "bar")
+ return 1;
+
+ t.bar ("barbar");
+ }
+
+ // baz
+ //
+ {
+ type::baz_type* p = 0;
+ type::baz_sequence s;
+ type::baz_iterator i (s.begin ());
+ type::baz_const_iterator ci (s.begin ());
+
+ if (t.baz () != s)
+ return 1;
+
+ t.baz (s);
+ }
+
+ // any
+ //
+ {
+ type::any_sequence s (t.dom_document ());
+ type::any_iterator i (s.begin ());
+ type::any_const_iterator ci (s.begin ());
+
+ if (t.any () != s)
+ return 1;
+
+ t.any (s);
+ }
+
+ // foo
+ //
+ {
+ type::fox_type x = type::fox_default_value ();
+
+ if (t.fox () != x)
+ return 1;
+
+ t.fox ("fox");
+ }
+
+ // any_attribute
+ //
+ {
+ type::any_attribute_set s (t.dom_document ());
+ type::any_attribute_iterator i (s.begin ());
+ type::any_attribute_const_iterator ci (s.begin ());
+
+ if (t.any_attribute () != s)
+ return 1;
+
+ t.any_attribute (s);
+ }
+ }
+
+ // Parsing/serialization functions.
+ //
+ {
+ istringstream is ("<t:root xmlns:t='test'>foo</t:root>");
+ root (is, xml_schema::flags::dont_validate);
+ }
+
+ {
+ ostringstream os;
+ xml_schema::namespace_infomap m;
+ m["t"].name = "test";
+
+ root (os, "foo", m);
+ }
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+
+ xercesc::XMLPlatformUtils::Terminate ();
+}
diff --git a/tests/cxx/tree/naming/knr/makefile b/tests/cxx/tree/naming/knr/makefile
new file mode 100644
index 0000000..3b92d37
--- /dev/null
+++ b/tests/cxx/tree/naming/knr/makefile
@@ -0,0 +1,87 @@
+# file : tests/cxx/tree/naming/knr/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := \
+--type-naming knr \
+--function-naming knr \
+--generate-ostream \
+--generate-serialization \
+--generate-comparison \
+--generate-wildcard
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/naming/knr/test.xsd b/tests/cxx/tree/naming/knr/test.xsd
new file mode 100644
index 0000000..4361544
--- /dev/null
+++ b/tests/cxx/tree/naming/knr/test.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="gender">
+ <restriction base="string">
+ <enumeration value="male"/>
+ <enumeration value="female"/>
+ </restriction>
+ </simpleType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="foo" minOccurs="0">
+ <complexType>
+ <sequence>
+ <element name="a" type="string"/>
+ <element name="b" type="string"/>
+ </sequence>
+ </complexType>
+ </element>
+ <element name="bar" type="string"/>
+ <element name="baz" type="string" maxOccurs="unbounded"/>
+ <any namespace="other" processContents="skip" maxOccurs="unbounded"/>
+ </sequence>
+ <attribute name="fox" type="string" default="hello"/>
+ <anyAttribute namespace="##other" processContents="skip"/>
+ </complexType>
+
+ <element name="root" type="string"/>
+
+</schema>
diff --git a/tests/cxx/tree/naming/makefile b/tests/cxx/tree/naming/makefile
new file mode 100644
index 0000000..8a70665
--- /dev/null
+++ b/tests/cxx/tree/naming/makefile
@@ -0,0 +1,20 @@
+# file : tests/cxx/tree/naming/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+tests := camel java knr
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/tree/polymorphism/comparison/driver.cxx b/tests/cxx/tree/polymorphism/comparison/driver.cxx
new file mode 100644
index 0000000..02fe4f7
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/comparison/driver.cxx
@@ -0,0 +1,75 @@
+// file : tests/cxx/tree/polymorphism/comparison/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test comparison of polymorphic object models.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<type> r (root (argv[1]));
+
+ // Equals.
+ //
+ {
+ derived1 d ("a", 1);
+ d.b ("b");
+ type r1 (d);
+
+ assert (*r == r1);
+ }
+
+ // Values are not equal.
+ //
+ {
+ derived1 d ("a", 1);
+ d.b ("c");
+ type r1 (d);
+
+ assert (*r != r1);
+ }
+
+ // Values are not equal.
+ //
+ {
+ derived1 d ("a", 2);
+ d.b ("b");
+ type r1 (d);
+
+ assert (*r != r1);
+ }
+
+ // Different types.
+ //
+ {
+ derived2 d ("a", 1);
+ d.c ().push_back ("c");
+ type r1 (d);
+
+ assert (*r != r1);
+ }
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/polymorphism/comparison/makefile b/tests/cxx/tree/polymorphism/comparison/makefile
new file mode 100644
index 0000000..1568b9c
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/comparison/makefile
@@ -0,0 +1,82 @@
+# file : tests/cxx/tree/polymorphism/comparison/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-polymorphic \
+--generate-comparison
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml
+ $(call message,test $$1,$$1 $(src_base)/test.xml,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/polymorphism/comparison/test.xml b/tests/cxx/tree/polymorphism/comparison/test.xml
new file mode 100644
index 0000000..0b8c125
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/comparison/test.xml
@@ -0,0 +1,7 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <base xsi:type="t:derived1"><a>a</a><fund>1</fund><b>b</b></base>
+
+</t:root>
diff --git a/tests/cxx/tree/polymorphism/comparison/test.xsd b/tests/cxx/tree/polymorphism/comparison/test.xsd
new file mode 100644
index 0000000..18532f2
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/comparison/test.xsd
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="base">
+ <sequence>
+ <element name="a" type="string"/>
+ <element name="fund" type="int"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="derived1">
+ <complexContent>
+ <extension base="t:base">
+ <sequence>
+ <element name="b" type="string" minOccurs="0"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="derived2">
+ <complexContent>
+ <extension base="t:base">
+ <sequence>
+ <element name="c" type="string" maxOccurs="unbounded"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="base" type="t:base"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/polymorphism/makefile b/tests/cxx/tree/polymorphism/makefile
new file mode 100644
index 0000000..b9d8bd6
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/makefile
@@ -0,0 +1,20 @@
+# file : tests/cxx/tree/polymorphism/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+tests := comparison ostream same-type
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/tree/polymorphism/ostream/driver.cxx b/tests/cxx/tree/polymorphism/ostream/driver.cxx
new file mode 100644
index 0000000..c483d6f
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/ostream/driver.cxx
@@ -0,0 +1,36 @@
+// file : tests/cxx/tree/polymorphism/ostream/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test printing of polymorphic object models.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<type> r (root (argv[1]));
+ cout << *r << endl;
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/polymorphism/ostream/makefile b/tests/cxx/tree/polymorphism/ostream/makefile
new file mode 100644
index 0000000..2631035
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/ostream/makefile
@@ -0,0 +1,83 @@
+# file : tests/cxx/tree/polymorphism/ostream/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-polymorphic \
+--generate-ostream
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/polymorphism/ostream/output b/tests/cxx/tree/polymorphism/ostream/output
new file mode 100644
index 0000000..bf0e814
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/ostream/output
@@ -0,0 +1,13 @@
+
+base:
+a: a
+fund: 1
+base:
+a: a
+fund: 1
+b: b
+base:
+a: a
+fund: 1
+c: c1
+c: c2
diff --git a/tests/cxx/tree/polymorphism/ostream/test.xml b/tests/cxx/tree/polymorphism/ostream/test.xml
new file mode 100644
index 0000000..157e15c
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/ostream/test.xml
@@ -0,0 +1,9 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <base><a>a</a><fund>1</fund></base>
+ <base xsi:type="t:derived1"><a>a</a><fund>1</fund><b>b</b></base>
+ <base xsi:type="t:derived2"><a>a</a><fund>1</fund><c>c1</c><c>c2</c></base>
+
+</t:root>
diff --git a/tests/cxx/tree/polymorphism/ostream/test.xsd b/tests/cxx/tree/polymorphism/ostream/test.xsd
new file mode 100644
index 0000000..cc1f7a8
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/ostream/test.xsd
@@ -0,0 +1,39 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="base">
+ <sequence>
+ <element name="a" type="string"/>
+ <element name="fund" type="int"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="derived1">
+ <complexContent>
+ <extension base="t:base">
+ <sequence>
+ <element name="b" type="string" minOccurs="0"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="derived2">
+ <complexContent>
+ <extension base="t:base">
+ <sequence>
+ <element name="c" type="string" maxOccurs="unbounded"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="base" type="t:base" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/polymorphism/same-type/driver.cxx b/tests/cxx/tree/polymorphism/same-type/driver.cxx
new file mode 100644
index 0000000..f3556a5
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/same-type/driver.cxx
@@ -0,0 +1,37 @@
+// file : tests/cxx/tree/polymorphism/same-type/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test substitution group and xsi:type that don't change the type.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<type> r (root (argv[1]));
+
+ cout << *r << endl;
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/polymorphism/same-type/makefile b/tests/cxx/tree/polymorphism/same-type/makefile
new file mode 100644
index 0000000..d255131
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/same-type/makefile
@@ -0,0 +1,82 @@
+# file : tests/cxx/tree/polymorphism/same-type/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-ostream \
+--generate-polymorphic --root-element root
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/polymorphism/same-type/output b/tests/cxx/tree/polymorphism/same-type/output
new file mode 100644
index 0000000..04b5cbf
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/same-type/output
@@ -0,0 +1,9 @@
+
+base:
+a: a1
+base:
+a: a2
+base:
+a: a3
+base:
+a: a4
diff --git a/tests/cxx/tree/polymorphism/same-type/test.xml b/tests/cxx/tree/polymorphism/same-type/test.xml
new file mode 100644
index 0000000..f8b6d1e
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/same-type/test.xml
@@ -0,0 +1,10 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <t:base><a>a1</a></t:base>
+ <t:derived><a>a2</a></t:derived>
+ <t:base xsi:type="t:base"><a>a3</a></t:base>
+ <t:derived xsi:type="t:base"><a>a4</a></t:derived>
+
+</t:root>
diff --git a/tests/cxx/tree/polymorphism/same-type/test.xsd b/tests/cxx/tree/polymorphism/same-type/test.xsd
new file mode 100644
index 0000000..a4157d3
--- /dev/null
+++ b/tests/cxx/tree/polymorphism/same-type/test.xsd
@@ -0,0 +1,21 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="base">
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ </complexType>
+
+ <element name="base" type="t:base"/>
+ <element name="derived" type="t:base" substitutionGroup="t:base"/>
+
+ <complexType name="type">
+ <sequence>
+ <element ref="t:base" maxOccurs="unbounded"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/prefix/bar.xsd b/tests/cxx/tree/prefix/bar.xsd
new file mode 100644
index 0000000..4e20902
--- /dev/null
+++ b/tests/cxx/tree/prefix/bar.xsd
@@ -0,0 +1,34 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:f="foo"
+ xmlns:b="bar"
+ targetNamespace="bar"
+ attributeFormDefault="qualified">
+
+ <import namespace="foo" schemaLocation="foo.xsd"/>
+
+ <attribute name="abar" type="int"/>
+
+ <complexType name="derived1">
+ <complexContent>
+ <extension base="f:base">
+ <sequence>
+ <element name="y" type="int"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <complexType name="derived2">
+ <complexContent>
+ <extension base="f:base">
+ <sequence>
+ <element name="z" type="int"/>
+ </sequence>
+ </extension>
+ </complexContent>
+ </complexType>
+
+ <element name="derived" type="b:derived1" substitutionGroup="f:base"/>
+
+</schema>
diff --git a/tests/cxx/tree/prefix/driver.cxx b/tests/cxx/tree/prefix/driver.cxx
new file mode 100644
index 0000000..7155345
--- /dev/null
+++ b/tests/cxx/tree/prefix/driver.cxx
@@ -0,0 +1,36 @@
+// file : tests/cxx/tree/prefix/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test automatic prefix assignment.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<type> r (root (argv[1]));
+ root (std::cout, *r);
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/prefix/foo.xsd b/tests/cxx/tree/prefix/foo.xsd
new file mode 100644
index 0000000..97a35cf
--- /dev/null
+++ b/tests/cxx/tree/prefix/foo.xsd
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:f="foo"
+ targetNamespace="foo">
+
+ <element name="efoo" type="int"/>
+
+ <complexType name="base">
+ <sequence>
+ <element name="x" type="int"/>
+ </sequence>
+ </complexType>
+
+ <element name="base" type="f:base"/>
+
+</schema>
diff --git a/tests/cxx/tree/prefix/makefile b/tests/cxx/tree/prefix/makefile
new file mode 100644
index 0000000..858925a
--- /dev/null
+++ b/tests/cxx/tree/prefix/makefile
@@ -0,0 +1,76 @@
+# file : tests/cxx/tree/prefix/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd foo.xsd bar.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+gen := $(addprefix $(out_base)/,$(xsd:.xsd=.hxx) $(xsd:.xsd=.ixx) $(xsd:.xsd=.cxx))
+
+$(gen): xsd := $(out_root)/xsd/xsd
+$(gen): xsd_options := --generate-serialization --generate-polymorphic \
+--root-element root
+$(gen): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/prefix/output b/tests/cxx/tree/prefix/output
new file mode 100644
index 0000000..4f40f49
--- /dev/null
+++ b/tests/cxx/tree/prefix/output
@@ -0,0 +1,22 @@
+<?xml version="1.0" encoding="UTF-8" standalone="no" ?>
+<p1:root xmlns:p1="test">
+
+ <a xmlns:p3="bar" p3:abar="456" xmlns:p2="foo">
+ <p2:efoo>123</p2:efoo>
+ </a>
+
+ <b xmlns:p2="bar">
+ <p2:derived>
+ <x>1</x>
+ <y>2</y>
+ </p2:derived>
+ </b>
+
+ <c xmlns:p2="foo" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
+ <p2:base xmlns:p3="bar" xsi:type="p3:derived2">
+ <x>1</x>
+ <z>2</z>
+ </p2:base>
+ </c>
+
+</p1:root>
diff --git a/tests/cxx/tree/prefix/test.xml b/tests/cxx/tree/prefix/test.xml
new file mode 100644
index 0000000..b6d0dd6
--- /dev/null
+++ b/tests/cxx/tree/prefix/test.xml
@@ -0,0 +1,19 @@
+<t:root xmlns:t="test"
+ xmlns:f="foo"
+ xmlns:b="bar"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <a b:abar="456">
+ <f:efoo>123</f:efoo>
+ </a>
+
+ <b>
+ <b:derived><x>1</x><y>2</y></b:derived>
+ </b>
+
+ <c>
+ <f:base xsi:type="b:derived2"><x>1</x><z>2</z></f:base>
+ </c>
+
+</t:root>
diff --git a/tests/cxx/tree/prefix/test.xsd b/tests/cxx/tree/prefix/test.xsd
new file mode 100644
index 0000000..421fdc0
--- /dev/null
+++ b/tests/cxx/tree/prefix/test.xsd
@@ -0,0 +1,40 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema"
+ xmlns:f="foo"
+ xmlns:b="bar"
+ xmlns:t="test"
+ targetNamespace="test">
+
+ <import namespace="foo" schemaLocation="foo.xsd"/>
+ <import namespace="bar" schemaLocation="bar.xsd"/>
+
+ <complexType name="a">
+ <sequence>
+ <element ref="f:efoo"/>
+ </sequence>
+ <attribute ref="b:abar"/>
+ </complexType>
+
+ <complexType name="b">
+ <sequence>
+ <element ref="f:base"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="c">
+ <sequence>
+ <element ref="f:base"/>
+ </sequence>
+ </complexType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="a" type="t:a"/>
+ <element name="b" type="t:b"/>
+ <element name="c" type="t:c"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/test-template/driver.cxx b/tests/cxx/tree/test-template/driver.cxx
new file mode 100644
index 0000000..55b7a76
--- /dev/null
+++ b/tests/cxx/tree/test-template/driver.cxx
@@ -0,0 +1,37 @@
+// file : tests/cxx/tree/test-template/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Insert test description here.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ try
+ {
+ auto_ptr<type> r (root (argv[1]));
+
+ cout << *r << endl;
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+}
diff --git a/tests/cxx/tree/test-template/makefile b/tests/cxx/tree/test-template/makefile
new file mode 100644
index 0000000..7dceb17
--- /dev/null
+++ b/tests/cxx/tree/test-template/makefile
@@ -0,0 +1,81 @@
+# file : tests/cxx/tree/test-template/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-ostream
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/test-template/output b/tests/cxx/tree/test-template/output
new file mode 100644
index 0000000..2a50681
--- /dev/null
+++ b/tests/cxx/tree/test-template/output
@@ -0,0 +1,2 @@
+
+a: a
diff --git a/tests/cxx/tree/test-template/test.xml b/tests/cxx/tree/test-template/test.xml
new file mode 100644
index 0000000..624a80c
--- /dev/null
+++ b/tests/cxx/tree/test-template/test.xml
@@ -0,0 +1,7 @@
+<t:root xmlns:t="test"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd">
+
+ <a>a</a>
+
+</t:root>
diff --git a/tests/cxx/tree/test-template/test.xsd b/tests/cxx/tree/test-template/test.xsd
new file mode 100644
index 0000000..07bebc7
--- /dev/null
+++ b/tests/cxx/tree/test-template/test.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="type">
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/cxx/tree/types-only/driver.cxx b/tests/cxx/tree/types-only/driver.cxx
new file mode 100644
index 0000000..1d819f1
--- /dev/null
+++ b/tests/cxx/tree/types-only/driver.cxx
@@ -0,0 +1,33 @@
+// file : tests/cxx/tree/types-only/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test that code generated without parsing and serialization functions
+// still compiles.
+//
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main ()
+{
+ color_enum red (color_enum::red);
+ red_blue_enum blue (red_blue_enum::blue);
+
+ long_string_union num ("123");
+
+ string_list list;
+ list.push_back ("Hello");
+ list.push_back ("World");
+
+ complex_type t ("Hello, World!", "foo", color_enum::red);
+
+ anon a ("Hello, World!");
+}
diff --git a/tests/cxx/tree/types-only/makefile b/tests/cxx/tree/types-only/makefile
new file mode 100644
index 0000000..5d55225
--- /dev/null
+++ b/tests/cxx/tree/types-only/makefile
@@ -0,0 +1,81 @@
+# file : tests/cxx/tree/types-only/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --suppress-parsing
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/types-only/test.xsd b/tests/cxx/tree/types-only/test.xsd
new file mode 100644
index 0000000..d6ae44d
--- /dev/null
+++ b/tests/cxx/tree/types-only/test.xsd
@@ -0,0 +1,52 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="color-enum">
+ <restriction base="token">
+ <enumeration value="red"/>
+ <enumeration value="green"/>
+ <enumeration value="blue"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="red-blue-enum">
+ <restriction base="t:color-enum">
+ <enumeration value="red"/>
+ <enumeration value="blue"/>
+ </restriction>
+ </simpleType>
+
+ <simpleType name="long-string-union">
+ <union memberTypes="long string"/>
+ </simpleType>
+
+ <simpleType name="string-list">
+ <list itemType="string"/>
+ </simpleType>
+
+ <complexType name="complex-type">
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ <!-- @@ fixed="foo" -->
+ <attribute name="text" type="string" use="required" />
+ <!-- @@ fixed="red" -->
+ <attribute name="color" type="t:color-enum" use="required"/>
+ </complexType>
+
+ <!-- Test that we do not perform type/element name conflict resolution
+ as well as print any warnings. -->
+ <element name="type" type="string"/>
+
+ <!-- Test that we generate anonymous type for global element. -->
+ <element name="anon">
+ <complexType>
+ <sequence>
+ <element name="a" type="string"/>
+ </sequence>
+ </complexType>
+ </element>
+
+ <element name="root" type="t:complex-type"/>
+
+</schema>
diff --git a/tests/cxx/tree/union/ctor/driver.cxx b/tests/cxx/tree/union/ctor/driver.cxx
new file mode 100644
index 0000000..965c98c
--- /dev/null
+++ b/tests/cxx/tree/union/ctor/driver.cxx
@@ -0,0 +1,32 @@
+// file : tests/cxx/tree/union/ctor/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test union constructors.
+//
+#include <string>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+
+int
+main ()
+{
+ // Test ctor(const std::string&)
+ //
+ {
+ string const s ("123");
+ int_string_union u (s);
+ type t (s);
+ }
+
+ // Test ctor(const char*).
+ //
+ {
+ int_string_union u ("123");
+ type t ("123");
+ }
+}
diff --git a/tests/cxx/tree/union/ctor/makefile b/tests/cxx/tree/union/ctor/makefile
new file mode 100644
index 0000000..13f1ae8
--- /dev/null
+++ b/tests/cxx/tree/union/ctor/makefile
@@ -0,0 +1,82 @@
+# file : tests/cxx/tree/union/ctor/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-default-ctor \
+--generate-from-base-ctor --generate-doxygen
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver)
+ $(call message,test $$1,$$1,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/union/ctor/test.xsd b/tests/cxx/tree/union/ctor/test.xsd
new file mode 100644
index 0000000..9601093
--- /dev/null
+++ b/tests/cxx/tree/union/ctor/test.xsd
@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <simpleType name="int-string-union">
+ <union memberTypes="int string"/>
+ </simpleType>
+
+ <complexType name="type">
+ <sequence>
+ <element name="a" type="t:int-string-union"/>
+ </sequence>
+ </complexType>
+
+</schema>
diff --git a/tests/cxx/tree/union/makefile b/tests/cxx/tree/union/makefile
new file mode 100644
index 0000000..4a2d045
--- /dev/null
+++ b/tests/cxx/tree/union/makefile
@@ -0,0 +1,20 @@
+# file : tests/cxx/tree/union/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+tests := ctor
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(addprefix $(out_base)/,$(addsuffix /,$(tests)))
+$(test): $(addprefix $(out_base)/,$(addsuffix /.test,$(tests)))
+$(clean): $(addprefix $(out_base)/,$(addsuffix /.clean,$(tests)))
+
+$(foreach t,$(tests),$(call import,$(src_base)/$t/makefile))
diff --git a/tests/cxx/tree/wildcard/driver.cxx b/tests/cxx/tree/wildcard/driver.cxx
new file mode 100644
index 0000000..5f46e1b
--- /dev/null
+++ b/tests/cxx/tree/wildcard/driver.cxx
@@ -0,0 +1,202 @@
+// file : tests/cxx/tree/wildcard/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+// Test wildcard (any & anyAttribute) mapping.
+//
+
+#include <memory> // std::auto_ptr
+#include <sstream>
+#include <iostream>
+
+#include <xsd/cxx/xml/string.hxx>
+
+#include "test.hxx"
+
+using namespace std;
+using namespace test;
+using namespace xercesc;
+
+namespace xml = xsd::cxx::xml;
+
+void
+print (type& t)
+{
+ if (t.att ())
+ cout << *t.att () << endl;
+
+ type::any_attribute_set& as (t.any_attribute ());
+
+ for (type::any_attribute_iterator i (as.begin ()); i != as.end (); ++i)
+ {
+ cout << xml::transcode<char> (i->getTextContent ()) << endl;
+ }
+
+ cout << xml::transcode<char> (t.any ().getTextContent ()) << endl
+ << t.foo () << endl;
+
+ if (t.any1 ())
+ cout << xml::transcode<char> (t.any1 ()->getTextContent ()) << endl;
+
+ cout << t.bar () << endl;
+
+ type::any2_sequence& es (t.any2 ());
+
+ for (type::any2_iterator i (es.begin ()); i != es.end (); ++i)
+ {
+ cout << xml::transcode<char> (i->getTextContent ()) << endl;
+ }
+
+ cout << endl;
+}
+
+int
+main (int argc, char* argv[])
+{
+ if (argc != 2)
+ {
+ cerr << "usage: " << argv[0] << " test.xml" << endl;
+ return 1;
+ }
+
+ XMLPlatformUtils::Initialize ();
+
+ try
+ {
+ // Test accessors/modifiers for various cardinalities.
+ //
+ type t;
+
+ DOMDocument& doc (t.dom_document ());
+
+ // one
+ //
+ {
+ DOMElement* e (doc.createElement (xml::string ("a").c_str ()));
+ t.any (*e);
+ e->release ();
+ assert (xml::transcode<char> (t.any ().getTagName ()) == "a");
+
+ t.any (doc.createElement (xml::string ("b").c_str ()));
+ assert (xml::transcode<char> (t.any ().getTagName ()) == "b");
+ }
+
+ // optional
+ //
+ {
+ assert (!t.any1 ().present ());
+
+ DOMElement* e (doc.createElement (xml::string ("a").c_str ()));
+ t.any1 (*e);
+ e->release ();
+ assert (t.any1 ().present ());
+ assert (xml::transcode<char> (t.any1 ().get ().getTagName ()) == "a");
+
+ t.any1 (doc.createElement (xml::string ("b").c_str ()));
+ assert (xml::transcode<char> (t.any1 ()->getTagName ()) == "b");
+
+ type::any1_optional c (
+ doc.createElement (xml::string ("c").c_str ()), doc);
+ t.any1 (c);
+ assert (xml::transcode<char> (t.any1 ()->getTagName ()) == "c");
+ }
+
+
+ // sequence
+ //
+ {
+ type::any2_sequence& s (t.any2 ());
+
+ DOMElement* e (doc.createElement (xml::string ("a").c_str ()));
+ s.push_back (*e);
+ e->release ();
+ s.push_back (doc.createElement (xml::string ("b").c_str ()));
+ assert (s.size () == 2);
+
+ for (type::any2_iterator i (s.begin ()); i != s.end (); ++i)
+ {
+ if (i == s.begin ())
+ assert (xml::transcode<char> (i->getTagName ()) == "a");
+ else
+ assert (xml::transcode<char> ((*i).getTagName ()) == "b");
+ }
+
+ // copy c-tor
+ type::any2_sequence cs (s, doc);
+ assert (cs.size () == 2);
+ assert (xml::transcode<char> (cs[0].getTagName ()) == "a");
+ assert (xml::transcode<char> (cs[1].getTagName ()) == "b");
+
+ // assignment
+ t.any2 (cs);
+ assert (s.size () == 2);
+ assert (xml::transcode<char> (s[0].getTagName ()) == "a");
+ assert (xml::transcode<char> (s[1].getTagName ()) == "b");
+ }
+
+ // anyAttribute
+ //
+ {
+ type::any_attribute_set& s (t.any_attribute ());
+
+ DOMAttr* a (doc.createAttribute (xml::string ("a").c_str ()));
+ s.insert (*a);
+ a->release ();
+ s.insert (doc.createAttribute (xml::string ("b").c_str ()));
+ assert (s.size () == 2);
+
+ assert (s.find ("a") != s.end ());
+ assert (s.find ("b") != s.end ());
+
+ for (type::any_attribute_iterator i (s.begin ()); i != s.end (); ++i)
+ {
+ assert (xml::transcode<char> (i->getName ()) == "a" ||
+ xml::transcode<char> ((*i).getName ()) == "b");
+ }
+
+ // copy c-tor
+ type::any_attribute_set cs (s, doc);
+ assert (cs.size () == 2);
+ assert (cs.count ("a"));
+ assert (cs.count ("b"));
+
+ // assignment
+ t.any_attribute (cs);
+ assert (s.size () == 2);
+ assert (s.count ("a"));
+ assert (s.count ("b"));
+ }
+
+ // Test parsing
+ //
+ auto_ptr<type> r (root (argv[1]));
+ print (*r);
+
+ // Test serialization.
+ //
+ xml_schema::namespace_infomap map;
+
+ map["t"].name = "test";
+ map["t"].schema = "test.xsd";
+ map["o"].name = "other";
+
+ stringstream iostr;
+ root (iostr, *r, map);
+
+ // cout << iostr.str () << endl
+ // << endl;
+
+ auto_ptr<type> copy (root (iostr, argv[1]));
+ assert (*copy == *r);
+
+ print (*copy);
+ }
+ catch (xml_schema::exception const& e)
+ {
+ cerr << e << endl;
+ return 1;
+ }
+
+ XMLPlatformUtils::Terminate ();
+}
diff --git a/tests/cxx/tree/wildcard/makefile b/tests/cxx/tree/wildcard/makefile
new file mode 100644
index 0000000..6d5eb83
--- /dev/null
+++ b/tests/cxx/tree/wildcard/makefile
@@ -0,0 +1,83 @@
+# file : tests/cxx/tree/wildcard/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../../../../build/bootstrap.make
+
+xsd := test.xsd
+cxx := driver.cxx
+
+obj := $(addprefix $(out_base)/,$(cxx:.cxx=.o) $(xsd:.xsd=.o))
+dep := $(obj:.o=.o.d)
+
+driver := $(out_base)/driver
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libxerces-c/stub.make,\
+ l: xerces_c.l,cpp-options: xerces_c.l.cpp-options)
+
+
+# Build.
+#
+$(driver): $(obj) $(xerces_c.l)
+
+$(obj) $(dep): cpp_options := -I$(src_root)/libxsd
+$(obj) $(dep): $(xerces_c.l.cpp-options)
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd := $(out_root)/xsd/xsd
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): xsd_options := --generate-wildcard \
+--generate-default-ctor --generate-from-base-ctor \
+--generate-serialization --generate-comparison
+
+$(out_base)/$(xsd:.xsd=.hxx) \
+$(out_base)/$(xsd:.xsd=.ixx) \
+$(out_base)/$(xsd:.xsd=.cxx): $(out_root)/xsd/xsd
+
+$(call include-dep,$(dep))
+
+# Convenience alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(driver)
+
+
+# Test.
+#
+.PHONY: $(test)
+
+$(test): driver := $(driver)
+$(test): $(driver) $(src_base)/test.xml $(src_base)/output
+ $(call message,test $$1,$$1 $(src_base)/test.xml | diff -u $(src_base)/output -,$(driver))
+
+# Clean.
+#
+.PHONY: $(clean)
+
+$(clean): $(driver).o.clean \
+ $(addsuffix .cxx.clean,$(obj)) \
+ $(addsuffix .cxx.clean,$(dep)) \
+ $(addprefix $(out_base)/,$(xsd:.xsd=.cxx.xsd.clean))
+
+
+# How to.
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(scf_root)/xsd/tree/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsd/makefile)
diff --git a/tests/cxx/tree/wildcard/output b/tests/cxx/tree/wildcard/output
new file mode 100644
index 0000000..b23b488
--- /dev/null
+++ b/tests/cxx/tree/wildcard/output
@@ -0,0 +1,24 @@
+att
+any
+o:any
+t:any
+o:one
+foo
+t:bar
+bar
+o:one1
+o:one2
+o:one3
+
+att
+any
+o:any
+t:any
+o:one
+foo
+t:bar
+bar
+o:one1
+o:one2
+o:one3
+
diff --git a/tests/cxx/tree/wildcard/test.xml b/tests/cxx/tree/wildcard/test.xml
new file mode 100644
index 0000000..b0c3267
--- /dev/null
+++ b/tests/cxx/tree/wildcard/test.xml
@@ -0,0 +1,19 @@
+<t:root xmlns:t="test"
+ xmlns:o="other"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="test test.xsd"
+
+ att="att"
+ any="any"
+ t:any="t:any"
+ o:any="o:any">
+
+ <o:one>o:one</o:one>
+ <foo>foo</foo>
+ <t:bar>t:bar</t:bar>
+ <bar>bar</bar>
+ <o:seq1>o:one1</o:seq1>
+ <o:seq2>o:one2</o:seq2>
+ <o:seq3>o:one3</o:seq3>
+
+</t:root>
diff --git a/tests/cxx/tree/wildcard/test.xsd b/tests/cxx/tree/wildcard/test.xsd
new file mode 100644
index 0000000..6c7b308
--- /dev/null
+++ b/tests/cxx/tree/wildcard/test.xsd
@@ -0,0 +1,18 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <complexType name="type">
+ <sequence>
+ <any namespace="##other" processContents="skip"/>
+ <element name="foo" type="string"/>
+ <any namespace="##targetNamespace" minOccurs="0" processContents="skip"/>
+ <element name="bar" type="string"/>
+ <any namespace="##other" maxOccurs="unbounded" processContents="skip"/>
+ </sequence>
+ <attribute name="att" type="string"/>
+ <anyAttribute namespace="##any" processContents="skip"/>
+ </complexType>
+
+ <element name="root" type="t:type"/>
+
+</schema>
diff --git a/tests/failed/test-00.xsd b/tests/failed/test-00.xsd
new file mode 100644
index 0000000..5223f82
--- /dev/null
+++ b/tests/failed/test-00.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:element name="foo">
+ <xsd:complexType/>
+ </xsd:element>
+
+</xsd:schema>
diff --git a/tests/makefile b/tests/makefile
new file mode 100644
index 0000000..f966c5c
--- /dev/null
+++ b/tests/makefile
@@ -0,0 +1,18 @@
+# file : tests/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
+
+default := $(out_base)/
+test := $(out_base)/.test
+clean := $(out_base)/.clean
+
+.PHONY: $(default) $(test) $(clean)
+
+$(default): $(out_base)/cxx/
+$(test): $(out_base)/cxx/.test
+$(clean): $(out_base)/cxx/.clean
+
+$(call import,$(src_base)/cxx/makefile)
diff --git a/tests/morphing/anonymous/attribute-group/test.xsd b/tests/morphing/anonymous/attribute-group/test.xsd
new file mode 100644
index 0000000..657be8a
--- /dev/null
+++ b/tests/morphing/anonymous/attribute-group/test.xsd
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- Attribute Group that names anonymous type. -->
+
+ <xsd:attributeGroup name="gfoo-1">
+ <xsd:attribute name="afoo-1">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:attributeGroup>
+
+ <xsd:attributeGroup name="gfoo-2">
+ <xsd:attributeGroup ref="gfoo-1"/>
+ <xsd:attribute name="afoo-2" type="xsd:string"/>
+ </xsd:attributeGroup>
+
+ <xsd:complexType name="Foo1">
+ <xsd:attributeGroup ref="gfoo-1"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="Foo2">
+ <xsd:attributeGroup ref="gfoo-2"/>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/tests/morphing/anonymous/cyclic-inclusion/includee.xsd b/tests/morphing/anonymous/cyclic-inclusion/includee.xsd
new file mode 100644
index 0000000..51f7916
--- /dev/null
+++ b/tests/morphing/anonymous/cyclic-inclusion/includee.xsd
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:t="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:include schemaLocation="includer.xsd"/>
+
+ <xsd:element name="bar">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="t:foo"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+</xsd:schema>
diff --git a/tests/morphing/anonymous/cyclic-inclusion/includer.xsd b/tests/morphing/anonymous/cyclic-inclusion/includer.xsd
new file mode 100644
index 0000000..54e6b69
--- /dev/null
+++ b/tests/morphing/anonymous/cyclic-inclusion/includer.xsd
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:t="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:include schemaLocation="includee.xsd"/>
+
+ <xsd:element name="foo">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+</xsd:schema>
diff --git a/tests/morphing/anonymous/group/test.xsd b/tests/morphing/anonymous/group/test.xsd
new file mode 100644
index 0000000..73e07af
--- /dev/null
+++ b/tests/morphing/anonymous/group/test.xsd
@@ -0,0 +1,29 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- Simple case. -->
+
+ <xsd:group name="gfoo">
+ <xsd:sequence>
+ <xsd:element name="foo-1">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:group>
+
+
+ <xsd:complexType name="Foo">
+ <xsd:group ref="gfoo"/>
+ </xsd:complexType>
+
+ <xsd:complexType name="Bar">
+ <xsd:group ref="gfoo"/>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/tests/morphing/anonymous/test-000.xsd b/tests/morphing/anonymous/test-000.xsd
new file mode 100644
index 0000000..ce930d8
--- /dev/null
+++ b/tests/morphing/anonymous/test-000.xsd
@@ -0,0 +1,20 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- Test xpath for nested anonymous types. -->
+
+ <element name="a">
+ <complexType>
+ <sequence>
+ <element name="b">
+ <complexType>
+ <sequence>
+ <element name="c" type="string"/>
+ </sequence>
+ </complexType>
+ </element>
+ </sequence>
+ </complexType>
+ </element>
+
+</schema>
diff --git a/tests/morphing/anonymous/unstable/includee-1.xsd b/tests/morphing/anonymous/unstable/includee-1.xsd
new file mode 100644
index 0000000..916816f
--- /dev/null
+++ b/tests/morphing/anonymous/unstable/includee-1.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:simpleType name="base">
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+</xsd:schema>
diff --git a/tests/morphing/anonymous/unstable/includee-2.xsd b/tests/morphing/anonymous/unstable/includee-2.xsd
new file mode 100644
index 0000000..eb8222c
--- /dev/null
+++ b/tests/morphing/anonymous/unstable/includee-2.xsd
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:element name="base">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+ </xsd:element>
+
+</xsd:schema>
diff --git a/tests/morphing/anonymous/unstable/includer.xsd b/tests/morphing/anonymous/unstable/includer.xsd
new file mode 100644
index 0000000..4593b5f
--- /dev/null
+++ b/tests/morphing/anonymous/unstable/includer.xsd
@@ -0,0 +1,18 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:Test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:include schemaLocation="includee-1.xsd"/>
+ <xsd:include schemaLocation="includee-2.xsd"/>
+
+ <xsd:simpleType name="derived">
+ <xsd:restriction base="Test:base"/>
+ </xsd:simpleType>
+
+ <xsd:element name="element" type="Test:base"/>
+ <xsd:attribute name="attribute" type="Test:base"/>
+
+</xsd:schema>
diff --git a/tests/processing/inheritance/test-000.xsd b/tests/processing/inheritance/test-000.xsd
new file mode 100644
index 0000000..ef1ef71
--- /dev/null
+++ b/tests/processing/inheritance/test-000.xsd
@@ -0,0 +1,22 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- Type base "depends" on itself via e element -->
+
+ <element name="e">
+ <complexType>
+ <complexContent>
+ <extension base="t:base"/>
+ </complexContent>
+ </complexType>
+ </element>
+
+ <complexType name="base">
+ <sequence>
+ <element ref="t:e"/>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:base"/>
+
+</schema>
diff --git a/tests/processing/inheritance/test-001.xsd b/tests/processing/inheritance/test-001.xsd
new file mode 100644
index 0000000..5afc997
--- /dev/null
+++ b/tests/processing/inheritance/test-001.xsd
@@ -0,0 +1,26 @@
+<?xml version="1.0"?>
+<schema xmlns="http://www.w3.org/2001/XMLSchema" xmlns:t="test" targetNamespace="test">
+
+ <!-- Type base depends on derived which in turn depends on base -->
+
+ <complexType name="derived">
+ <complexContent>
+ <extension base="t:base"/>
+ </complexContent>
+ </complexType>
+
+ <complexType name="base">
+ <sequence>
+ <element name="e">
+ <complexType>
+ <complexContent>
+ <extension base="t:derived"/>
+ </complexContent>
+ </complexType>
+ </element>
+ </sequence>
+ </complexType>
+
+ <element name="root" type="t:base"/>
+
+</schema>
diff --git a/tests/schema/anonymous/test.xsd b/tests/schema/anonymous/test.xsd
new file mode 100644
index 0000000..cba3300
--- /dev/null
+++ b/tests/schema/anonymous/test.xsd
@@ -0,0 +1,143 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- Test 'type' name escaping. -->
+ <xsd:element name="type">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+
+
+ <!-- Anonymous type via global element. -->
+ <xsd:element name="global_element">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+
+
+ <!-- Anonymous type via global attribute. -->
+ <xsd:attribute name="global_attribute">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+ </xsd:attribute>
+
+
+
+ <!-- Anonymous type via local element. -->
+ <xsd:complexType name="local_element_type">
+ <xsd:sequence>
+ <xsd:element name="local_element">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+
+ <!-- Anonymous type via local attribute. -->
+ <xsd:complexType name="local_attribute_type">
+ <xsd:attribute name="local_attribute">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:complexType>
+
+<!--
+
+ Various weird anonymous type combinations (some of them are fruits of a
+ really sick imagination).
+
+-->
+
+ <xsd:element name="tasks">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="test:periodicTask"/>
+ <xsd:element ref="test:braindamageTask"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="periodicTask">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="test:tasks"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="braindamageTask">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="test:tasks"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+
+ <xsd:complexType name="PropertySeq">
+ <xsd:sequence>
+ <xsd:element name="propery">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element name="value">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="typecode">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NCName">
+ <xsd:enumeration value="string"/>
+ <xsd:enumeration value="integer"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+ <xsd:element name="content" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <xsd:element name="periods">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element name="period" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+
+ <xsd:element name="typecode">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:NCName">
+ <xsd:enumeration value="string"/>
+ <xsd:enumeration value="integer"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:element>
+
+
+</xsd:schema>
diff --git a/tests/schema/any-attribute/test.xsd b/tests/schema/any-attribute/test.xsd
new file mode 100644
index 0000000..55419c4
--- /dev/null
+++ b/tests/schema/any-attribute/test.xsd
@@ -0,0 +1,22 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+
+ <xsd:complexType name="type">
+ <xsd:attribute name="a" type="xsd:string"/>
+ <xsd:anyAttribute namespace="##other" processContents="skip"/>
+ <xsd:attributeGroup ref="test:agroup"/>
+ </xsd:complexType>
+
+ <xsd:attributeGroup name="agroup">
+ <xsd:attribute name="b" type="xsd:string"/>
+ <xsd:anyAttribute namespace="##any" processContents="skip"/>
+ </xsd:attributeGroup>
+
+ <xsd:element name="root" type="test:type"/>
+
+</xsd:schema>
diff --git a/tests/schema/any-type/test.xsd b/tests/schema/any-type/test.xsd
new file mode 100644
index 0000000..9e3ff79
--- /dev/null
+++ b/tests/schema/any-type/test.xsd
@@ -0,0 +1,22 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="name"/> <!-- type="anyType" -->
+ <xsd:element name="name2" type="xsd:anyType" minOccurs="0"/>
+ <xsd:element name="name3" type="xsd:anyType" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="id"/> <!-- type="anySimpleType" -->
+ <xsd:attribute name="id2" type="xsd:anySimpleType" use="required"/>
+ </xsd:complexType>
+
+ <xsd:element name="person" type="test:person"/>
+
+ <xsd:element name="name"/> <!-- type="anyType" -->
+
+</xsd:schema>
diff --git a/tests/schema/any/fail.xsd b/tests/schema/any/fail.xsd
new file mode 100644
index 0000000..2eb9513
--- /dev/null
+++ b/tests/schema/any/fail.xsd
@@ -0,0 +1,19 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:element name="foo" type="xsd:string"/>
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:element ref="test:foo"/>
+ <xsd:any namespace="##any" processContents="strict"/>
+ <xsd:any namespace="http://www.codesynthesis.com/xmlns/test" processContents="strict"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/tests/schema/any/test.xsd b/tests/schema/any/test.xsd
new file mode 100644
index 0000000..ff896fd
--- /dev/null
+++ b/tests/schema/any/test.xsd
@@ -0,0 +1,19 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:complexType name="person">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ <xsd:any namespace="##other" processContents="strict" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ <xsd:attribute name="id" type="xsd:ID"/>
+ <xsd:anyAttribute namespace="##other" processContents="strict"/>
+ </xsd:complexType>
+
+ <xsd:element name="person" type="test:person"/>
+
+</xsd:schema>
diff --git a/tests/schema/attribute-group/global.xsd b/tests/schema/attribute-group/global.xsd
new file mode 100644
index 0000000..6ee0539
--- /dev/null
+++ b/tests/schema/attribute-group/global.xsd
@@ -0,0 +1,50 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- Simple case. -->
+
+ <xsd:attributeGroup name="gfoo_1">
+ <xsd:attribute name="foo_1_1" type="xsd:string"/>
+ <xsd:attribute name="foo_1_2" type="xsd:string"/>
+ </xsd:attributeGroup>
+
+ <xsd:attributeGroup name="gfoo_2">
+ <xsd:attributeGroup ref="gfoo_1"/>
+ <xsd:attribute name="foo_2_1" type="xsd:string"/>
+ <xsd:attribute name="foo_2_2" type="xsd:string"/>
+ </xsd:attributeGroup>
+
+ <xsd:complexType name="Foo">
+ <xsd:attributeGroup ref="gfoo_2"/>
+ </xsd:complexType>
+
+
+
+ <!-- Forward reference. -->
+
+ <xsd:attributeGroup name="gbar_3">
+ <xsd:attribute name="bar_3_1" type="xsd:string"/>
+ <xsd:attribute name="bar_3_2" type="xsd:string"/>
+ <xsd:attributeGroup ref="gbar_1"/>
+ </xsd:attributeGroup>
+
+ <xsd:complexType name="Bar">
+ <xsd:attributeGroup ref="gbar_2"/>
+ </xsd:complexType>
+
+ <xsd:attributeGroup name="gbar_2">
+ <xsd:attributeGroup ref="gbar_3"/>
+ <xsd:attribute name="bar_2_1" type="xsd:string"/>
+ <xsd:attribute name="bar_2_2" type="xsd:string"/>
+ </xsd:attributeGroup>
+
+ <xsd:attributeGroup name="gbar_1">
+ <xsd:attribute name="bar_1_1" type="xsd:string"/>
+ <xsd:attribute name="bar_1_2" type="xsd:string"/>
+ </xsd:attributeGroup>
+
+</xsd:schema>
diff --git a/tests/schema/attribute/global.xsd b/tests/schema/attribute/global.xsd
new file mode 100644
index 0000000..e2dcc93
--- /dev/null
+++ b/tests/schema/attribute/global.xsd
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- Typed with named type. -->
+
+ <xsd:attribute name="foo" type="xsd:string"/>
+
+
+ <!-- Typed with anonymous type. -->
+
+ <xsd:attribute name="bar">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+ </xsd:attribute>
+
+</xsd:schema>
diff --git a/tests/schema/attribute/local.xsd b/tests/schema/attribute/local.xsd
new file mode 100644
index 0000000..7a7a480
--- /dev/null
+++ b/tests/schema/attribute/local.xsd
@@ -0,0 +1,37 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+
+ <!-- Typed with named type. -->
+
+ <xsd:complexType name="Foo">
+ <xsd:attribute name="foo" type="xsd:string"/>
+ </xsd:complexType>
+
+
+ <!-- Forward reference to a yet undeclared type. -->
+
+ <xsd:complexType name="Bar">
+ <xsd:attribute name="bar" type="Bar2"/>
+ </xsd:complexType>
+
+ <xsd:simpleType name="Bar2">
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+
+ <!-- Typed with anonymous type. -->
+
+ <xsd:complexType name="Baz">
+ <xsd:attribute name="baz">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/tests/schema/attribute/ref.xsd b/tests/schema/attribute/ref.xsd
new file mode 100644
index 0000000..f6c3c10
--- /dev/null
+++ b/tests/schema/attribute/ref.xsd
@@ -0,0 +1,42 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+
+ <!-- Easy case. -->
+
+ <xsd:attribute name="foo" type="xsd:string"/>
+
+ <xsd:complexType name="Foo">
+ <xsd:attribute ref="foo"/>
+ </xsd:complexType>
+
+
+
+ <!-- Forward reference to a yet undeclared attribute. -->
+
+ <xsd:complexType name="Bar">
+ <xsd:attribute ref="bar"/>
+ </xsd:complexType>
+
+ <xsd:attribute name="bar" type="xsd:string"/>
+
+
+
+ <!-- Reference to an attribute with a forward reference to a yet
+ undeclared type. -->
+
+ <xsd:attribute name="baz" type="Baz2"/>
+
+ <xsd:complexType name="Baz">
+ <xsd:attribute ref="baz"/>
+ </xsd:complexType>
+
+ <xsd:simpleType name="Baz2">
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+</xsd:schema>
diff --git a/tests/schema/cardinality/test.xsd b/tests/schema/cardinality/test.xsd
new file mode 100644
index 0000000..b27f923
--- /dev/null
+++ b/tests/schema/cardinality/test.xsd
@@ -0,0 +1,46 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!--
+ This test tries to cover various cardinality cases with
+ built-in and user-defined types.
+ -->
+
+ <xsd:complexType name="Foo">
+ <xsd:sequence>
+ <xsd:element name="foo" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="Bar">
+ <xsd:sequence>
+
+ <xsd:element name="one-int" type="xsd:int"/>
+ <xsd:element name="opt-int" type="xsd:int" minOccurs="0"/>
+ <xsd:element name="seq-int" type="xsd:int" maxOccurs="unbounded"/>
+
+ <xsd:element name="one-string" type="xsd:string"/>
+ <xsd:element name="opt-string" type="xsd:string" minOccurs="0"/>
+ <xsd:element name="seq-string" type="xsd:string" maxOccurs="unbounded"/>
+
+ <xsd:element name="one-foo" type="test:Foo"/>
+ <xsd:element name="opt-foo" type="test:Foo" minOccurs="0"/>
+ <xsd:element name="seq-foo" type="test:Foo" maxOccurs="unbounded"/>
+
+ </xsd:sequence>
+
+ <xsd:attribute name="one-int-a" type="xsd:int" use="required"/>
+ <xsd:attribute name="opt-int-a" type="xsd:int"/>
+
+ <xsd:attribute name="one-string-a" type="xsd:string" use="required"/>
+ <xsd:attribute name="opt-string-a" type="xsd:string"/>
+
+ </xsd:complexType>
+
+ <xsd:element name="bar" type="test:Bar"/>
+
+</xsd:schema>
diff --git a/tests/schema/chameleon/includer.xsd b/tests/schema/chameleon/includer.xsd
new file mode 100644
index 0000000..c93ea18
--- /dev/null
+++ b/tests/schema/chameleon/includer.xsd
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:Test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:include schemaLocation="schemas/includee.xsd"/>
+
+ <xsd:simpleType name="derived">
+ <xsd:restriction base="Test:base"/>
+ </xsd:simpleType>
+
+ <xsd:element name="element" type="Test:base"/>
+ <xsd:attribute name="attribute" type="Test:base"/>
+
+</xsd:schema>
diff --git a/tests/schema/chameleon/schemas/includee.xsd b/tests/schema/chameleon/schemas/includee.xsd
new file mode 100644
index 0000000..d89b9c4
--- /dev/null
+++ b/tests/schema/chameleon/schemas/includee.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd">
+
+ <xsd:simpleType name="base">
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+ <xsd:element name="base_e" type="base"/>
+
+</xsd:schema>
diff --git a/tests/schema/enumeration/test.xsd b/tests/schema/enumeration/test.xsd
new file mode 100644
index 0000000..b8253d9
--- /dev/null
+++ b/tests/schema/enumeration/test.xsd
@@ -0,0 +1,89 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- string-based -->
+
+ <xsd:simpleType name="StringEnum">
+ <xsd:restriction base="xsd:string">
+ <xsd:enumeration value="one"/>
+ <xsd:enumeration value="two"/>
+ <xsd:enumeration value="three"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="StringSimple">
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+ <!-- inheritance of a enum from a simple type -->
+ <xsd:simpleType name="StringSimpleRestriction">
+ <xsd:restriction base="test:StringSimple">
+ <xsd:enumeration value="one"/>
+ <xsd:enumeration value="two"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- inheritance of a enum from a strig-based enum -->
+ <xsd:simpleType name="StringEnumRestriction">
+ <xsd:restriction base="test:StringEnum">
+ <xsd:enumeration value="one"/>
+ <xsd:enumeration value="two"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- inheritance of a complex type from a string-based enum -->
+ <xsd:complexType name="StringComplex">
+ <xsd:simpleContent>
+ <xsd:extension base="test:StringEnumRestriction">
+ <xsd:attribute name="lang" type="xsd:language"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+
+
+ <!-- non string-based -->
+
+ <xsd:simpleType name="IntEnum">
+ <xsd:restriction base="xsd:int">
+ <xsd:enumeration value="1"/>
+ <xsd:enumeration value="2"/>
+ <xsd:enumeration value="3"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="IntSimple">
+ <xsd:restriction base="xsd:int"/>
+ </xsd:simpleType>
+
+ <!-- inheritance of a enum from a simple type -->
+ <xsd:simpleType name="IntSimpleRestriction">
+ <xsd:restriction base="test:IntSimple">
+ <xsd:enumeration value="1"/>
+ <xsd:enumeration value="2"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- inheritance of a enum from a enum -->
+ <xsd:simpleType name="IntEnumRestriction">
+ <xsd:restriction base="test:IntEnum">
+ <xsd:enumeration value="1"/>
+ <xsd:enumeration value="2"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+
+ <!-- inheritance of a complex type from a enum -->
+ <xsd:complexType name="IntComplex">
+ <xsd:simpleContent>
+ <xsd:extension base="test:IntEnumRestriction">
+ <xsd:attribute name="lang" type="xsd:language"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+
+</xsd:schema>
diff --git a/tests/schema/forward/test.xsd b/tests/schema/forward/test.xsd
new file mode 100644
index 0000000..c7cc24e
--- /dev/null
+++ b/tests/schema/forward/test.xsd
@@ -0,0 +1,32 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+<!--
+
+ Various weird forward reference combinations.
+
+-->
+
+ <!-- case 1 -->
+
+ <xsd:complexType name="Type1A">
+ <xsd:complexContent>
+ <xsd:extension base="test:Type1B">
+ <xsd:sequence>
+ <xsd:element name="bar" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="Type1B">
+ <xsd:sequence>
+ <xsd:element name="foo" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/tests/schema/group/global.xsd b/tests/schema/group/global.xsd
new file mode 100644
index 0000000..27ccadf
--- /dev/null
+++ b/tests/schema/group/global.xsd
@@ -0,0 +1,39 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- Simple case. -->
+
+ <xsd:group name="gfoo">
+ <xsd:sequence>
+ <xsd:element name="foo_1" type="xsd:string"/>
+ <xsd:element name="foo_2" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:group>
+
+
+ <xsd:complexType name="Foo">
+ <xsd:group ref="gfoo"/>
+ </xsd:complexType>
+
+
+
+ <!-- Forward reference. -->
+
+ <xsd:complexType name="Bar">
+ <xsd:group ref="gbar"/>
+ </xsd:complexType>
+
+ <xsd:group name="gbar">
+ <xsd:choice>
+ <xsd:element name="bar_1" type="xsd:string"/>
+ <xsd:element ref="bar_2"/>
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:element name="bar_2" type="xsd:string"/>
+
+</xsd:schema>
diff --git a/tests/schema/group/test.xsd b/tests/schema/group/test.xsd
new file mode 100644
index 0000000..7527cbb
--- /dev/null
+++ b/tests/schema/group/test.xsd
@@ -0,0 +1,148 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!--
+
+ Various weird group combinations.
+
+ -->
+
+ <!-- case 1 -->
+
+ <xsd:group name="g1">
+ <xsd:sequence>
+ <xsd:element name="e1" type="xsd:string"/>
+ <xsd:element name="e2" type="xsd:long"/>
+ </xsd:sequence>
+ </xsd:group>
+
+ <xsd:complexType name="Type1">
+ <xsd:sequence>
+ <xsd:group ref="test:g1"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- case 2 -->
+
+ <xsd:group name="g2">
+ <xsd:sequence>
+ <xsd:element ref="test:g2e1"/>
+ </xsd:sequence>
+ </xsd:group>
+
+ <xsd:complexType name="TypeTwo">
+ <xsd:sequence>
+ <xsd:group ref="test:g2"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="g2e1" type="xsd:string"/>
+
+ <!-- case 3 -->
+
+ <xsd:complexType name="Type3">
+ <xsd:sequence>
+ <xsd:group ref="test:g3"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:group name="g3">
+ <xsd:sequence>
+ <xsd:element ref="test:g3e1"/>
+ </xsd:sequence>
+ </xsd:group>
+
+ <xsd:element name="g3e1" type="xsd:string"/>
+
+ <!-- case 4 -->
+
+ <xsd:complexType name="Type4A">
+ <xsd:sequence>
+ <xsd:group ref="test:g4" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="Type4B">
+ <xsd:sequence minOccurs="0">
+ <xsd:group ref="test:g4"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <xsd:group name="g4">
+ <xsd:sequence>
+ <xsd:element name="e1" type="xsd:string"/>
+ <xsd:element name="e2" type="xsd:long" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:group>
+
+ <xsd:complexType name="Type4C">
+ <xsd:sequence>
+ <xsd:group ref="test:g4" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- case 5 -->
+
+ <xsd:group name="g5-1">
+ <xsd:choice>
+ <xsd:group ref="test:g5-2"/>
+ <xsd:element name="e1" type="xsd:string"/>
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:group name="g5-2">
+ <xsd:choice>
+ <xsd:group ref="test:g5-3"/>
+ <xsd:element name="e2" type="xsd:string"/>
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:group name="g5-3">
+ <xsd:choice>
+ <xsd:element name="e3" type="xsd:long"/>
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:complexType name="Type5">
+ <xsd:choice>
+ <xsd:group ref="test:g5-1"/>
+ </xsd:choice>
+ </xsd:complexType>
+
+ <!-- case 6 -->
+
+ <xsd:group name="g6-3">
+ <xsd:choice>
+ <xsd:group ref="test:g6-1"/>
+ <xsd:element name="e_3_1" type="xsd:string"/>
+ <xsd:element name="e_3_2" type="xsd:string"/>
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:complexType name="Type6">
+ <xsd:choice>
+ <xsd:group ref="test:g6-2"/>
+ </xsd:choice>
+ </xsd:complexType>
+
+ <xsd:group name="g6-2">
+ <xsd:choice>
+ <xsd:group ref="test:g6-3"/>
+ <xsd:element name="e_2_1" type="xsd:string"/>
+ <xsd:element name="e_2_2" type="xsd:string"/>
+ </xsd:choice>
+ </xsd:group>
+
+ <xsd:group name="g6-1">
+ <xsd:choice>
+ <xsd:element name="e_1_1" type="xsd:string"/>
+ <xsd:element name="e_1_2" type="xsd:string"/>
+ </xsd:choice>
+ </xsd:group>
+
+</xsd:schema>
diff --git a/tests/schema/import/importer.xsd b/tests/schema/import/importer.xsd
new file mode 100644
index 0000000..82fc33c
--- /dev/null
+++ b/tests/schema/import/importer.xsd
@@ -0,0 +1,20 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:Test="http://www.codesynthesis.com/xmlns/test"
+ xmlns:Impl="http://www.codesynthesis.com/xmlns/test/impl"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test/impl">
+
+ <!-- <xsd::element name="foo" type="xsd:string"/> -->
+
+ <xsd:import namespace="http://www.codesynthesis.com/xmlns/test" schemaLocation="schemas/importee.xsd"/>
+
+ <xsd:simpleType name="derived">
+ <xsd:restriction base="Test:base"/>
+ </xsd:simpleType>
+
+ <xsd:element name="element" type="Test:base"/>
+ <xsd:attribute name="attribute" type="Test:base"/>
+
+</xsd:schema>
diff --git a/tests/schema/import/schemas/importee.xsd b/tests/schema/import/schemas/importee.xsd
new file mode 100644
index 0000000..9b03315
--- /dev/null
+++ b/tests/schema/import/schemas/importee.xsd
@@ -0,0 +1,15 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+
+ <xsd:simpleType name="base">
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+ <xsd:element name="base_e" type="test:base"/>
+
+</xsd:schema>
diff --git a/tests/schema/include/includer.xsd b/tests/schema/include/includer.xsd
new file mode 100644
index 0000000..c93ea18
--- /dev/null
+++ b/tests/schema/include/includer.xsd
@@ -0,0 +1,17 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:Test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:include schemaLocation="schemas/includee.xsd"/>
+
+ <xsd:simpleType name="derived">
+ <xsd:restriction base="Test:base"/>
+ </xsd:simpleType>
+
+ <xsd:element name="element" type="Test:base"/>
+ <xsd:attribute name="attribute" type="Test:base"/>
+
+</xsd:schema>
diff --git a/tests/schema/include/schemas/includee.xsd b/tests/schema/include/schemas/includee.xsd
new file mode 100644
index 0000000..0a928f5
--- /dev/null
+++ b/tests/schema/include/schemas/includee.xsd
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:simpleType name="base">
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+ <xsd:element name="base_e" type="test:base"/>
+
+</xsd:schema>
diff --git a/tests/schema/inheritance/cycle.xsd b/tests/schema/inheritance/cycle.xsd
new file mode 100644
index 0000000..c705311
--- /dev/null
+++ b/tests/schema/inheritance/cycle.xsd
@@ -0,0 +1,34 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:complexType name="Base">
+ <xsd:sequence>
+ <xsd:element name="e1">
+ <xsd:complexType>
+ <xsd:complexContent>
+ <xsd:extension base="test:Derived">
+ <xsd:sequence>
+ <xsd:element name="e2" type="xsd:int"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="Derived">
+ <xsd:complexContent>
+ <xsd:extension base="test:Base">
+ <xsd:sequence>
+ <xsd:element name="e3" type="xsd:int"/>
+ </xsd:sequence>
+ </xsd:extension>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/tests/schema/inheritance/sourced-forward/includee.xsd b/tests/schema/inheritance/sourced-forward/includee.xsd
new file mode 100644
index 0000000..531027d
--- /dev/null
+++ b/tests/schema/inheritance/sourced-forward/includee.xsd
@@ -0,0 +1,10 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd">
+
+ <xsd:simpleType name="Derived">
+ <xsd:restriction base="Base"/>
+ </xsd:simpleType>
+
+</xsd:schema>
diff --git a/tests/schema/inheritance/sourced-forward/includer.xsd b/tests/schema/inheritance/sourced-forward/includer.xsd
new file mode 100644
index 0000000..7d18efc
--- /dev/null
+++ b/tests/schema/inheritance/sourced-forward/includer.xsd
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:include schemaLocation="includee.xsd"/>
+
+ <xsd:simpleType name="Base">
+ <xsd:restriction base="xsd:string"/>
+ </xsd:simpleType>
+
+</xsd:schema>
diff --git a/tests/schema/list/anonymous/test.xsd b/tests/schema/list/anonymous/test.xsd
new file mode 100644
index 0000000..7db39ba
--- /dev/null
+++ b/tests/schema/list/anonymous/test.xsd
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:simpleType name="IntList">
+ <xsd:list>
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:int"/>
+ </xsd:simpleType>
+ </xsd:list>
+ </xsd:simpleType>
+
+</xsd:schema>
diff --git a/tests/schema/list/any-simple-type/test.xsd b/tests/schema/list/any-simple-type/test.xsd
new file mode 100644
index 0000000..29fe95c
--- /dev/null
+++ b/tests/schema/list/any-simple-type/test.xsd
@@ -0,0 +1,12 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:simpleType name="any">
+ <xsd:list itemType="xsd:anySimpleType"/>
+ </xsd:simpleType>
+
+</xsd:schema>
diff --git a/tests/schema/list/driver.cxx b/tests/schema/list/driver.cxx
new file mode 100644
index 0000000..7bd46e9
--- /dev/null
+++ b/tests/schema/list/driver.cxx
@@ -0,0 +1,13 @@
+#include "test.hxx"
+
+typedef xmlns::test::IntList<void, int> IntListImpl;
+typedef xmlns::test::IntList<void, void> IntListVoidImpl;
+typedef xmlns::test::IntComplex<void, int, char*> IntComplexImpl;
+
+int
+main ()
+{
+ IntListImpl int_list_impl;
+ IntListVoidImpl int_list_void_impl;
+ IntComplexImpl int_complex_impl;
+}
diff --git a/tests/schema/list/test.xsd b/tests/schema/list/test.xsd
new file mode 100644
index 0000000..e16a58d
--- /dev/null
+++ b/tests/schema/list/test.xsd
@@ -0,0 +1,72 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:simpleType name="IntList">
+ <xsd:list itemType="xsd:int"/>
+ </xsd:simpleType>
+
+ <!-- local element with anonymous list inside. -->
+
+ <xsd:complexType name="Foo">
+ <xsd:sequence>
+ <xsd:element name="string-list">
+ <xsd:simpleType>
+ <xsd:list itemType="xsd:string"/>
+ </xsd:simpleType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <!-- global element with anonymous list inside. -->
+
+ <xsd:element name="string-list">
+ <xsd:simpleType>
+ <xsd:list itemType="xsd:string"/>
+ </xsd:simpleType>
+ </xsd:element>
+
+
+
+ <!-- global element and global list with conflicting names -->
+
+ <xsd:simpleType name="long-list">
+ <xsd:list itemType="xsd:long"/>
+ </xsd:simpleType>
+
+ <xsd:element name="long-list" type="test:long-list"/>
+
+
+ <!-- forward reference -->
+
+ <xsd:simpleType name="int-list">
+ <xsd:list itemType="test:int"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="int">
+ <xsd:restriction base="xsd:int"/>
+ </xsd:simpleType>
+
+
+ <!-- inheritance from list -->
+
+ <xsd:complexType name="IntComplex">
+ <xsd:simpleContent>
+ <xsd:extension base="test:IntList">
+ <xsd:attribute name="foo" type="xsd:string"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="IntComplexEmpty">
+ <xsd:simpleContent>
+ <xsd:extension base="test:IntList">
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/tests/schema/no-namespace/test.xsd b/tests/schema/no-namespace/test.xsd
new file mode 100644
index 0000000..b426e8a
--- /dev/null
+++ b/tests/schema/no-namespace/test.xsd
@@ -0,0 +1,15 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd">
+
+
+ <xsd:complexType name="Test">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="test" type="Test"/>
+
+</xsd:schema>
diff --git a/tests/schema/recursive/test.xsd b/tests/schema/recursive/test.xsd
new file mode 100644
index 0000000..6efc7d2
--- /dev/null
+++ b/tests/schema/recursive/test.xsd
@@ -0,0 +1,43 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:element name="BooleanExpression">
+ <xsd:complexType>
+ <xsd:choice>
+ <xsd:element name="literal" type="xsd:boolean"/>
+ <xsd:element ref="test:AND"/>
+ <xsd:element ref="test:OR"/>
+ <xsd:element ref="test:XOR"/>
+ </xsd:choice>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="AND">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="test:BooleanExpression" maxOccurs="2"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="OR">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="test:BooleanExpression" maxOccurs="2"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+ <xsd:element name="XOR">
+ <xsd:complexType>
+ <xsd:sequence>
+ <xsd:element ref="test:BooleanExpression" maxOccurs="2"/>
+ </xsd:sequence>
+ </xsd:complexType>
+ </xsd:element>
+
+</xsd:schema>
diff --git a/tests/schema/ref-type/idref.xsd b/tests/schema/ref-type/idref.xsd
new file mode 100644
index 0000000..49ebe40
--- /dev/null
+++ b/tests/schema/ref-type/idref.xsd
@@ -0,0 +1,42 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- attribute -->
+
+ <xsd:attribute name="attribute" type="xsd:IDREF" xse:refType="test:a-author"/>
+
+ <xsd:complexType name="a-author">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ </xsd:sequence>
+ <xsd:attribute name="recommends" type="xsd:IDREF" xse:refType="test:a-author"/>
+ </xsd:complexType>
+
+
+ <!-- element -->
+
+ <xsd:element name="element" type="xsd:IDREF" xse:refType="test:e-author"/>
+
+ <xsd:complexType name="e-author">
+ <xsd:sequence>
+ <xsd:element name="recommends" type="xsd:IDREF" xse:refType="test:e-author"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- base -->
+
+ <xsd:simpleType name="author-ref">
+ <xsd:restriction base="xsd:IDREF" xse:refType="test:e-author"/>
+ </xsd:simpleType>
+
+
+ <!-- itemType -->
+
+ <xsd:simpleType name="author-refs">
+ <xsd:list itemType="xsd:IDREF" xse:refType="test:e-author"/>
+ </xsd:simpleType>
+
+</xsd:schema>
diff --git a/tests/schema/ref-type/idrefs.xsd b/tests/schema/ref-type/idrefs.xsd
new file mode 100644
index 0000000..b68ed03
--- /dev/null
+++ b/tests/schema/ref-type/idrefs.xsd
@@ -0,0 +1,43 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- attribute -->
+
+ <xsd:attribute name="attribute" type="xsd:IDREFS" xse:refType="test:a-author"/>
+
+ <xsd:complexType name="a-author">
+ <xsd:sequence>
+ <xsd:element name="name" type="xsd:string"/>
+ </xsd:sequence>
+ <xsd:attribute name="recommends" type="xsd:IDREFS" xse:refType="test:a-author"/>
+ </xsd:complexType>
+
+
+ <!-- element -->
+
+ <xsd:element name="element" type="xsd:IDREFS" xse:refType="test:e-author"/>
+
+ <xsd:complexType name="e-author">
+ <xsd:sequence>
+ <xsd:element name="recommends" type="xsd:IDREFS" xse:refType="test:e-author"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <!-- base -->
+
+ <xsd:simpleType name="author-refs">
+ <xsd:restriction base="xsd:IDREFS" xse:refType="test:e-author"/>
+ </xsd:simpleType>
+
+
+ <!-- itemType - illegal -->
+ <!--
+ <xsd:simpleType name="author-refss">
+ <xsd:list itemType="xsd:IDREFS" xse:refType="test:e-author"/>
+ </xsd:simpleType>
+ -->
+
+</xsd:schema>
diff --git a/tests/schema/ref-type/invalid-0.xsd b/tests/schema/ref-type/invalid-0.xsd
new file mode 100644
index 0000000..7ce82ed
--- /dev/null
+++ b/tests/schema/ref-type/invalid-0.xsd
@@ -0,0 +1,17 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ xmlns:phony="http://www.codesynthesis.com/xmlns/phony"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- unresolvable namespace prefix -->
+
+ <xsd:attribute name="attribute1" type="xsd:IDREF" xse:refType="author"/>
+ <xsd:attribute name="attribute2" type="xsd:IDREF" xse:refType="t:author"/>
+
+ <!-- unresolvable namespace -->
+
+ <xsd:attribute name="attribute3" type="xsd:IDREF" xse:refType="phony:author"/>
+
+</xsd:schema>
diff --git a/tests/schema/ref-type/invalid-1.xsd b/tests/schema/ref-type/invalid-1.xsd
new file mode 100644
index 0000000..d989065
--- /dev/null
+++ b/tests/schema/ref-type/invalid-1.xsd
@@ -0,0 +1,11 @@
+<?xml version="1.0"?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xse="http://www.codesynthesis.com/xmlns/xml-schema-extension"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- unresolvable type -->
+
+ <xsd:attribute name="attribute" type="xsd:IDREF" xse:refType="test:author"/>
+
+</xsd:schema>
diff --git a/tests/schema/restriction/test.xsd b/tests/schema/restriction/test.xsd
new file mode 100644
index 0000000..331ba78
--- /dev/null
+++ b/tests/schema/restriction/test.xsd
@@ -0,0 +1,67 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <!-- Simple content. -->
+
+ <xsd:complexType name="SimpleBase">
+ <xsd:simpleContent>
+ <xsd:extension base="xsd:string">
+ <xsd:attribute name="lang" type="xsd:language"/>
+ <xsd:attribute name="note" type="xsd:string"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="SimpleType">
+ <xsd:simpleContent>
+ <xsd:restriction base="test:SimpleBase">
+ <xsd:maxLength value="255"/>
+ <xsd:attribute name="lang">
+ <xsd:simpleType>
+ <xsd:restriction base="xsd:language">
+ <xsd:enumeration value="en"/>
+ <xsd:enumeration value="es"/>
+ </xsd:restriction>
+ </xsd:simpleType>
+ </xsd:attribute>
+ </xsd:restriction>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+ <!-- Complex content. -->
+
+ <xsd:complexType name="ComplexBase">
+ <xsd:sequence>
+ <xsd:element name="lang" type="xsd:language"/>
+ <xsd:element name="note" type="xsd:string" minOccurs="0"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <xsd:complexType name="ComplexType">
+ <xsd:complexContent>
+ <xsd:restriction base="test:ComplexBase">
+ <xsd:sequence>
+ <xsd:element name="lang" type="xsd:language"/>
+ <xsd:element name="note" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+ <xsd:complexType name="AnyType">
+ <xsd:complexContent>
+ <xsd:restriction base="xsd:anyType">
+ <xsd:sequence>
+ <xsd:element name="lang" type="xsd:language"/>
+ <xsd:element name="note" type="xsd:string"/>
+ </xsd:sequence>
+ </xsd:restriction>
+ </xsd:complexContent>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/tests/schema/union/test.xsd b/tests/schema/union/test.xsd
new file mode 100644
index 0000000..706f6f2
--- /dev/null
+++ b/tests/schema/union/test.xsd
@@ -0,0 +1,65 @@
+<?xml version="1.0" ?>
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema"
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:schemaLocation="http://www.w3.org/2001/XMLSchema XMLSchema.xsd"
+ xmlns:test="http://www.codesynthesis.com/xmlns/test"
+ targetNamespace="http://www.codesynthesis.com/xmlns/test">
+
+ <xsd:simpleType name="IntUnion">
+ <xsd:union memberTypes="xsd:int xsd:string"/>
+ </xsd:simpleType>
+
+ <!-- local element with anonymous union inside. -->
+
+ <xsd:complexType name="Foo">
+ <xsd:sequence>
+ <xsd:element name="string-union">
+ <xsd:simpleType>
+ <xsd:union memberTypes="xsd:int xsd:string"/>
+ </xsd:simpleType>
+ </xsd:element>
+ </xsd:sequence>
+ </xsd:complexType>
+
+
+ <!-- global element with anonymous union inside. -->
+
+ <xsd:element name="string-union">
+ <xsd:simpleType>
+ <xsd:union memberTypes="xsd:int xsd:string"/>
+ </xsd:simpleType>
+ </xsd:element>
+
+
+
+ <!-- global element and global union with conflicting names -->
+
+ <xsd:simpleType name="long-union">
+ <xsd:union memberTypes="xsd:long xsd:string"/>
+ </xsd:simpleType>
+
+ <xsd:element name="long-union" type="test:long-union"/>
+
+
+ <!-- forward reference -->
+
+ <xsd:simpleType name="int-union">
+ <xsd:union memberTypes="test:int xsd:string"/>
+ </xsd:simpleType>
+
+ <xsd:simpleType name="int">
+ <xsd:restriction base="xsd:int"/>
+ </xsd:simpleType>
+
+
+ <!-- inheritance from union -->
+
+ <xsd:complexType name="IntComplex">
+ <xsd:simpleContent>
+ <xsd:extension base="test:IntUnion">
+ <xsd:attribute name="foo" type="xsd:string"/>
+ </xsd:extension>
+ </xsd:simpleContent>
+ </xsd:complexType>
+
+</xsd:schema>
diff --git a/version b/version
new file mode 100644
index 0000000..59de0b4
--- /dev/null
+++ b/version
@@ -0,0 +1 @@
+3.3.0.a5
diff --git a/xsd/cxx/elements.cxx b/xsd/cxx/elements.cxx
new file mode 100644
index 0000000..a62ed5d
--- /dev/null
+++ b/xsd/cxx/elements.cxx
@@ -0,0 +1,1020 @@
+// file : xsd/cxx/elements.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/elements.hxx>
+
+#include <backend-elements/regex.hxx>
+
+#include <sstream>
+#include <iostream>
+#include <algorithm>
+
+using std::wcerr;
+using std::endl;
+
+namespace CXX
+{
+ //
+ //
+ wchar_t
+ upcase (wchar_t c)
+ {
+ return std::toupper (c);
+ }
+
+ // Context
+ //
+
+ Context::
+ Context (std::wostream& o,
+ SemanticGraph::Schema& root,
+ NarrowString const& char_type__,
+ Boolean include_with_brackets__,
+ NarrowString const& include_prefix__,
+ NarrowString const& esymbol,
+ Containers::Vector<NarrowString> const& nsm,
+ Containers::Vector<NarrowString> const& nsr,
+ Boolean trace_namespace_regex_,
+ Containers::Vector<NarrowString> const& ir,
+ Boolean trace_include_regex_,
+ Boolean inline_,
+ Containers::Vector<NarrowString> const& reserved_name)
+ : os (o),
+ schema_root (root),
+ char_type (char_type_),
+ L (L_),
+ string_type (string_type_),
+ include_with_brackets (include_with_brackets_),
+ include_prefix (include_prefix_),
+ type_exp (type_exp_),
+ inst_exp (inst_exp_),
+ inl (inl_),
+ ns_mapping_cache (ns_mapping_cache_),
+ xs_ns_ (0),
+ char_type_ (char_type__),
+ L_ (char_type == L"wchar_t" ? L"L" : L""),
+ include_with_brackets_ (include_with_brackets__),
+ include_prefix_ (include_prefix__),
+ type_exp_ (esymbol ? esymbol + " " : esymbol),
+ inst_exp_ (esymbol ? esymbol + "\n" : esymbol),
+ inl_ (inline_ ? L"inline\n" : L""),
+ cxx_id_expr_ (L"^(::)?([a-zA-Z_]\\w*)(::[a-zA-Z_]\\w*)*$"),
+ cxx_id_expr (cxx_id_expr_),
+ trace_namespace_regex (trace_namespace_regex_),
+ nsr_mapping (nsr_mapping_),
+ nsm_mapping (nsm_mapping_),
+ include_mapping (include_mapping_),
+ trace_include_regex (trace_include_regex_),
+ reserved_name_map (reserved_name_map_)
+ {
+ // Resolve and cache XML Schema namespace.
+ //
+ {
+ SemanticGraph::Nameable* n;
+
+ if (schema_root.names_begin ()->name () ==
+ L"http://www.w3.org/2001/XMLSchema")
+ {
+ // schema_root is the XML Schema itself.
+ //
+ n = &schema_root.names_begin ()->named ();
+ }
+ else
+ {
+ // Otherwise, the first used schema is implied XML Schema.
+ //
+ SemanticGraph::Uses& u = *schema_root.uses_begin ();
+ assert (u.is_a<SemanticGraph::Implies> ());
+ n = &u.schema ().names_begin ()->named ();
+ }
+
+ xs_ns_ = dynamic_cast<SemanticGraph::Namespace*> (n);
+ }
+
+ //
+ //
+ if (char_type == L"char")
+ string_type_ = L"::std::string";
+ else if (char_type == L"wchar_t")
+ string_type_ = L"::std::wstring";
+ else
+ string_type_ = L"::std::basic_string< " + char_type + L" >";
+
+ // Default mapping.
+ //
+ nsr_mapping_.push_back (
+ Regex (L"#^.* (.*?/)??"L"(([a-zA-Z_]\\w*)(/[a-zA-Z_]\\w*)*)/?$#$2#"));
+ nsr_mapping_.push_back (
+ Regex (L"#^.* http://www\\.w3\\.org/2001/XMLSchema$#xml_schema#"));
+
+ // Custom regex mapping.
+ //
+ for (Containers::Vector<NarrowString>::ConstIterator
+ i (nsr.begin ()), e (nsr.end ()); i != e; ++i)
+ {
+ nsr_mapping_.push_back (Regex (*i));
+ }
+
+ // Custom direct mapping.
+ //
+ for (Containers::Vector<NarrowString>::ConstIterator
+ i (nsm.begin ()), e (nsm.end ()); i != e; ++i)
+ {
+ String s (*i);
+
+ // Split the string in two parts at the last '='.
+ //
+ Size pos (s.rfind ('='));
+
+ if (pos == String::npos)
+ throw InvalidNamespaceMapping (s, "delimiter ('=') not found");
+
+ // Empty xml_ns designates the no-namespace case.
+ //
+ String xml_ns (s, 0, pos);
+ String cxx_ns (s, pos + 1);
+
+ if (!cxx_ns.empty () && !cxx_id_expr.match (cxx_ns))
+ throw InvalidNamespaceMapping (s, "invalid C++ identifier");
+
+ nsm_mapping_[xml_ns] = cxx_ns;
+ }
+
+ // Include path regex
+ //
+ for (Containers::Vector<NarrowString>::ConstIterator
+ i (ir.begin ()), e (ir.end ()); i != e; ++i)
+ {
+ include_mapping_.push_back (Regex (*i));
+ }
+
+ // Reserved names.
+ //
+ for (Containers::Vector<NarrowString>::ConstIterator
+ i (reserved_name.begin ()), e (reserved_name.end ()); i != e; ++i)
+ {
+ String s (*i);
+
+ // Split the string in two parts at '='.
+ //
+ Size pos (s.find ('='));
+
+ if (pos == String::npos)
+ reserved_name_map_[s] = L"";
+ else
+ reserved_name_map_[String (s, 0, pos)] = String (s, pos + 1);
+ }
+ }
+
+ String Context::
+ ns_name (SemanticGraph::Namespace& ns)
+ {
+ using SemanticGraph::Schema;
+ using SemanticGraph::Includes;
+ using SemanticGraph::Imports;
+ using SemanticGraph::Implies;
+ using SemanticGraph::Sources;
+
+ String tmp;
+ MapMapping::ConstIterator i (nsm_mapping.find (ns.name ()));
+
+ if (i != nsm_mapping.end ())
+ {
+ tmp = i->second;
+ }
+ else
+ {
+ SemanticGraph::Path path;
+ Schema& schema (dynamic_cast<Schema&> (ns.scope ()));
+
+ if (schema.used ())
+ {
+ // Here we need to detect a special multi-schema compilation
+ // case where the root schemas are imported into a special
+ // schema that doesn't have a namespace.
+ //
+ SemanticGraph::Uses& u (*schema.used_begin ());
+ SemanticGraph::Schema& s (u.user ());
+
+ if (s.names_begin () != s.names_end ())
+ path = u.path ();
+ }
+
+ String pair;
+
+ if (!path.empty ())
+ {
+ // Try to use the portable representation of the path. If that
+ // fails, fall back to the native representation.
+ //
+ try
+ {
+ pair = path.string ();
+ }
+ catch (SemanticGraph::InvalidPath const&)
+ {
+ pair = path.native_file_string ();
+ }
+ }
+
+ pair += L' ' + ns.name ();
+
+ // Check cache first
+ //
+ MappingCache::ConstIterator i (ns_mapping_cache.find (pair));
+
+ if (i != ns_mapping_cache.end ())
+ {
+ tmp = i->second;
+ }
+ else
+ {
+ if (trace_namespace_regex)
+ wcerr << "namespace: '" << pair << "'" << endl;
+
+ Boolean found (false);
+ Regex colon (L"#/#::#");
+
+ for (RegexMapping::ConstReverseIterator e (nsr_mapping.rbegin ());
+ e != nsr_mapping.rend (); ++e)
+ {
+ if (trace_namespace_regex)
+ wcerr << "try: '" << e->pattern () << "' : ";
+
+ if (e->match (pair))
+ {
+ tmp = e->merge (pair);
+ tmp = colon.merge (tmp); // replace `/' with `::'
+
+ // Check the result.
+ //
+ found = cxx_id_expr.match (tmp);
+
+ if (trace_namespace_regex)
+ wcerr << "'" << tmp << "' : ";
+ }
+
+ if (trace_namespace_regex)
+ wcerr << (found ? '+' : '-') << endl;
+
+ if (found)
+ break;
+ }
+
+ if (!found)
+ {
+ // Check if the name is valid by itself.
+ //
+ if (ns.name ().empty ())
+ {
+ // Empty name denotes a no-namespace case.
+ //
+ tmp = ns.name ();
+ }
+ else
+ {
+ tmp = colon.merge (ns.name ()); // replace `/' with `::'
+
+ if (!cxx_id_expr.match (tmp))
+ {
+ throw NoNamespaceMapping (
+ ns.file (), ns.line (), ns.column (), ns.name ());
+ }
+ }
+ }
+
+ // Add the mapping to the cache.
+ //
+ ns_mapping_cache[pair] = tmp;
+ }
+ }
+
+
+ // Parse resulting namespace string and id() each name.
+ //
+ String r;
+ String::size_type b (0), e;
+
+ do
+ {
+ e = tmp.find (L"::", b);
+
+ String name (tmp, b, e == tmp.npos ? e : e - b);
+
+ if (!name.empty ())
+ r += L"::" + escape (name);
+
+ b = e;
+
+ if (b == tmp.npos)
+ break;
+
+ b += 2;
+
+ } while (true);
+
+ return r;
+ }
+
+ SemanticGraph::Namespace& Context::
+ xs_ns ()
+ {
+ return *xs_ns_;
+ }
+
+ String Context::
+ xs_ns_name ()
+ {
+ return ns_name (*xs_ns_);
+ }
+
+ SemanticGraph::Namespace& Context::
+ namespace_ (SemanticGraph::Nameable& n)
+ {
+ // The basic idea goes like this: go up Names edges until you
+ // reach Namespace. There are, however, anonymous types which
+ // need special handling. In the case of an anonymous type we
+ // will go up the first Belongs edge (because the first edge
+ // is where the type was defined.
+ //
+
+ if (n.named ())
+ {
+ SemanticGraph::Scope& s (n.scope ());
+
+ SemanticGraph::Namespace* ns (
+ dynamic_cast<SemanticGraph::Namespace*> (&n));
+
+ return ns ? *ns : namespace_ (s);
+ }
+ else
+ {
+ SemanticGraph::Type& t (dynamic_cast<SemanticGraph::Type&> (n));
+
+ SemanticGraph::Belongs& b (*t.classifies_begin ());
+
+ return namespace_ (b.instance ());
+ }
+ }
+
+ String Context::
+ xml_ns_name (SemanticGraph::Nameable& n)
+ {
+ return namespace_ (n).name ();
+ }
+
+ String Context::
+ fq_name (SemanticGraph::Nameable& n, Char const* name_key)
+ {
+ using namespace SemanticGraph;
+
+ String r;
+
+ if (dynamic_cast<Schema*> (&n))
+ {
+ return L""; // Map to global namespace.
+ }
+ else if (SemanticGraph::Namespace* ns =
+ dynamic_cast<SemanticGraph::Namespace*> (&n))
+ {
+ r = ns_name (*ns);
+ }
+ else
+ {
+ r = fq_name (n.scope ());
+ r += L"::";
+ r += n.context ().get<String> (name_key);
+ }
+
+ return r;
+ }
+
+ SemanticGraph::Type& Context::
+ ultimate_base (SemanticGraph::Complex& c)
+ {
+ using namespace SemanticGraph;
+
+ Type* b (&c.inherits ().base ());
+
+ while (true)
+ {
+ Complex* cb (dynamic_cast<Complex*> (b));
+
+ if (cb != 0 && cb->inherits_p ())
+ {
+ b = &cb->inherits ().base ();
+ continue;
+ }
+
+ break;
+ }
+
+ return *b;
+ }
+
+ namespace
+ {
+ WideChar const* keywords[] = {
+ L"NULL",
+ L"and",
+ L"asm",
+ L"auto",
+ L"bitand",
+ L"bitor",
+ L"bool",
+ L"break",
+ L"case",
+ L"catch",
+ L"char",
+ L"class",
+ L"compl",
+ L"const",
+ L"const_cast",
+ L"continue",
+ L"default",
+ L"delete",
+ L"do",
+ L"double",
+ L"dynamic_cast",
+ L"else",
+ L"end_eq",
+ L"enum",
+ L"explicit",
+ L"export",
+ L"extern",
+ L"false",
+ L"float",
+ L"for",
+ L"friend",
+ L"goto",
+ L"if",
+ L"inline",
+ L"int",
+ L"long",
+ L"mutable",
+ L"namespace",
+ L"new",
+ L"not",
+ L"not_eq",
+ L"operator",
+ L"or",
+ L"or_eq",
+ L"private",
+ L"protected",
+ L"public",
+ L"register",
+ L"reinterpret_cast",
+ L"return",
+ L"short",
+ L"signed",
+ L"sizeof",
+ L"static",
+ L"static_cast",
+ L"struct",
+ L"switch",
+ L"template",
+ L"this",
+ L"throw",
+ L"true",
+ L"try",
+ L"typedef",
+ L"typeid",
+ L"typename",
+ L"union",
+ L"unsigned",
+ L"using",
+ L"virtual",
+ L"void",
+ L"volatile",
+ L"wchar_t",
+ L"while",
+ L"xor",
+ L"xor_eq"
+ };
+ }
+
+ String Context::
+ escape (String const& name)
+ {
+ String r;
+ Size n (name.size ());
+
+ // In most common cases we will have that many chars.
+ //
+ r.reserve (n);
+
+ for (Size i (0); i < n; ++i)
+ {
+ Boolean first (i == 0);
+
+ UnsignedLong u (unicode_char (name, i)); // May advance i.
+
+ if (first)
+ {
+ if (!((u >= 'a' && u <= 'z') ||
+ (u >= 'A' && u <= 'Z') ||
+ u == '_'))
+ r = (u >= '0' && u <= '9') ? L"cxx_" : L"cxx";
+ }
+
+ if (!((u >= 'a' && u <= 'z') ||
+ (u >= 'A' && u <= 'Z') ||
+ (u >= '0' && u <= '9') ||
+ u == '_'))
+ r.push_back ('_');
+ else
+ r.push_back (static_cast<WideChar> (u));
+ }
+
+ if (r.empty ())
+ r = L"cxx";
+
+ // Custom reserved words.
+ //
+ ReservedNameMap::ConstIterator i (reserved_name_map.find (r));
+
+ if (i != reserved_name_map.end ())
+ {
+ if (i->second)
+ return i->second;
+ else
+ r += L'_';
+ }
+
+ // Keywords
+ //
+ Size const size (sizeof (keywords) / sizeof (WideChar*));
+
+ if (std::binary_search (keywords, keywords + size, r))
+ {
+ r += L'_';
+
+ // Re-run custom words.
+ //
+ i = reserved_name_map.find (r);
+
+ if (i != reserved_name_map.end ())
+ {
+ if (i->second)
+ return i->second;
+ else
+ r += L'_';
+ }
+ }
+
+ return r;
+ }
+
+ // String escaping.
+ //
+
+ String
+ charlit (UnsignedLong u)
+ {
+ String r ("\\x");
+ Boolean lead (true);
+
+ for (Long i (7); i >= 0; --i)
+ {
+ UnsignedLong x ((u >> (i * 4)) & 0x0F);
+
+ if (lead)
+ {
+ if (x == 0)
+ continue;
+
+ lead = false;
+ }
+
+ r += x < 10 ? ('0' + x) : ('A' + x - 10);
+ }
+
+ return r;
+ }
+
+ const UnsignedLong utf8_first_char_mask[5] =
+ {
+ 0x00, 0x00, 0xC0, 0xE0, 0xF0
+ };
+
+ String
+ strlit_utf8 (String const& str)
+ {
+ String r;
+ Size n (str.size ());
+
+ // In most common cases we will have that many chars.
+ //
+ r.reserve (n + 2);
+
+ r += '"';
+
+ Boolean escape (false);
+
+ for (Size i (0); i < n; ++i)
+ {
+ UnsignedLong u (Context::unicode_char (str, i)); // May advance i.
+
+ // [128 - ] - UTF-8
+ // 127 - \x7F
+ // [32 - 126] - as is
+ // [0 - 31] - \X or \xXX
+ //
+
+ if (u < 32 || u == 127)
+ {
+ switch (u)
+ {
+ case L'\n':
+ {
+ r += L"\\n";
+ break;
+ }
+ case L'\t':
+ {
+ r += L"\\t";
+ break;
+ }
+ case L'\v':
+ {
+ r += L"\\v";
+ break;
+ }
+ case L'\b':
+ {
+ r += L"\\b";
+ break;
+ }
+ case L'\r':
+ {
+ r += L"\\r";
+ break;
+ }
+ case L'\f':
+ {
+ r += L"\\f";
+ break;
+ }
+ case L'\a':
+ {
+ r += L"\\a";
+ break;
+ }
+ default:
+ {
+ r += charlit (u);
+ escape = true;
+ break;
+ }
+ }
+ }
+ else if (u < 127)
+ {
+ if (escape)
+ {
+ // Close and open the string so there are no clashes.
+ //
+ r += '"';
+ r += '"';
+
+ escape = false;
+ }
+
+ switch (u)
+ {
+ case L'"':
+ {
+ r += L"\\\"";
+ break;
+ }
+ case L'\\':
+ {
+ r += L"\\\\";
+ break;
+ }
+ default:
+ {
+ r += static_cast<WideChar> (u);
+ break;
+ }
+ }
+ }
+ else
+ {
+ UnsignedLong count;
+ UnsignedLong tmp[4];
+
+ if (u < 0x800)
+ count = 2;
+ else if (u < 0x10000)
+ count = 3;
+ else if (u < 0x110000)
+ count = 4;
+
+ switch (count)
+ {
+ case 4:
+ {
+ tmp[3] = (u | 0x80UL) & 0xBFUL;
+ u >>= 6;
+ }
+ case 3:
+ {
+ tmp[2] = (u | 0x80UL) & 0xBFUL;
+ u >>= 6;
+ }
+ case 2:
+ {
+ tmp[1] = (u | 0x80UL) & 0xBFUL;
+ u >>= 6;
+ }
+ case 1:
+ {
+ tmp[0] = u | utf8_first_char_mask[count];
+ }
+ }
+
+ for (UnsignedLong j (0); j < count; ++j)
+ r += charlit (tmp[j]);
+
+ escape = true;
+ }
+ }
+
+ r += '"';
+
+ return r;
+ }
+
+ String
+ strlit_utf32 (String const& str)
+ {
+ String r;
+ Size n (str.size ());
+
+ // In most common cases we will have that many chars.
+ //
+ r.reserve (n + 2);
+
+ r += '"';
+
+ Boolean escape (false);
+
+ for (Size i (0); i < n; ++i)
+ {
+ UnsignedLong u (Context::unicode_char (str, i)); // May advance i.
+
+ // [128 - ] - \xUUUUUUUU
+ // 127 - \x7F
+ // [32 - 126] - as is
+ // [0 - 31] - \X or \xXX
+ //
+
+ if (u < 32 || u == 127)
+ {
+ switch (u)
+ {
+ case L'\n':
+ {
+ r += L"\\n";
+ break;
+ }
+ case L'\t':
+ {
+ r += L"\\t";
+ break;
+ }
+ case L'\v':
+ {
+ r += L"\\v";
+ break;
+ }
+ case L'\b':
+ {
+ r += L"\\b";
+ break;
+ }
+ case L'\r':
+ {
+ r += L"\\r";
+ break;
+ }
+ case L'\f':
+ {
+ r += L"\\f";
+ break;
+ }
+ case L'\a':
+ {
+ r += L"\\a";
+ break;
+ }
+ default:
+ {
+ r += charlit (u);
+ escape = true;
+ break;
+ }
+ }
+ }
+ else if (u < 127)
+ {
+ if (escape)
+ {
+ // Close and open the string so there are no clashes.
+ //
+ r += '"';
+ r += '"';
+
+ escape = false;
+ }
+
+ switch (u)
+ {
+ case L'"':
+ {
+ r += L"\\\"";
+ break;
+ }
+ case L'\\':
+ {
+ r += L"\\\\";
+ break;
+ }
+ default:
+ {
+ r += static_cast<WideChar> (u);
+ break;
+ }
+ }
+ }
+ else
+ {
+ r += charlit (u);
+ escape = true;
+ }
+ }
+
+ r += '"';
+
+ return r;
+ }
+
+ String Context::
+ strlit (String const& str)
+ {
+ if (char_type == L"char")
+ return strlit_utf8 (str);
+ else
+ return strlit_utf32 (str);
+ }
+
+ String Context::
+ comment (String const& str)
+ {
+ String r;
+
+ WideChar const* s (str.c_str ());
+ Size size (str.size ());
+
+ // In most common cases we will have that many chars.
+ //
+ r.reserve (size);
+
+ for (WideChar const* p (s); p < s + size; ++p)
+ {
+ UnsignedLong u (unicode_char (p)); // May advance p.
+
+ // We are going to treat \v, \f and \n as unrepresentable
+ // here even though they can be present in C++ source code.
+ //
+ if (u > 127 || (u < 32 && u != '\t'))
+ r += L'?';
+ else
+ r += static_cast<WideChar> (u);
+ }
+
+ return r;
+ }
+
+ String Context::
+ process_include_path (String const& name) const
+ {
+ String path (include_prefix + name);
+
+ if (trace_include_regex)
+ wcerr << "include: '" << path << "'" << endl;
+
+ String r;
+ Boolean found (false);
+
+ for (RegexMapping::ConstReverseIterator e (include_mapping.rbegin ());
+ e != include_mapping.rend (); ++e)
+ {
+ if (trace_include_regex)
+ wcerr << "try: '" << e->pattern () << "' : ";
+
+ if (e->match (path))
+ {
+ r = e->merge (path);
+ found = true;
+
+ if (trace_include_regex)
+ wcerr << "'" << r << "' : ";
+ }
+
+ if (trace_include_regex)
+ wcerr << (found ? '+' : '-') << endl;
+
+ if (found)
+ break;
+ }
+
+ if (!found)
+ r = path;
+
+ if (!r.empty () && r[0] != L'"' && r[0] != L'<')
+ {
+ WideChar op (include_with_brackets ? L'<' : L'"');
+ WideChar cl (include_with_brackets ? L'>' : L'"');
+ r = op + r + cl;
+ }
+
+ return r;
+ }
+
+ // Namespace
+ //
+
+ Void Namespace::
+ pre (Type& n)
+ {
+ String ns (ctx_.ns_name (n));
+
+ String::size_type b (0), e;
+
+ if (st_)
+ st_->enter (n, L"", ns ? false : true);
+
+ do
+ {
+ e = ns.find (L"::", b);
+
+ String name (ns, b, e == ns.npos ? e : e - b);
+
+ if (!name.empty ())
+ {
+ if (st_)
+ st_->enter (n, name, e == ns.npos);
+
+ ctx_.os << "namespace " << name << "{";
+ }
+
+ b = e;
+
+ if (b == ns.npos)
+ break;
+
+ b += 2;
+
+ } while (true);
+ }
+
+ Void Namespace::
+ post (Type& n)
+ {
+ String ns (ctx_.ns_name (n));
+
+ String::size_type b (0), e;
+
+ do
+ {
+ e = ns.find (L"::", b);
+
+ String name (ns, b, e == ns.npos ? e : e - b);
+
+ if (!name.empty ())
+ {
+ ctx_.os << "}";
+
+ if (st_)
+ st_->leave ();
+ }
+
+
+ b = e;
+
+ if (b == ns.npos)
+ break;
+
+ b += 2;
+
+ }
+ while (true);
+
+ if (st_)
+ st_->leave ();
+ }
+}
diff --git a/xsd/cxx/elements.hxx b/xsd/cxx/elements.hxx
new file mode 100644
index 0000000..dba9665
--- /dev/null
+++ b/xsd/cxx/elements.hxx
@@ -0,0 +1,577 @@
+// file : xsd/cxx/elements.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_ELEMENTS_HXX
+#define CXX_ELEMENTS_HXX
+
+#include <cult/types.hxx>
+#include <cult/containers/map.hxx>
+#include <cult/containers/vector.hxx>
+
+#include <backend-elements/regex.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <elements.hxx>
+
+#include <ostream>
+
+namespace CXX
+{
+ using std::endl;
+ typedef WideString String;
+
+
+ // On some platforms std::toupper can be something other than a
+ // function with C++ linkage.
+ //
+ wchar_t
+ upcase (wchar_t c);
+
+
+ // Exceptions.
+ //
+
+ struct NoNamespaceMapping
+ {
+ NoNamespaceMapping (SemanticGraph::Path const& file,
+ UnsignedLong line,
+ UnsignedLong column,
+ String const& ns)
+ : file_ (file),
+ line_ (line),
+ column_ (column),
+ ns_ (ns)
+ {
+ }
+
+
+ SemanticGraph::Path const&
+ file () const
+ {
+ return file_;
+ }
+
+ UnsignedLong
+ line () const
+ {
+ return line_;
+ }
+
+ UnsignedLong
+ column () const
+ {
+ return column_;
+ }
+
+ String const&
+ ns () const
+ {
+ return ns_;
+ }
+
+ private:
+ SemanticGraph::Path file_;
+ UnsignedLong line_;
+ UnsignedLong column_;
+ String ns_;
+ };
+
+ struct InvalidNamespaceMapping
+ {
+ InvalidNamespaceMapping (String const& mapping,
+ String const& reason)
+ : mapping_ (mapping), reason_ (reason)
+ {
+ }
+
+ String const&
+ mapping () const
+ {
+ return mapping_;
+ }
+
+ String const&
+ reason () const
+ {
+ return reason_;
+ }
+
+ private:
+ String mapping_;
+ String reason_;
+ };
+
+
+ //
+ //
+ class Context
+ {
+ public:
+ typedef BackendElements::Regex::Pattern<WideChar> RegexPat;
+ typedef BackendElements::Regex::Expression<WideChar> Regex;
+ typedef Cult::Containers::Vector<Regex> RegexMapping;
+ typedef Cult::Containers::Map<String, String> MapMapping;
+ typedef Cult::Containers::Map<String, String> MappingCache;
+
+ typedef Cult::Containers::Map<String, String> ReservedNameMap;
+
+ public:
+ Context (std::wostream& o,
+ SemanticGraph::Schema& root,
+ NarrowString const& char_type__,
+ Boolean include_with_brackets__,
+ NarrowString const& include_prefix__,
+ NarrowString const& esymbol,
+ Containers::Vector<NarrowString> const& nsm,
+ Containers::Vector<NarrowString> const& nsr,
+ Boolean trace_namespace_regex_,
+ Containers::Vector<NarrowString> const& include_regex,
+ Boolean trace_include_regex_,
+ Boolean inline_,
+ Containers::Vector<NarrowString> const& reserved_name);
+
+ protected:
+ Context (Context& c)
+ : os (c.os),
+ schema_root (c.schema_root),
+ char_type (c.char_type),
+ L (c.L),
+ string_type (c.string_type),
+ include_with_brackets (c.include_with_brackets),
+ include_prefix (c.include_prefix),
+ type_exp (c.type_exp),
+ inst_exp (c.inst_exp),
+ inl (c.inl),
+ ns_mapping_cache (c.ns_mapping_cache),
+ xs_ns_ (c.xs_ns_),
+ cxx_id_expr (c.cxx_id_expr),
+ trace_namespace_regex (c.trace_namespace_regex),
+ nsr_mapping (c.nsr_mapping),
+ nsm_mapping (c.nsm_mapping),
+ include_mapping (c.include_mapping),
+ trace_include_regex (c.trace_include_regex),
+ reserved_name_map (c.reserved_name_map)
+ {
+ }
+
+ Context (Context& c, std::wostream& o)
+ : os (o),
+ schema_root (c.schema_root),
+ char_type (c.char_type),
+ L (c.L),
+ string_type (c.string_type),
+ include_with_brackets (c.include_with_brackets),
+ include_prefix (c.include_prefix),
+ type_exp (c.type_exp),
+ inst_exp (c.inst_exp),
+ inl (c.inl),
+ ns_mapping_cache (c.ns_mapping_cache),
+ xs_ns_ (c.xs_ns_),
+ cxx_id_expr (c.cxx_id_expr),
+ trace_namespace_regex (c.trace_namespace_regex),
+ nsr_mapping (c.nsr_mapping),
+ nsm_mapping (c.nsm_mapping),
+ include_mapping (c.include_mapping),
+ trace_include_regex (c.trace_include_regex),
+ reserved_name_map (c.reserved_name_map)
+ {
+ }
+
+ public:
+ static String
+ unclash (String const& name, String const& new_name)
+ {
+ return name == new_name ? (new_name + L'_') : new_name;
+ }
+
+ public:
+ // Return UTF-32 character starting at this position. Position is
+ // advanced by 1 if this Unicode character takes more than one
+ // underlying character.
+ //
+ static UnsignedLong
+ unicode_char (String const& str, Size& pos);
+
+ static UnsignedLong
+ unicode_char (WideChar const*& p);
+
+ // Escape C++ keywords and illegal characters.
+ //
+ String
+ escape (String const&);
+
+ // Create a string literal so that it can be used in C++ source
+ // code. It includes "".
+ //
+ String
+ strlit (String const&);
+
+ // Escape the string so that it can be used in C++ comment.
+ //
+ String
+ comment (String const&);
+
+ // Translate XML namespace name to a C++ identifier.
+ //
+ String
+ ns_name (SemanticGraph::Namespace&);
+
+ // XML Schema namespace.
+ //
+ SemanticGraph::Namespace&
+ xs_ns ();
+
+ // C++ namespace for XML Schema.
+ //
+ String
+ xs_ns_name ();
+
+ //
+ //
+ SemanticGraph::Namespace&
+ namespace_ (SemanticGraph::Nameable& n);
+
+ // Original XML namespace name.
+ //
+ String
+ xml_ns_name (SemanticGraph::Nameable& ns);
+
+
+ // Fully-qualified C++ name.
+ //
+ String
+ fq_name (SemanticGraph::Nameable& n, Char const* name_key = "name");
+
+ public:
+ static SemanticGraph::Type&
+ ultimate_base (SemanticGraph::Complex&);
+
+ public:
+ String
+ process_include_path (String const&) const;
+
+ public:
+ static Boolean
+ skip (SemanticGraph::Member& m)
+ {
+ // "Subsequent" local element.
+ //
+ return !m.scope ().is_a<SemanticGraph::Namespace> () &&
+ m.context ().count ("min") == 0;
+ }
+
+ static UnsignedLong
+ min (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<UnsignedLong> ("min");
+ }
+
+ static UnsignedLong
+ min (SemanticGraph::Any const& a)
+ {
+ return a.context ().get<UnsignedLong> ("min");
+ }
+
+ static UnsignedLong
+ max (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<UnsignedLong> ("max");
+ }
+
+ static UnsignedLong
+ max (SemanticGraph::Any const& a)
+ {
+ return a.context ().get<UnsignedLong> ("max");
+ }
+
+ public:
+ // Get escaped name.
+ //
+ static String const&
+ ename (SemanticGraph::Nameable const& n)
+ {
+ return n.context ().get<String> ("name");
+ }
+
+ public:
+ std::wostream& os;
+
+ SemanticGraph::Schema& schema_root;
+
+ String& char_type;
+ String& L; // string literal prefix
+ String& string_type;
+
+ Boolean& include_with_brackets;
+ String& include_prefix;
+
+ String& type_exp;
+ String& inst_exp;
+ String& inl;
+
+ public:
+ MappingCache& ns_mapping_cache;
+
+ private:
+ SemanticGraph::Namespace* xs_ns_;
+
+ String char_type_;
+ String L_;
+ String string_type_;
+
+ Boolean include_with_brackets_;
+ String include_prefix_;
+
+ String type_exp_;
+ String inst_exp_;
+ String inl_;
+
+ private:
+ RegexPat const cxx_id_expr_;
+ RegexPat const& cxx_id_expr;
+ Boolean trace_namespace_regex;
+ RegexMapping nsr_mapping_;
+ MapMapping nsm_mapping_;
+ RegexMapping const& nsr_mapping;
+ MapMapping const& nsm_mapping;
+ MappingCache ns_mapping_cache_;
+
+ RegexMapping include_mapping_;
+ RegexMapping const& include_mapping;
+ Boolean trace_include_regex;
+
+ ReservedNameMap const& reserved_name_map;
+ ReservedNameMap reserved_name_map_;
+ };
+
+ inline UnsignedLong Context::
+ unicode_char (String const& str, Size& pos)
+ {
+ if (sizeof (WideChar) == 4)
+ {
+ return str[pos];
+ }
+ else if (sizeof (WideChar) == 2)
+ {
+ WideChar x (str[pos]);
+
+ if (x < 0xD800 || x > 0xDBFF)
+ return x;
+ else
+ return ((x - 0xD800) << 10) + (str[++pos] - 0xDC00) + 0x10000;
+ }
+ else
+ return 0;
+ }
+
+ inline UnsignedLong Context::
+ unicode_char (WideChar const*& p)
+ {
+ if (sizeof (WideChar) == 4)
+ {
+ return *p;
+ }
+ else if (sizeof (WideChar) == 2)
+ {
+ WideChar x (*p);
+
+ if (x < 0xD800 || x > 0xDBFF)
+ return x;
+ else
+ return ((x - 0xD800) << 10) + (*(++p) - 0xDC00) + 0x10000;
+ }
+ else
+ return 0;
+ }
+
+ // Usual namespace mapping.
+ //
+ struct Namespace : Traversal::Namespace
+ {
+ struct ScopeTracker
+ {
+ // First scope name if always empty (global scope). The last flag
+ // signals the last scope.
+ //
+ virtual Void
+ enter (Type&, String const& name, Boolean last) = 0;
+
+ virtual Void
+ leave () = 0;
+ };
+
+
+ Namespace (Context& c)
+ : ctx_ (c), st_ (0)
+ {
+ }
+
+ Namespace (Context& c, ScopeTracker& st)
+ : ctx_ (c), st_ (&st)
+ {
+ }
+
+ virtual Void
+ pre (Type&);
+
+ virtual Void
+ post (Type&);
+
+ private:
+ Context& ctx_;
+ ScopeTracker* st_;
+ };
+
+
+ //
+ //
+ template <typename X>
+ struct Has : X
+ {
+ Has (Boolean& result)
+ : result_ (result)
+ {
+ }
+
+ virtual Void
+ traverse (typename X::Type&)
+ {
+ result_ = true;
+ }
+
+ private:
+ Boolean& result_;
+ };
+
+ // Checks if scope 'Y' names any of 'X'
+ //
+ template <typename X, typename Y>
+ Boolean
+ has (Y& y)
+ {
+ using SemanticGraph::Scope;
+
+ Boolean result (false);
+ Has<X> t (result);
+
+ for (Scope::NamesIterator i (y.names_begin ()), e (y.names_end ());
+ !result && i != e; ++i)
+ t.dispatch (i->named ());
+
+ return result;
+ }
+
+ // Checks if the compositor has any particle of 'X'
+ //
+ template <typename X>
+ Boolean
+ has_particle (SemanticGraph::Compositor& y)
+ {
+ using SemanticGraph::Compositor;
+
+ Boolean result (false);
+ Has<X> t (result);
+
+ for (Compositor::ContainsIterator i (y.contains_begin ()),
+ e (y.contains_end ()); !result && i != e; ++i)
+ {
+ SemanticGraph::Particle& p (i->particle ());
+
+ t.dispatch (p);
+
+ if (!result && p.is_a<Compositor> ())
+ result = has_particle<X> (dynamic_cast<Compositor&> (p));
+ }
+
+ return result;
+ }
+
+ // Specialization for Complex
+ //
+ template <typename X>
+ Boolean
+ has_particle (SemanticGraph::Complex& c)
+ {
+ return c.contains_compositor_p () &&
+ has_particle<X> (c.contains_compositor ().compositor ());
+ }
+
+ // Fundamental type mapping helper.
+ //
+ struct Fundamental : Traversal::Fundamental::Type,
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef
+ {
+ virtual Void
+ fundamental_type (SemanticGraph::Fundamental::Type& t) = 0;
+
+ virtual Void
+ fundamental_template (SemanticGraph::Fundamental::Type& t) = 0;
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Type& t)
+ {
+ fundamental_type (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id& t)
+ {
+ fundamental_template (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef& t)
+ {
+ fundamental_template (t);
+ }
+ };
+}
+
+#endif // CXX_TREE_ELEMENTS_HXX
diff --git a/xsd/cxx/parser/attribute-validation-source.cxx b/xsd/cxx/parser/attribute-validation-source.cxx
new file mode 100644
index 0000000..52c51b1
--- /dev/null
+++ b/xsd/cxx/parser/attribute-validation-source.cxx
@@ -0,0 +1,410 @@
+// file : xsd/cxx/parser/attribute-validation-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/parser/attribute-validation-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace
+ {
+ struct Test: Traversal::Attribute,
+ Traversal::AnyAttribute,
+ protected virtual Context
+ {
+ Test (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Attribute& a)
+ {
+ String const& name (a.name ());
+
+ if (a.qualified () && a.namespace_ ().name ())
+ {
+ String const& ns (a.namespace_ ().name ());
+
+ os << "n == " << L << strlit (name) << " &&" << endl
+ << "ns == " << L << strlit (ns);
+ }
+ else
+ os << "n == " << L << strlit (name) << " && ns.empty ()";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute& a)
+ {
+ String const& ns (a.definition_namespace ().name ());
+
+ for (SemanticGraph::AnyAttribute::NamespaceIterator
+ i (a.namespace_begin ()), e (a.namespace_end ()); i != e;)
+ {
+ if (*i == L"##any")
+ {
+ os << "!n.empty ()";
+ }
+ else if (*i == L"##other")
+ {
+ if (ns)
+ {
+ // Note that here I assume that ##other does not include
+ // unqualified names in a schema with target namespace.
+ // This is not what the spec says but that seems to be
+ // the consensus.
+ //
+ os << "(!ns.empty () && ns != " << L << strlit (ns) << ")";
+ }
+ else
+ os << "!ns.empty ()";
+ }
+ else if (*i == L"##local")
+ {
+ os << "(ns.empty () && !n.empty ())";
+ }
+ else if (*i == L"##targetNamespace")
+ {
+ os << "ns == " << L << strlit (ns);
+ }
+ else
+ {
+ os << "ns == " << L << strlit (*i);
+ }
+
+ if (++i != e)
+ os << " ||" << endl;
+ }
+ }
+ };
+
+ //
+ //
+ struct PhaseOne : Traversal::Attribute,
+ protected virtual Context
+ {
+ PhaseOne (Context& c)
+ : Context (c), test_ (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ String const& name (ename (a));
+ String const& inst (emember (a));
+
+ SemanticGraph::Type& type (a.type ());
+ String const& post (post_name (type));
+ String const& ret (ret_type (type));
+
+ os << "if (";
+
+ test_.traverse (a);
+
+ os << ")"
+ << "{"
+ << "if (this->" << inst << ")"
+ << "{"
+ << "this->" << inst << "->pre ();"
+ << "this->" << inst << "->_pre_impl ();"
+ << "this->" << inst << "->_characters (s);"
+ << "this->" << inst << "->_post_impl ();";
+
+ if (ret == L"void")
+ os << "this->" << inst << "->" << post << " ();"
+ << "this->" << name << " ();";
+ else
+ os << arg_type (type) << " tmp (this->" << inst << "->" <<
+ post << " ());"
+ << "this->" << name << " (tmp);"
+ << endl;
+
+ os << "}";
+
+ if (!a.optional ())
+ os << "static_cast< v_state_attr_* > (" <<
+ "this->v_state_attr_stack_.top ())->" << name << " = true;";
+
+ os << "return true;"
+ << "}";
+ }
+
+ private:
+ Test test_;
+ };
+
+
+ //
+ //
+ struct PhaseTwo : Traversal::AnyAttribute,
+ protected virtual Context
+ {
+ PhaseTwo (Context& c)
+ : Context (c), test_ (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ os << "if (";
+
+ test_.traverse (a);
+
+ os << ")" << endl
+ << "{"
+ << "this->_any_attribute (ns, n, s);"
+ << "return true;"
+ << "}";
+ }
+
+ private:
+ Test test_;
+ };
+
+
+ //
+ //
+ struct AttributeStateInit: Traversal::Attribute,
+ protected virtual Context
+ {
+ AttributeStateInit (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ if (!a.optional ())
+ os << "as." << ename (a) << " = false;";
+ }
+ };
+
+
+ //
+ //
+ struct AttributeStateCheck: Traversal::Attribute,
+ protected virtual Context
+ {
+ AttributeStateCheck (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ if (!a.optional ())
+ {
+ String ns (a.qualified () ? a.namespace_ ().name () : String ());
+
+ os << "if (!as." << ename (a) << ")" << endl
+ << "this->_expected_attribute (" << endl
+ << L << strlit (ns) << ", " << L << strlit (a.name ()) << ");";
+ }
+ }
+ };
+
+ //
+ //
+ struct Complex : Traversal::Complex,
+ protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c),
+ phase_one_ (c),
+ phase_two_ (c),
+ attribute_state_init_ (c),
+ attribute_state_check_ (c)
+ {
+ names_phase_one_ >> phase_one_;
+ names_phase_two_ >> phase_two_;
+
+ names_attribute_state_init_ >> attribute_state_init_;
+ names_attribute_state_check_ >> attribute_state_check_;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ Boolean has_att (has<Traversal::Attribute> (c));
+ Boolean has_any (has<Traversal::AnyAttribute> (c));
+
+ if (!has_att && !has_any)
+ return;
+
+ Boolean has_req_att (false);
+ if (has_att)
+ {
+ RequiredAttributeTest test (has_req_att);
+ Traversal::Names names_test (test);
+ names (c, names_test);
+ }
+
+ String const& name (ename (c));
+
+ os <<"// Attribute validation and dispatch functions for " <<
+ name << "." << endl
+ <<"//" << endl;
+
+ if (has_att)
+ {
+ // _attribute_impl_phase_one
+ //
+ os << "bool " << name << "::" << endl
+ << "_attribute_impl_phase_one (const " << string_type <<
+ "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "& s)" << endl
+ << "{";
+
+ names (c, names_phase_one_);
+
+ // Nothing matched - call our base (extension) or return false
+ // if there is no base (or restriction (even from anyType)).
+ //
+ os << "return ";
+
+ if (c.inherits_p () &&
+ !c.inherits ().is_a<SemanticGraph::Restricts> ())
+ {
+ os << "this->" << fq_name (c.inherits ().base ()) <<
+ "::_attribute_impl_phase_one (ns, n, s);";
+ }
+ else
+ os << "false;";
+
+ os << "}";
+ }
+
+
+ if (has_any)
+ {
+ // _attribute_impl_phase_two
+ //
+ os << "bool " << name << "::" << endl
+ << "_attribute_impl_phase_two (const " << string_type <<
+ "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "& s)"
+ << "{";
+
+ names (c, names_phase_two_);
+
+ // Nothing matched - call our base (extension) or return false
+ // if there is no base (or restriction (even from anyType)).
+ //
+ os << "return ";
+
+ if (c.inherits_p () &&
+ !c.inherits ().is_a<SemanticGraph::Restricts> ())
+ {
+ os << "this->" << fq_name (c.inherits ().base ()) <<
+ "::_attribute_impl_phase_two (ns, n, s);";
+ }
+ else
+ os << "false;";
+
+ os << "}";
+ }
+
+ if (has_req_att)
+ {
+ // _pre_a_validate
+ //
+ os << "void " << name << "::" << endl
+ << "_pre_a_validate ()"
+ << "{"
+ << "this->v_state_attr_stack_.push ();"
+ << "v_state_attr_& as = *static_cast< v_state_attr_* > (" <<
+ "this->v_state_attr_stack_.top ());"
+ << endl;
+
+ names (c, names_attribute_state_init_);
+
+ // Call our base (extension) last.
+ //
+ if (c.inherits_p () &&
+ !c.inherits ().is_a<SemanticGraph::Restricts> ())
+ {
+ os << "this->" << fq_name (c.inherits ().base ()) <<
+ "::_pre_a_validate ();";
+ }
+
+ os << "}";
+
+
+ // _post_a_validate
+ //
+ os << "void " << name << "::" << endl
+ << "_post_a_validate ()"
+ << "{";
+
+ // Call our base (extension) first.
+ //
+ if (c.inherits_p () &&
+ !c.inherits ().is_a<SemanticGraph::Restricts> ())
+ {
+ os << "this->" << fq_name (c.inherits ().base ()) <<
+ "::_post_a_validate ();"
+ << endl;
+ }
+
+ os << "v_state_attr_& as = *static_cast< v_state_attr_* > (" <<
+ "this->v_state_attr_stack_.top ());"
+ << endl;
+
+ names (c, names_attribute_state_check_);
+
+ os << endl
+ << "this->v_state_attr_stack_.pop ();"
+ << "}";
+ }
+ }
+
+ private:
+ PhaseOne phase_one_;
+ Traversal::Names names_phase_one_;
+
+ PhaseTwo phase_two_;
+ Traversal::Names names_phase_two_;
+
+ AttributeStateInit attribute_state_init_;
+ Traversal::Names names_attribute_state_init_;
+
+ AttributeStateCheck attribute_state_check_;
+ Traversal::Names names_attribute_state_check_;
+ };
+ }
+
+ Void
+ generate_attribute_validation_source (Context& ctx)
+ {
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names schema_names;
+
+ Namespace ns (ctx);
+ Traversal::Names names;
+
+ schema >> sources >> schema;
+ schema >> schema_names >> ns >> names;
+
+ Complex complex (ctx);
+
+ names >> complex;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
+
diff --git a/xsd/cxx/parser/attribute-validation-source.hxx b/xsd/cxx/parser/attribute-validation-source.hxx
new file mode 100644
index 0000000..400e460
--- /dev/null
+++ b/xsd/cxx/parser/attribute-validation-source.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/parser/attribute-validation-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_ATTRIBUTE_VALIDATION_SOURCE_HXX
+#define CXX_PARSER_ATTRIBUTE_VALIDATION_SOURCE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/parser/elements.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ Void
+ generate_attribute_validation_source (Context&);
+ }
+}
+
+#endif // CXX_PARSER_ATTRIBUTE_VALIDATION_SOURCE_HXX
diff --git a/xsd/cxx/parser/characters-validation-source.cxx b/xsd/cxx/parser/characters-validation-source.cxx
new file mode 100644
index 0000000..ec698f8
--- /dev/null
+++ b/xsd/cxx/parser/characters-validation-source.cxx
@@ -0,0 +1,77 @@
+// file : xsd/cxx/parser/characters-validation-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/parser/characters-validation-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace
+ {
+ //
+ //
+ struct Complex : Traversal::Complex,
+ protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ if (!c.mixed ())
+ return;
+
+ String const& name (ename (c));
+
+ os <<"// Character validation functions for " << name << "." << endl
+ <<"//" << endl;
+
+ // _characters_impl
+ //
+ os << "bool " << name << "::" << endl
+ << "_characters_impl (const " << string_type << "& s)"
+ << "{"
+ << "this->_any_characters (s);"
+ << "return true;"
+ << "}";
+ }
+ };
+ }
+
+ Void
+ generate_characters_validation_source (Context& ctx)
+ {
+ //@@ Most of the time there is no mixed content type so
+ // we generate an empty namespace which looks ugly. Will
+ // need to implement smart namespace to handle this at
+ // some point.
+ //
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names schema_names;
+
+ Namespace ns (ctx);
+ Traversal::Names names;
+
+ schema >> sources >> schema;
+ schema >> schema_names >> ns >> names;
+
+ Complex complex (ctx);
+
+ names >> complex;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
+
diff --git a/xsd/cxx/parser/characters-validation-source.hxx b/xsd/cxx/parser/characters-validation-source.hxx
new file mode 100644
index 0000000..c9e9889
--- /dev/null
+++ b/xsd/cxx/parser/characters-validation-source.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/parser/characters-validation-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_CHARACTERS_VALIDATION_SOURCE_HXX
+#define CXX_PARSER_CHARACTERS_VALIDATION_SOURCE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/parser/elements.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ Void
+ generate_characters_validation_source (Context&);
+ }
+}
+
+#endif // CXX_PARSER_CHARACTERS_VALIDATION_SOURCE_HXX
diff --git a/xsd/cxx/parser/cli.hxx b/xsd/cxx/parser/cli.hxx
new file mode 100644
index 0000000..504de43
--- /dev/null
+++ b/xsd/cxx/parser/cli.hxx
@@ -0,0 +1,152 @@
+// file : xsd/cxx/parser/cli.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_CLI_HXX
+#define CXX_PARSER_CLI_HXX
+
+#include <cult/types.hxx>
+
+#include <cult/containers/vector.hxx>
+
+#include <cult/cli/options.hxx>
+#include <cult/cli/options-spec.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace CLI
+ {
+ using namespace Cult::Types;
+
+ typedef Char const Key[];
+
+ extern Key type_map;
+ extern Key char_type;
+ extern Key output_dir;
+ extern Key xml_parser;
+ extern Key generate_inline;
+ extern Key generate_validation;
+ extern Key suppress_validation;
+ extern Key generate_polymorphic;
+ extern Key generate_noop_impl;
+ extern Key generate_print_impl;
+ extern Key generate_test_driver;
+ extern Key force_overwrite;
+ extern Key root_element_first;
+ extern Key root_element_last;
+ extern Key root_element;
+ extern Key generate_xml_schema;
+ extern Key extern_xml_schema;
+ extern Key skel_type_suffix;
+ extern Key skel_file_suffix;
+ extern Key impl_type_suffix;
+ extern Key impl_file_suffix;
+ extern Key namespace_map;
+ extern Key namespace_regex;
+ extern Key namespace_regex_trace;
+ extern Key reserved_name;
+ extern Key include_with_brackets;
+ extern Key include_prefix;
+ extern Key include_regex;
+ extern Key include_regex_trace;
+ extern Key guard_prefix;
+ extern Key hxx_suffix;
+ extern Key ixx_suffix;
+ extern Key cxx_suffix;
+ extern Key hxx_regex;
+ extern Key ixx_regex;
+ extern Key cxx_regex;
+ extern Key hxx_prologue;
+ extern Key ixx_prologue;
+ extern Key cxx_prologue;
+ extern Key prologue;
+ extern Key hxx_epilogue;
+ extern Key ixx_epilogue;
+ extern Key cxx_epilogue;
+ extern Key epilogue;
+ extern Key hxx_prologue_file;
+ extern Key ixx_prologue_file;
+ extern Key cxx_prologue_file;
+ extern Key prologue_file;
+ extern Key hxx_epilogue_file;
+ extern Key ixx_epilogue_file;
+ extern Key cxx_epilogue_file;
+ extern Key epilogue_file;
+ extern Key export_symbol;
+ extern Key export_maps;
+ extern Key import_maps;
+ extern Key show_anonymous;
+ extern Key show_sloc;
+ extern Key proprietary_license;
+
+ typedef Cult::CLI::Options<
+ type_map, Cult::Containers::Vector<NarrowString>,
+ char_type, NarrowString,
+ output_dir, NarrowString,
+ xml_parser, NarrowString,
+ generate_inline, Boolean,
+ generate_validation, Boolean,
+ suppress_validation, Boolean,
+ generate_polymorphic, Boolean,
+ generate_noop_impl, Boolean,
+ generate_print_impl, Boolean,
+ generate_test_driver, Boolean,
+ force_overwrite, Boolean,
+ root_element_first, Boolean,
+ root_element_last, Boolean,
+ root_element, NarrowString,
+ generate_xml_schema, Boolean,
+ extern_xml_schema, NarrowString,
+ skel_type_suffix, NarrowString,
+ skel_file_suffix, NarrowString,
+ impl_type_suffix, NarrowString,
+ impl_file_suffix, NarrowString,
+ namespace_map, Cult::Containers::Vector<NarrowString>,
+ namespace_regex, Cult::Containers::Vector<NarrowString>,
+ namespace_regex_trace, Boolean,
+ reserved_name, Cult::Containers::Vector<NarrowString>,
+ include_with_brackets, Boolean,
+ include_prefix, NarrowString,
+ include_regex, Cult::Containers::Vector<NarrowString>,
+ include_regex_trace, Boolean,
+ guard_prefix, NarrowString,
+ hxx_suffix, NarrowString,
+ ixx_suffix, NarrowString,
+ cxx_suffix, NarrowString,
+ hxx_regex, NarrowString,
+ ixx_regex, NarrowString,
+ cxx_regex, NarrowString,
+ hxx_prologue, Cult::Containers::Vector<NarrowString>,
+ ixx_prologue, Cult::Containers::Vector<NarrowString>,
+ cxx_prologue, Cult::Containers::Vector<NarrowString>,
+ prologue, Cult::Containers::Vector<NarrowString>,
+ hxx_epilogue, Cult::Containers::Vector<NarrowString>,
+ ixx_epilogue, Cult::Containers::Vector<NarrowString>,
+ cxx_epilogue, Cult::Containers::Vector<NarrowString>,
+ epilogue, Cult::Containers::Vector<NarrowString>,
+ hxx_prologue_file, NarrowString,
+ ixx_prologue_file, NarrowString,
+ cxx_prologue_file, NarrowString,
+ prologue_file, NarrowString,
+ hxx_epilogue_file, NarrowString,
+ ixx_epilogue_file, NarrowString,
+ cxx_epilogue_file, NarrowString,
+ epilogue_file, NarrowString,
+ export_symbol, NarrowString,
+ export_maps, Boolean,
+ import_maps, Boolean,
+ show_anonymous, Boolean,
+ show_sloc, Boolean,
+ proprietary_license, Boolean
+
+ > Options;
+
+ struct OptionsSpec: Cult::CLI::OptionsSpec<Options> {};
+ }
+ }
+}
+
+#endif // CXX_PARSER_CLI_HXX
diff --git a/xsd/cxx/parser/driver-source.cxx b/xsd/cxx/parser/driver-source.cxx
new file mode 100644
index 0000000..91c4cca
--- /dev/null
+++ b/xsd/cxx/parser/driver-source.cxx
@@ -0,0 +1,768 @@
+// file : xsd/cxx/parser/driver-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/parser/driver-source.hxx>
+#include <cxx/parser/print-impl-common.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cult/containers/map.hxx>
+#include <cult/containers/set.hxx>
+
+#include <sstream>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace
+ {
+ typedef
+ Cult::Containers::Map<SemanticGraph::Type*, String>
+ TypeInstanceMap;
+
+ typedef Cult::Containers::Set<String> InstanceSet;
+
+ // For base types we only want member's types, but not the
+ // base itself.
+ //
+ struct BaseType: Traversal::Complex, Context
+ {
+ BaseType (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ inherits (c);
+
+ if (!restriction_p (c))
+ names (c);
+ }
+ };
+
+ struct ParserDef: Traversal::Type,
+ Traversal::List,
+ Traversal::Complex,
+
+ Traversal::AnyType,
+ Traversal::AnySimpleType,
+
+ Traversal::Fundamental::Byte,
+ Traversal::Fundamental::UnsignedByte,
+ Traversal::Fundamental::Short,
+ Traversal::Fundamental::UnsignedShort,
+ Traversal::Fundamental::Int,
+ Traversal::Fundamental::UnsignedInt,
+ Traversal::Fundamental::Long,
+ Traversal::Fundamental::UnsignedLong,
+ Traversal::Fundamental::Integer,
+ Traversal::Fundamental::NonPositiveInteger,
+ Traversal::Fundamental::NonNegativeInteger,
+ Traversal::Fundamental::PositiveInteger,
+ Traversal::Fundamental::NegativeInteger,
+
+ Traversal::Fundamental::Boolean,
+
+ Traversal::Fundamental::Float,
+ Traversal::Fundamental::Double,
+ Traversal::Fundamental::Decimal,
+
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NameTokens,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Language,
+
+ Traversal::Fundamental::QName,
+
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef,
+ Traversal::Fundamental::IdRefs,
+
+ Traversal::Fundamental::AnyURI,
+
+ Traversal::Fundamental::Base64Binary,
+ Traversal::Fundamental::HexBinary,
+
+ Traversal::Fundamental::Date,
+ Traversal::Fundamental::DateTime,
+ Traversal::Fundamental::Duration,
+ Traversal::Fundamental::Day,
+ Traversal::Fundamental::Month,
+ Traversal::Fundamental::MonthDay,
+ Traversal::Fundamental::Year,
+ Traversal::Fundamental::YearMonth,
+ Traversal::Fundamental::Time,
+
+ Traversal::Fundamental::Entity,
+ Traversal::Fundamental::Entities,
+
+ Context
+ {
+ ParserDef (Context& c, TypeInstanceMap& map, InstanceSet& set)
+ : Context (c), map_ (map), set_ (set), base_ (c)
+ {
+ *this >> inherits_ >> base_ >> inherits_;
+
+ *this >> names_;
+ base_ >> names_;
+
+ names_ >> member_ >> belongs_ >> *this;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type& t)
+ {
+ if (map_.find (&t) == map_.end ())
+ {
+ String inst (find_instance_name (t));
+ map_[&t] = inst;
+
+ os << fq_name (t, "impl") << " " << inst << ";";
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::List& l)
+ {
+ if (map_.find (&l) == map_.end ())
+ {
+ String inst (find_instance_name (l));
+ map_[&l] = inst;
+
+ os << fq_name (l, "impl") << " " << inst << ";";
+
+ dispatch (l.argumented ().type ());
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ if (map_.find (&c) == map_.end ())
+ {
+ String inst (find_instance_name (c));
+ map_[&c] = inst;
+
+ os << fq_name (c, "impl") << " " << inst << ";";
+
+ inherits (c);
+
+ if (!restriction_p (c))
+ names (c);
+ }
+ }
+
+ // anyType & anySimpleType.
+ //
+ virtual Void
+ traverse (SemanticGraph::AnyType& t)
+ {
+ fund_type (t, "any_type");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnySimpleType& t)
+ {
+ fund_type (t, "any_simple_type");
+ }
+
+ // Boolean.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Boolean& t)
+ {
+ fund_type (t, "boolean");
+ }
+
+ // Integral types.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Byte& t)
+ {
+ fund_type (t, "byte");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedByte& t)
+ {
+ fund_type (t, "unsigned_byte");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Short& t)
+ {
+ fund_type (t, "short");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedShort& t)
+ {
+ fund_type (t, "unsigned_short");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Int& t)
+ {
+ fund_type (t, "int");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedInt& t)
+ {
+ fund_type (t, "unsigned_int");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Long& t)
+ {
+ fund_type (t, "long");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedLong& t)
+ {
+ fund_type (t, "unsigned_long");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Integer& t)
+ {
+ fund_type (t, "integer");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger& t)
+ {
+ fund_type (t, "non_positive_integer");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger& t)
+ {
+ fund_type (t, "non_negative_integer");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::PositiveInteger& t)
+ {
+ fund_type (t, "positive_integer");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NegativeInteger& t)
+ {
+ fund_type (t, "negative_integer");
+ }
+
+ // Floats.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Float& t)
+ {
+ fund_type (t, "float");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Double& t)
+ {
+ fund_type (t, "double");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Decimal& t)
+ {
+ fund_type (t, "decimal");
+ }
+
+ // Strings.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String& t)
+ {
+ fund_type (t, "string");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString& t)
+ {
+ fund_type (t, "normalized_string");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token& t)
+ {
+ fund_type (t, "token");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken& t)
+ {
+ fund_type (t, "nmtoken");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameTokens& t)
+ {
+ fund_type (t, "nmtokens");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name& t)
+ {
+ fund_type (t, "name");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName& t)
+ {
+ fund_type (t, "ncname");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Language& t)
+ {
+ fund_type (t, "language");
+ }
+
+
+ // Qualified name.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::QName& t)
+ {
+ fund_type (t, "qname");
+ }
+
+
+ // ID/IDREF.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id& t)
+ {
+ fund_type (t, "id");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef& t)
+ {
+ fund_type (t, "idref");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRefs& t)
+ {
+ fund_type (t, "idrefs");
+ }
+
+ // URI.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::AnyURI& t)
+ {
+ fund_type (t, "uri");
+ }
+
+ // Binary.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Base64Binary& t)
+ {
+ fund_type (t, "base64_binary");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::HexBinary& t)
+ {
+ fund_type (t, "hex_binary");
+ }
+
+
+ // Date/time.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Date& t)
+ {
+ fund_type (t, "date");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::DateTime& t)
+ {
+ fund_type (t, "date_time");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Duration& t)
+ {
+ fund_type (t, "duration");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Day& t)
+ {
+ fund_type (t, "day");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Month& t)
+ {
+ fund_type (t, "month");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::MonthDay& t)
+ {
+ fund_type (t, "month_day");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Year& t)
+ {
+ fund_type (t, "year");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::YearMonth& t)
+ {
+ fund_type (t, "year_month");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Time& t)
+ {
+ fund_type (t, "time");
+ }
+
+ // Entity.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entity& t)
+ {
+ fund_type (t, "entity");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entities& t)
+ {
+ fund_type (t, "entities");
+ }
+
+ private:
+ virtual Void
+ fund_type (SemanticGraph::Type& t, String const& name)
+ {
+ if (map_.find (&t) == map_.end ())
+ {
+ String inst (find_instance_name (name));
+ map_[&t] = inst;
+
+ os << fq_name (t, "impl") << " " << inst << ";";
+ }
+ }
+
+ String
+ find_instance_name (String const& raw_name)
+ {
+ String base_name (escape (raw_name + L"_p"));
+ String name (base_name);
+
+ for (UnsignedLong i (1); set_.find (name) != set_.end (); ++i)
+ {
+ std::wostringstream os;
+ os << i;
+ name = base_name + os.str ();
+ }
+
+ set_.insert (name);
+ return name;
+ }
+
+ String
+ find_instance_name (SemanticGraph::Type& t)
+ {
+ return find_instance_name (t.name ());
+ }
+
+ TypeInstanceMap& map_;
+ InstanceSet& set_;
+
+ BaseType base_;
+ Traversal::Inherits inherits_;
+
+ Traversal::Names names_;
+ Traversal::Member member_;
+ Traversal::Belongs belongs_;
+ };
+
+ struct ArgList : Traversal::Complex,
+ Traversal::List,
+ Traversal::Member,
+ Context
+ {
+ ArgList (Context& c, TypeInstanceMap& map)
+ : Context (c), map_ (map), first_ (true)
+ {
+ inherits_ >> *this;
+ names_ >> *this;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ inherits (c, inherits_);
+
+ if (!restriction_p (c))
+ names (c, names_);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::List& l)
+ {
+ if (!first_)
+ os << "," << endl;
+ else
+ first_ = false;
+
+ os << map_[&l.argumented ().type ()];
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Member& m)
+ {
+ if (skip (m))
+ return;
+
+ if (!first_)
+ os << "," << endl;
+ else
+ first_ = false;
+
+ os << map_[&m.type ()];
+ }
+
+ private:
+ TypeInstanceMap& map_;
+
+ Traversal::Inherits inherits_;
+ Traversal::Names names_;
+
+ Boolean first_;
+ };
+
+ struct ParserConnect: Traversal::List,
+ Traversal::Complex,
+ Context
+ {
+ ParserConnect (Context& c, TypeInstanceMap& map)
+ : Context (c), map_ (map), base_ (c)
+ {
+ *this >> inherits_ >> base_ >> inherits_;
+
+ *this >> names_;
+ base_ >> names_;
+
+ names_ >> member_ >> belongs_ >> *this;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::List& l)
+ {
+ if (type_set_.find (&l) == type_set_.end ())
+ {
+ os << map_[&l] << ".parsers (" <<
+ map_[&l.argumented ().type ()] << ");"
+ << endl;
+
+ type_set_.insert (&l);
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ if (type_set_.find (&c) == type_set_.end ())
+ {
+ if (has_members (c))
+ {
+ os << map_[&c] << ".parsers (";
+
+ ArgList args (*this, map_);
+ args.dispatch (c);
+
+ os << ");"
+ << endl;
+ }
+
+ type_set_.insert (&c);
+
+ inherits (c);
+
+ if (!restriction_p (c))
+ names (c);
+ }
+ }
+
+ private:
+ Boolean
+ has_members (SemanticGraph::Complex& c)
+ {
+ using SemanticGraph::Complex;
+
+ if (has<Traversal::Member> (c))
+ return true;
+
+ if (c.inherits_p ())
+ {
+ SemanticGraph::Type& b (c.inherits ().base ());
+
+ if (Complex* cb = dynamic_cast<Complex*> (&b))
+ return has_members (*cb);
+
+ return b.is_a<SemanticGraph::List> ();
+ }
+
+ return false;
+ }
+
+ private:
+ TypeInstanceMap& map_;
+ Cult::Containers::Set<SemanticGraph::Type*> type_set_;
+
+ BaseType base_;
+ Traversal::Inherits inherits_;
+
+ Traversal::Names names_;
+ Traversal::Member member_;
+ Traversal::Belongs belongs_;
+ };
+ }
+
+ Void
+ generate_driver_source (Context& ctx)
+ {
+ // Figure out the root element. Validator should have made sure
+ // it is unique.
+ //
+ SemanticGraph::Element* root (0);
+ {
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+
+ schema >> sources >> schema;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ RootElement root_element (ctx.options, root);
+
+ schema >> schema_names >> ns >> ns_names >> root_element;
+
+ schema.dispatch (ctx.schema_root);
+ }
+
+ std::wostream& os (ctx.os);
+ String const& L (ctx.L);
+ String const& cerr (ctx.cerr_inst);
+
+ InstanceSet set;
+ TypeInstanceMap map;
+ SemanticGraph::Type& root_type (root->type ());
+
+ set.insert ("doc_p");
+
+ os << "#include <iostream>" << endl
+ << endl
+ << "int" << endl
+ << "main (int argc, char* argv[])"
+ << "{"
+ << "if (argc != 2)"
+ << "{"
+ << cerr << " << " << L << "\"usage: \" << argv[0] << " <<
+ L << "\" file.xml\" << std::endl;"
+ << "return 1;"
+ << "}"
+ << "try"
+ << "{"
+ << "// Instantiate individual parsers." << endl
+ << "//" << endl;
+
+ {
+ ParserDef def (ctx, map, set);
+ def.dispatch (root_type);
+ }
+
+ os << endl
+ << "// Connect the parsers together." << endl
+ << "//" << endl;
+
+ {
+ ParserConnect connect (ctx, map);
+ connect.dispatch (root_type);
+ }
+
+ String const& root_p (map[&root_type]);
+
+ os << "// Parse the XML document." << endl
+ << "//" << endl;
+
+ if (root->namespace_().name ())
+ os << ctx.xs_ns_name () << "::document doc_p (" << endl
+ << root_p << "," << endl
+ << L << ctx.strlit (root->namespace_().name ()) << "," << endl
+ << L << ctx.strlit (root->name ()) << ");"
+ << endl;
+ else
+ os << ctx.xs_ns_name () << "::document doc_p (" << root_p << ", " <<
+ L << ctx.strlit (root->name ()) << ");"
+ << endl;
+
+ os << root_p << ".pre ();"
+ << "doc_p.parse (argv[1]);";
+
+ String const& ret (Context::ret_type (root_type));
+ String const& post (Context::post_name (root_type));
+
+ if (ret == L"void")
+ os << root_p << "." << post << " ();";
+ else
+ {
+ os << Context::arg_type (root_type) << " v (" <<
+ root_p << "." << post << " ());"
+ << endl;
+
+ if (ctx.options.value<CLI::generate_print_impl> ())
+ {
+ PrintCall t (ctx, root->name (), "v");
+ t.dispatch (root_type);
+ }
+ else
+ os << "// TODO" << endl
+ << "//" << endl;
+ }
+
+ os << "}" // try
+ << "catch (const " << ctx.xs_ns_name () << "::exception& e)"
+ << "{"
+ << cerr << " << e << std::endl;"
+ << "return 1;"
+ << "}"
+ << "catch (const std::ios_base::failure&)"
+ << "{"
+ << cerr << " << argv[1] << " <<
+ L << "\": error: io failure\" << std::endl;"
+ << "return 1;"
+ << "}"
+ << "}";
+ }
+ }
+}
diff --git a/xsd/cxx/parser/driver-source.hxx b/xsd/cxx/parser/driver-source.hxx
new file mode 100644
index 0000000..9e0912f
--- /dev/null
+++ b/xsd/cxx/parser/driver-source.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/parser/driver-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_DRIVER_SOURCE_HXX
+#define CXX_PARSER_DRIVER_SOURCE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/parser/elements.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ Void
+ generate_driver_source (Context&);
+ }
+}
+
+#endif // CXX_PARSER_DRIVER_SOURCE_HXX
diff --git a/xsd/cxx/parser/element-validation-source.cxx b/xsd/cxx/parser/element-validation-source.cxx
new file mode 100644
index 0000000..949f491
--- /dev/null
+++ b/xsd/cxx/parser/element-validation-source.cxx
@@ -0,0 +1,1587 @@
+// file : xsd/cxx/parser/element-validation-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/parser/element-validation-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cult/containers/vector.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace
+ {
+ typedef Cult::Containers::Vector<SemanticGraph::Particle*> Particles;
+
+
+ //
+ //
+ struct ParticleTest: Traversal::Compositor,
+ Traversal::Element,
+ Traversal::Any,
+ protected virtual Context
+ {
+ ParticleTest (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ String const& name (e.name ());
+
+ if (polymorphic && e.global ())
+ os << "(";
+
+ if (e.qualified () && e.namespace_ ().name ())
+ {
+ String const& ns (e.namespace_ ().name ());
+
+ os << "n == " << L << strlit (name) << " &&" << endl
+ << "ns == " << L << strlit (ns);
+ }
+ else
+ os << "n == " << L << strlit (name) << " && ns.empty ()";
+
+
+ // Only a globally-defined element can be a subst-group root.
+ //
+ if (polymorphic && e.global ())
+ {
+ os << ") ||" << endl
+ << "::xsd::cxx::parser::substitution_map_instance< " <<
+ char_type << " > ().check (" << endl
+ << "ns, n, " << L << strlit (e.namespace_ ().name ()) <<
+ ", " << L << strlit (name) << ", t)";
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ String const& ns (a.definition_namespace ().name ());
+
+ // Note that we need to make sure the "flush" element (both name
+ // and namespace are empty) does not match any compositor.
+ //
+ for (SemanticGraph::Any::NamespaceIterator i (a.namespace_begin ()),
+ e (a.namespace_end ()); i != e;)
+ {
+ if (*i == L"##any")
+ {
+ os << "!n.empty ()";
+ }
+ else if (*i == L"##other")
+ {
+ if (ns)
+ {
+ // Note that here I assume that ##other does not include
+ // unqualified names in a schema with target namespace.
+ // This is not what the spec says but that seems to be
+ // the consensus.
+ //
+ os << "(!ns.empty () && ns != " << L << strlit (ns) << ")";
+ }
+ else
+ os << "!ns.empty ()";
+ }
+ else if (*i == L"##local")
+ {
+ os << "(ns.empty () && !n.empty ())";
+ }
+ else if (*i == L"##targetNamespace")
+ {
+ os << "ns == " << L << strlit (ns);
+ }
+ else
+ {
+ os << "ns == " << L << strlit (*i);
+ }
+
+ if (++i != e)
+ os << " ||" << endl;
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Compositor& c)
+ {
+ // This compositor should already have been tested for
+ // triviality (empty).
+ //
+ Particles const& p (c.context ().get<Particles> ("prefixes"));
+
+ Boolean paren (p.size () != 1);
+
+ for (Particles::ConstIterator i (p.begin ()), e (p.end ());
+ i != e;)
+ {
+ if (paren)
+ os << "(";
+
+ dispatch (**i);
+
+ if (paren)
+ os << ")";
+
+ if (++i != e)
+ os << " ||" << endl;
+ }
+ }
+ };
+
+
+ // Generates particle namespace-name pair. Used to generate
+ // the _expected_element call.
+ //
+ struct ParticleName: Traversal::Compositor,
+ Traversal::Element,
+ Traversal::Any,
+ protected virtual Context
+ {
+ ParticleName (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ String ns (e.qualified () ? e.namespace_ ().name () : String ());
+ os << L << strlit (ns) << ", " << L << strlit (e.name ());
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ String const& ns (*a.namespace_begin ());
+ os << L << strlit (ns) << ", " << L << "\"*\"";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Compositor& c)
+ {
+ Particles const& p (c.context ().get<Particles> ("prefixes"));
+
+ dispatch (**p.begin ());
+ }
+ };
+
+
+ // Common base for the ParticleIn{All, Choice, Sequence} treversers.
+ //
+ struct ParticleInCompositor: protected Context
+ {
+ protected:
+ ParticleInCompositor (Context& c, SemanticGraph::Complex& type)
+ : Context (c), type_ (type), particle_test_ (c)
+ {
+ }
+
+
+ // Generate sub-parser setup code as well as the pre/post calls.
+ //
+ Void
+ pre_post_calls (SemanticGraph::Particle& p)
+ {
+ using SemanticGraph::Element;
+ using SemanticGraph::Complex;
+
+ if (Element* e = dynamic_cast<Element*> (&p))
+ {
+ SemanticGraph::Type& type (e->type ());
+ Boolean poly (polymorphic && !anonymous (type));
+
+ String name, inst, def_parser, map;
+
+ if (e->context ().count("name"))
+ {
+ name = ename (*e);
+ inst = poly ? emember_cache (*e) : emember (*e);
+
+ if (poly)
+ {
+ def_parser = emember (*e);
+ map = emember_map (*e);
+ }
+ }
+ else
+ {
+ // This is the subsequent mentioning of this element in the
+ // content. We need to find the first one in order to get
+ // to the escaped names.
+ //
+ Complex::NamesIteratorPair ip (type_.find (e->name ()));
+ assert (ip.first != ip.second);
+ Element& fe (dynamic_cast<Element&>(ip.first->named ()));
+
+ name = ename (fe);
+ inst = poly ? emember_cache (fe) : emember (fe);
+
+ if (poly)
+ {
+ def_parser = emember (fe);
+ map = emember_map (fe);
+ }
+ }
+
+ if (poly)
+ {
+ // For pre-computing length.
+ //
+ String type_id (type.name ());
+
+ if (String type_ns = xml_ns_name (type))
+ {
+ type_id += L' ';
+ type_id += type_ns;
+ }
+
+ os << "if (t == 0 && this->" << def_parser << " != 0)" << endl
+ << "this->" << inst << " = this->" << def_parser << ";"
+ << "else"
+ << "{"
+ << string_type << " ts (" << fq_name (type) <<
+ "::_static_type (), " << type_id.size () << "UL);"
+ << endl
+ << "if (t == 0)" << endl
+ << "t = &ts;"
+ << endl
+ << "if (this->" << def_parser << " != 0 && *t == ts)" << endl
+ << "this->" << inst << " = this->" << def_parser << ";"
+ << "else"
+ << "{";
+
+ // Check that the types are related by inheritance.
+ //
+ os << "if (t != &ts &&" << endl
+ << "!::xsd::cxx::parser::validating::" <<
+ "inheritance_map_instance< " << char_type <<
+ " > ().check (" << endl
+ << "t->data (), ts))" << endl
+ << "throw ::xsd::cxx::parser::dynamic_type< " << char_type <<
+ " > (*t);"
+ << endl
+ << "if (this->" << map << " != 0)" << endl
+ << "this->" << inst << " = dynamic_cast< " <<
+ fq_name (type) << "* > (" << endl
+ << "this->" << map << "->find (*t));"
+ << "else" << endl
+ << "this->" << inst << " = 0;"
+ << "}"
+ << "}";
+ }
+
+ os << "this->" << complex_base << "::context_.top ()." <<
+ "parser_ = this->" << inst << ";"
+ << endl
+ << "if (this->" << inst << ")" << endl
+ << "this->" << inst << "->pre ();"
+ << "}"
+ << "else" // start
+ << "{"
+ << "if (this->" << inst << ")"
+ << "{";
+
+ String const& ret (ret_type (type));
+ String const& post (post_name (type));
+
+ if (ret == L"void")
+ os << "this->" << inst << "->" << post << " ();"
+ << "this->" << name << " ();";
+ else
+ os << arg_type (type) << " tmp (this->" << inst << "->" <<
+ post << " ());"
+ << "this->" << name << " (tmp);";
+
+ os << "}";
+ }
+ else
+ {
+ os << "this->_start_any_element (ns, n, t);"
+ << "this->" << complex_base << "::context_.top ().any_ = true;"
+ << "}"
+ << "else" // start
+ << "{"
+ << "this->" << complex_base << "::context_.top ().any_ = false;"
+ << "this->_end_any_element (ns, n);";
+ }
+ }
+
+ protected:
+ SemanticGraph::Complex& type_;
+ ParticleTest particle_test_;
+ };
+
+
+
+ // The 'all' compositor can only contain elements with min={0,1}, max=1.
+ //
+ struct ParticleInAll: Traversal::Element,
+ ParticleInCompositor
+ {
+ ParticleInAll (Context& c, SemanticGraph::Complex& type)
+ : ParticleInCompositor (c, type)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ UnsignedLong state (e.context ().get<UnsignedLong> ("state"));
+
+ if (state != 0)
+ os << "else ";
+
+ os << "if (";
+
+ particle_test_.traverse (e);
+
+ os << ")"
+ << "{"
+ << "if (count[" << state << "UL] == 0)"
+ << "{"
+ << "if (start)"
+ << "{";
+
+ pre_post_calls (e);
+
+ os << "count[" << state << "UL] = 1;"
+ << "}"
+ << "}"
+ << "else" // count != 0
+ << "{"
+ << "assert (start);" // Assuming well-formed XML.
+
+ // Since there is never more content after 'all', we could have
+ // as well thrown here. But instead we will let the code in
+ // start_element handle this along with other unexpected
+ // elements.
+ //
+ << "state = ~0UL;"
+ << "}"
+ << "}";
+ }
+ };
+
+
+ //
+ //
+ struct ParticleInChoice: Traversal::Particle,
+ Traversal::Compositor,
+ ParticleInCompositor
+ {
+ ParticleInChoice (Context& c, SemanticGraph::Complex& type)
+ : ParticleInCompositor (c, type), particle_name_ (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Particle& p)
+ {
+ using SemanticGraph::Element;
+
+ UnsignedLong state (p.context ().get<UnsignedLong> ("state"));
+
+ UnsignedLong min (p.min ()), max (p.max ());
+
+ os << "case " << state << "UL:" << endl
+ << "{";
+
+ if (max != 1) // We don't need the test if max == 1.
+ {
+ os << "if (";
+
+ particle_test_.dispatch (p);
+
+ os << ")"
+ << "{";
+ }
+
+ os << "if (start)"
+ << "{";
+
+ pre_post_calls (p);
+
+ switch (max)
+ {
+ case 0:
+ {
+ os << "count++;";
+ break;
+ }
+ case 1:
+ {
+ // We do not need to increment count because min <= max and
+ // we do not generate min check for min <= 1 (see below).
+ //
+ os << "state = ~0UL;";
+ break;
+ }
+ default:
+ {
+ os << "if (++count == " << max << "UL)" << endl
+ << "state = ~0UL;";
+ }
+ };
+
+ os << "}"; // start
+
+ // We've already moved to the final state if max == 1.
+ //
+ if (max != 1)
+ {
+ os << "}"
+ << "else"
+ << "{"
+ << "assert (start);"; // Assuming well-formed XML
+
+ // Check if min cardinality requirements have been met. Since
+ // count is always >= 1, don't generate dead code if min <= 1.
+ //
+ if (min > 1)
+ {
+ os << "if (count < " << min << "UL)" << endl
+ << "this->_expected_element (" << endl;
+
+ particle_name_.dispatch (p);
+
+ os << "," << endl
+ << "ns, n);";
+ }
+
+
+ os << "state = ~0UL;"
+ << "}";
+ }
+
+ os << "break;"
+ << "}"; // case
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Compositor& c)
+ {
+ using SemanticGraph::Compositor;
+
+ UnsignedLong max (c.max ());
+ UnsignedLong min (c.context ().get<UnsignedLong> ("effective-min"));
+ UnsignedLong n (c.context ().get<UnsignedLong> ("comp-number"));
+ UnsignedLong state (c.context ().get<UnsignedLong> ("state"));
+
+ String func (c.is_a<SemanticGraph::Choice> () ?
+ "choice_" : "sequence_");
+
+ os << "case " << state << "UL:" << endl
+ << "{"
+ << "unsigned long s (~0UL);"
+ << endl;
+
+ Boolean first (true);
+
+ for (Compositor::ContainsIterator ci (c.contains_begin ());
+ ci != c.contains_end (); ++ci)
+ {
+ SemanticGraph::Particle& p (ci->particle ());
+
+ if (p.is_a<Compositor> () && !c.context ().count ("comp-number"))
+ continue; // Empty compositor.
+
+ if (!p.context ().count ("prefix"))
+ break;
+
+ UnsignedLong state (p.context ().get<UnsignedLong> ("state"));
+
+ if (first)
+ first = false;
+ else
+ os << "else ";
+
+ os << "if (";
+
+ particle_test_.dispatch (p);
+
+ os << ")" << endl
+ << "s = " << state << "UL;";
+ }
+
+ // This compositor.
+ //
+ os << endl
+ << "if (s != ~0UL)"
+ << "{"
+ << "assert (start);"; // End is handled by the sub-machine.
+
+ switch (max)
+ {
+ case 0:
+ {
+ os << "count++;";
+ break;
+ }
+ case 1:
+ {
+ // We do not need to increment count because min <= max and
+ // we do not generate min check for min <= 1 (see below).
+ //
+ os << "state = ~0UL;";
+ break;
+ }
+ default:
+ {
+ os << "if (++count == " << max << "UL)" << endl
+ << "state = ~0UL;";
+ }
+ };
+
+ // Delegate to the sub-machine.
+ //
+
+ os << endl
+ << "v_state_& vs = *static_cast< v_state_* > (" <<
+ "this->v_state_stack_.top ());"
+ << "v_state_descr_& vd = vs.data[vs.size++];" // push
+ << endl
+ << "vd.func = &" << ename (type_) << "::" << func << n << ";"
+ << "vd.state = s;"
+ << "vd.count = 0;"
+ << endl
+ << "this->" << func << n << " (vd.state, vd.count, ns, n, t, true);"
+ << "}";
+
+
+ // Not this compositor. We've elready moved to the final state
+ // if max == 1.
+ //
+ if (max != 1)
+ {
+ os << "else"
+ << "{"
+ << "assert (start);"; // Assuming well-formed XML
+
+ // Check if min cardinality requirements have been met. Since
+ // count is always >= 1, don't generate dead code if min <= 1.
+ //
+ if (min > 1)
+ {
+ os << "if (count < " << min << "UL)" << endl
+ << "this->_expected_element (" << endl;
+
+ particle_name_.dispatch (c);
+
+ os << "," << endl
+ << "ns, n);";
+ }
+
+ os << "state = ~0UL;"
+ << "}";
+ }
+
+ os << "break;"
+ << "}"; // case
+ }
+
+ private:
+ ParticleName particle_name_;
+ };
+
+
+ //
+ //
+ struct ParticleInSequence: Traversal::Particle,
+ Traversal::Compositor,
+ ParticleInCompositor
+ {
+ ParticleInSequence (Context& c,
+ UnsignedLong state,
+ UnsignedLong next_state,
+ SemanticGraph::Complex& type)
+ : ParticleInCompositor (c, type),
+ state_ (state), particle_name_ (c)
+ {
+ // next_state == 0 indicates the terminal state (~0UL).
+ //
+ if (next_state != 0)
+ {
+ std::wostringstream ostr;
+ ostr << next_state;
+ next_state_ = ostr.str ();
+ }
+ else
+ next_state_ = L"~0";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Particle& p)
+ {
+ UnsignedLong min (p.min ()), max (p.max ());
+
+ os << "case " << state_ << "UL:" << endl
+ << "{"
+ << "if (";
+
+ particle_test_.dispatch (p);
+
+ os << ")"
+ << "{";
+
+ // This element.
+ //
+
+ os << "if (start)"
+ << "{";
+
+ pre_post_calls (p);
+
+ switch (max)
+ {
+ case 0:
+ {
+ os << "count++;";
+ break;
+ }
+ case 1:
+ {
+ os << "count = 0;"
+ << "state = " << next_state_ << "UL;";
+ break;
+ }
+ default:
+ {
+ os << "if (++count == " << max << "UL)"
+ << "{"
+ << "count = 0;"
+ << "state = " << next_state_ << "UL;"
+ << "}";
+ }
+ };
+
+ os << "}" // start
+ << "break;"
+ << "}";
+
+ // Not this element.
+ //
+
+ os << "else"
+ << "{"
+ << "assert (start);"; // Assuming well-formed XML.
+
+ // Check if min cardinality requirements have been met. Since
+ // count is always >= 0, don't generate dead code if min == 0.
+ //
+ if (min != 0)
+ {
+ os << "if (count < " << min << "UL)" << endl
+ << "this->_expected_element (" << endl;
+
+ particle_name_.dispatch (p);
+
+ os << "," << endl
+ << "ns, n);";
+ }
+
+ os << "count = 0;"
+ << "state = " << next_state_ << "UL;"
+ << "// Fall through." << endl
+ << "}" // else
+ << "}"; // case
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Compositor& c)
+ {
+ using SemanticGraph::Compositor;
+
+ UnsignedLong max (c.max ());
+ UnsignedLong min (c.context ().get<UnsignedLong> ("effective-min"));
+ UnsignedLong n (c.context ().get<UnsignedLong> ("comp-number"));
+
+ String func (c.is_a<SemanticGraph::Choice> () ?
+ "choice_" : "sequence_");
+
+ os << "case " << state_ << "UL:" << endl
+ << "{"
+ << "unsigned long s (~0UL);"
+ << endl;
+
+ Boolean first (true);
+
+ for (Compositor::ContainsIterator ci (c.contains_begin ());
+ ci != c.contains_end (); ++ci)
+ {
+ SemanticGraph::Particle& p (ci->particle ());
+
+ if (p.is_a<Compositor> () && !c.context ().count ("comp-number"))
+ continue; // Empty compositor.
+
+ if (!p.context ().count ("prefix"))
+ break;
+
+ UnsignedLong state (p.context ().get<UnsignedLong> ("state"));
+
+ if (first)
+ first = false;
+ else
+ os << "else ";
+
+ os << "if (";
+
+ particle_test_.dispatch (p);
+
+ os << ")" << endl
+ << "s = " << state << "UL;";
+ }
+
+ // This element.
+ //
+
+ os << endl
+ << "if (s != ~0UL)"
+ << "{"
+ << "assert (start);"; // End is handled by the sub-machine.
+
+ switch (max)
+ {
+ case 0:
+ {
+ os << "count++;"
+ << endl;
+ break;
+ }
+ case 1:
+ {
+ os << "count = 0;"
+ << "state = " << next_state_ << "UL;"
+ << endl;
+ break;
+ }
+ default:
+ {
+ os << "if (++count == " << max << "UL)"
+ << "{"
+ << "count = 0;"
+ << "state = " << next_state_ << "UL;"
+ << "}";
+ }
+ };
+
+ // Delegate to the sub-machine.
+ //
+
+ os << "v_state_& vs = *static_cast< v_state_* > (" <<
+ "this->v_state_stack_.top ());"
+ << "v_state_descr_& vd = vs.data[vs.size++];" // push
+ << endl
+ << "vd.func = &" << ename (type_) << "::" << func << n << ";"
+ << "vd.state = s;"
+ << "vd.count = 0;"
+ << endl
+ << "this->" << func << n << " (vd.state, vd.count, ns, n, t, true);"
+ << "break;"
+ << "}";
+
+ // Not this compositor.
+ //
+
+ os << "else"
+ << "{"
+ << "assert (start);"; // Assuming well-formed XML
+
+ // Check if min cardinality requirements have been met. Since
+ // count is always >= 0, don't generate dead code if min == 0.
+ //
+ if (min != 0)
+ {
+ os << "if (count < " << min << "UL)" << endl
+ << "this->_expected_element (" << endl;
+
+ particle_name_.dispatch (c);
+
+ os << "," << endl
+ << "ns, n);";
+ }
+
+ os << "count = 0;"
+ << "state = " << next_state_ << "UL;"
+ << "// Fall through." << endl
+ << "}" // else
+ << "}"; // case
+ }
+
+ private:
+ UnsignedLong state_;
+ String next_state_;
+
+ ParticleName particle_name_;
+ };
+
+
+ //
+ //
+ struct ParticleFunction: Traversal::All,
+ Traversal::Choice,
+ Traversal::Sequence,
+ protected virtual Context
+ {
+ ParticleFunction (Context& c, SemanticGraph::Complex& type)
+ : Context (c), type_ (type)
+ {
+ *this >> contains_particle_ >> *this;
+ }
+
+
+ virtual Void
+ traverse (SemanticGraph::All& a)
+ {
+ if (!a.context().count ("comp-number")) // Empty compositor.
+ return;
+
+ using SemanticGraph::Element;
+ using SemanticGraph::Compositor;
+
+
+ os << "void " << ename (type_) << "::" << endl
+ << "all_0 (unsigned long& state," << endl
+ << "unsigned char* count," << endl
+ << "const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "* t," << endl
+ << "bool start)"
+ << "{"
+ << "XSD_UNUSED (t);"
+ << endl;
+
+ for (Compositor::ContainsIterator ci (a.contains_begin ()),
+ ce (a.contains_end ()); ci != ce; ++ci)
+ {
+ ParticleInAll t (*this, type_);
+ t.dispatch (ci->particle ());
+ }
+
+ // Handle the flush.
+ //
+ os << "else if (n.empty () && ns.empty ())"
+ << "{";
+
+ for (Compositor::ContainsIterator ci (a.contains_begin ()),
+ ce (a.contains_end ()); ci != ce; ++ci)
+ {
+ if (ci->min () == 0)
+ continue;
+
+ Element& e (dynamic_cast<Element&> (ci->particle ()));
+ String ns (e.qualified () ? e.namespace_ ().name () : String ());
+ UnsignedLong state (e.context ().get<UnsignedLong> ("state"));
+
+ os << "if (count[" << state << "UL] == 0)" << endl
+ << "this->_expected_element (" << endl
+ << L << strlit (ns) << ", " <<
+ L << strlit (e.name ()) << ");"
+ << endl;
+ }
+
+ os << "state = ~0UL;"
+ << "}"
+ << "else" << endl
+ << "state = ~0UL;"
+ << "}";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Choice& c)
+ {
+ if (!c.context().count ("comp-number")) // Empty compositor.
+ return;
+
+ using SemanticGraph::Compositor;
+
+ UnsignedLong n (c.context ().get<UnsignedLong> ("comp-number"));
+
+ os << "void " << ename (type_) << "::" << endl
+ << "choice_" << n << " (unsigned long& state," << endl
+ << "unsigned long& count," << endl
+ << "const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "* t," << endl
+ << "bool start)"
+ << "{"
+ << "XSD_UNUSED (count);"
+ << "XSD_UNUSED (ns);"
+ << "XSD_UNUSED (n);"
+ << "XSD_UNUSED (t);"
+ << endl
+ << "switch (state)"
+ << "{";
+
+ for (Compositor::ContainsIterator ci (c.contains_begin ()),
+ ce (c.contains_end ()); ci != ce; ++ci)
+ {
+ SemanticGraph::Particle& p (ci->particle ());
+
+ if (p.is_a<Compositor> () && !p.context().count ("comp-number"))
+ continue; // Empty compositor.
+
+ ParticleInChoice t (*this, type_);
+ t.dispatch (p);
+ }
+
+ os << "}" // switch
+ << "}";
+
+ // Generate nested compositor functions.
+ //
+ Traversal::Choice::traverse (c);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Sequence& s)
+ {
+ if (!s.context().count ("comp-number")) // Empty compositor.
+ return;
+
+ using SemanticGraph::Compositor;
+
+ UnsignedLong n (s.context ().get<UnsignedLong> ("comp-number"));
+
+ os << "void " << ename (type_) << "::" << endl
+ << "sequence_" << n << " (unsigned long& state," << endl
+ << "unsigned long& count," << endl
+ << "const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "* t," << endl
+ << "bool start)"
+ << "{"
+ << "XSD_UNUSED (t);"
+ << endl
+ << "switch (state)"
+ << "{";
+
+ UnsignedLong state (0);
+
+ for (Compositor::ContainsIterator ci (s.contains_begin ()),
+ ce (s.contains_end ()); ci != ce;)
+ {
+ SemanticGraph::Particle& p (ci->particle ());
+
+ if (p.is_a<Compositor> () && !p.context().count ("comp-number"))
+ {
+ // Empty compositor.
+ //
+ ++ci;
+ continue;
+ }
+
+ // Find the next state.
+ //
+ do
+ ++ci;
+ while (ci != ce &&
+ ci->particle ().is_a<Compositor> () &&
+ !ci->particle ().context().count ("comp-number"));
+
+ UnsignedLong next (ci == ce ? 0 : state + 1);
+
+ ParticleInSequence t (*this, state++, next, type_);
+ t.dispatch (p);
+ }
+
+ os << "case ~0UL:" << endl
+ << "break;"
+ << "}" // switch
+ << "}";
+
+ // Generate nested compositor functions.
+ //
+ Traversal::Sequence::traverse (s);
+ }
+
+ private:
+ SemanticGraph::Complex& type_;
+ Traversal::ContainsParticle contains_particle_;
+ };
+
+
+ //
+ //
+ struct CompositorPre: Traversal::All,
+ Traversal::Compositor,
+ protected virtual Context
+ {
+ CompositorPre (Context& c, SemanticGraph::Complex& type)
+ : Context (c), type_ (type)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::All& a)
+ {
+ // Clear the counts and push the initial state.
+ //
+ os << "v_all_count_.push ();"
+ << endl;
+
+ SemanticGraph::Compositor& c (a);
+ traverse (c);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Compositor&) // Choice and sequence.
+ {
+ os << "v_state_& vs = *static_cast< v_state_* > (" <<
+ "this->v_state_stack_.top ());"
+ << "v_state_descr_& vd = vs.data[vs.size++];" // push
+ << endl
+ << "vd.func = 0;"
+ << "vd.state = 0;"
+ << "vd.count = 0;";
+ }
+
+ private:
+ SemanticGraph::Complex& type_;
+ };
+
+
+ //
+ //
+ struct CompositorStartElement: Traversal::All,
+ Traversal::Compositor,
+ protected virtual Context
+ {
+ CompositorStartElement (Context& c, SemanticGraph::Complex& type)
+ : Context (c), type_ (type),
+ particle_test_ (c), particle_name_ (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::All&)
+ {
+ // The 'all' state machine reaches the final state only
+ // on an unknown element, in which case we won't get here
+ // again (it would be a validation error). Note that 'all'
+ // compositor cannot contain nested compositors so we don't
+ // need to re-set vd.
+ //
+ os << "all_0 (vd->state, v_all_count_.top (), ns, n, t, true);"
+ << endl
+ << "if (vd->state != ~0UL)" << endl
+ << "vd->count++;"
+ << "else" << endl
+ << "return false;" // Let our parent handle this.
+ << endl;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Compositor& c) // Choice and sequence.
+ {
+ using SemanticGraph::Compositor;
+
+ UnsignedLong max (c.max ());
+ UnsignedLong min (c.context ().get<UnsignedLong> ("effective-min"));
+ UnsignedLong n (c.context ().get<UnsignedLong> ("comp-number"));
+
+ String func (c.is_a<SemanticGraph::Choice> () ?
+ "choice_" : "sequence_");
+
+ // Invoke the current state machine. If it reaches its
+ // terminal state, pop it and invoke the next one until
+ // we reach the top, which requires special handling.
+ //
+ os << "while (vd->func != 0)"
+ << "{"
+ << "(this->*vd->func) (vd->state, vd->count, ns, n, t, true);"
+ << endl
+ << "vd = vs.data + (vs.size - 1);" // re-acquire
+ << endl
+ << "if (vd->state == ~0UL)" << endl
+ << "vd = vs.data + (--vs.size - 1);" // pop
+ << "else" << endl
+ << "break;"
+ << "}";
+
+
+ // Check if we got to the top. This code is pretty much the
+ // same as the one found in ParticleInSequence.
+ //
+ os << "if (vd->func == 0)"
+ << "{"
+ << "if (vd->state != ~0UL)"
+ << "{"
+ << "unsigned long s = ~0UL;"
+ << endl;
+
+ Boolean first (true);
+
+ // Note that we don't need to worry about the compositor
+ // being empty - this case is handled by our caller.
+ //
+ for (Compositor::ContainsIterator ci (c.contains_begin ());
+ ci != c.contains_end (); ++ci)
+ {
+ SemanticGraph::Particle& p (ci->particle ());
+
+ if (p.is_a<Compositor> () && !c.context ().count ("comp-number"))
+ continue; // Empty compositor.
+
+ if (!p.context ().count ("prefix"))
+ break;
+
+ UnsignedLong state (p.context ().get<UnsignedLong> ("state"));
+
+ if (first)
+ first = false;
+ else
+ os << "else ";
+
+ os << "if (";
+
+ particle_test_.dispatch (p);
+
+ os << ")" << endl
+ << "s = " << state << "UL;";
+ }
+
+ os << endl
+ << "if (s != ~0UL)"
+ << "{";
+
+ // This element is a prefix of the root compositor.
+ //
+
+ switch (max)
+ {
+ case 0:
+ {
+ os << "vd->count++;";
+ break;
+ }
+ case 1:
+ {
+ os << "vd->count++;"
+ << "vd->state = ~0UL;";
+ break;
+ }
+ default:
+ {
+ os << "if (++vd->count == " << max << "UL)" << endl
+ << "vd->state = ~0UL;";
+ }
+ };
+
+ // Delegate to the sub-machine.
+ //
+
+ os << endl
+ << "vd = vs.data + vs.size++;" // push
+ << "vd->func = &" << ename (type_) << "::" << func << n << ";"
+ << "vd->state = s;"
+ << "vd->count = 0;"
+ << endl
+ << "this->" << func << n << " (vd->state, vd->count, ns, n, t, true);"
+ << "}";
+
+ // This element is not our prefix.
+ //
+
+ os << "else"
+ << "{";
+
+ // Check if min cardinality requirements have been met. Since
+ // count is always >= 0, don't generate dead code if min == 0.
+ //
+ if (min != 0)
+ {
+ os << "if (vd->count < " << min << "UL)" << endl
+ << "this->_expected_element (" << endl;
+
+ particle_name_.dispatch (c);
+
+ os << "," << endl
+ << "ns, n);";
+ }
+
+ // Return false to indicate that we are not handling this element.
+ //
+ os << "return false;"
+ << "}"
+ << "}" // if (state != ~0)
+ << "else" << endl
+ << "return false;"
+ << "}"; // if (function == 0)
+ }
+
+ private:
+ SemanticGraph::Complex& type_;
+ ParticleTest particle_test_;
+ ParticleName particle_name_;
+ };
+
+
+ //
+ //
+ struct CompositorEndElement: Traversal::All,
+ Traversal::Compositor,
+ protected virtual Context
+ {
+ CompositorEndElement (Context& c, SemanticGraph::Complex& type)
+ : Context (c), type_ (type)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::All&)
+ {
+ os << "all_0 (vd.state, v_all_count_.top (), " <<
+ "ns, n, 0, false);"
+ << endl;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Compositor&) // Choice and sequence.
+ {
+ os << "assert (vd.func != 0);"
+ << "(this->*vd.func) (vd.state, vd.count, ns, n, 0, false);"
+ << endl
+ << "if (vd.state == ~0UL)" << endl
+ << "vs.size--;" // pop
+ << endl;
+ }
+
+ private:
+ SemanticGraph::Complex& type_;
+ };
+
+
+ //
+ //
+ struct CompositorPost: Traversal::All,
+ Traversal::Compositor,
+ protected virtual Context
+ {
+ CompositorPost (Context& c, SemanticGraph::Complex& type)
+ : Context (c), type_ (type), particle_name_ (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::All& a)
+ {
+ using SemanticGraph::Element;
+
+ os << "v_state_& vs = *static_cast< v_state_* > (" <<
+ "this->v_state_stack_.top ());"
+ << "v_state_descr_& vd = vs.data[vs.size - 1];"
+ << endl;
+
+ // Flush the state machine with the empty element name. This
+ // allows us to detect missing content.
+ //
+ os << "if (vd.count != 0)"
+ << "{"
+ << string_type << " empty;"
+ << "all_0 (vd.state, v_all_count_.top (), empty, empty, 0, true);"
+ << "}";
+
+ if (a.context ().get<UnsignedLong> ("effective-min") != 0)
+ {
+ os << "else" << endl
+ << "this->_expected_element (" << endl;
+
+ particle_name_.dispatch (a);
+
+ os << ");";
+ }
+
+ os << endl
+ << "vs.size--;" // pop
+ << "v_all_count_.pop ();";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Compositor& c) // Choice and sequence.
+ {
+ UnsignedLong min (c.context ().get<UnsignedLong> ("effective-min"));
+
+ os << "v_state_& vs = *static_cast< v_state_* > (" <<
+ "this->v_state_stack_.top ());"
+ << "v_state_descr_* vd = vs.data + (vs.size - 1);"
+ << endl;
+
+
+ // Flush unfinished state machines with the empty element name.
+ // This allows us to detect missing content. Note that I am
+ // not re-setting vd since no new compositors are pushed on
+ // flush.
+ //
+ os << string_type << " empty;"
+ << "while (vd->func != 0)"
+ << "{"
+ << "(this->*vd->func) (vd->state, vd->count, empty, empty, 0, true);"
+ << "assert (vd->state == ~0UL);"
+ << "vd = vs.data + (--vs.size - 1);" // pop
+ << "}";
+
+ // Check if min cardinality requirements have been met. Since
+ // count is always >= 0, don't generate dead code if min == 0.
+ //
+ if (min != 0)
+ {
+ os << "if (vd->count < " << min << "UL)" << endl
+ << "this->_expected_element (" << endl;
+
+ particle_name_.dispatch (c);
+
+ os << ");";
+ }
+ }
+
+ private:
+ SemanticGraph::Complex& type_;
+ ParticleName particle_name_;
+ };
+
+
+ //
+ //
+ struct Complex : Traversal::Complex,
+ protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ // Nothing to generate if we don't have any elements and wildcards.
+ //
+ if (!has<Traversal::Element> (c) &&
+ !has_particle<Traversal::Any> (c))
+ return;
+
+ using SemanticGraph::Compositor;
+
+ String const& name (ename (c));
+ Compositor& comp (c.contains_compositor ().compositor ());
+
+ // Don't use restriction_p here since we don't want special
+ // treatment of anyType.
+ //
+ Boolean restriction (
+ c.inherits_p () &&
+ c.inherits ().is_a<SemanticGraph::Restricts> ());
+
+ os <<"// Element validation and dispatch functions for " <<
+ name << "." << endl
+ <<"//" << endl;
+
+ // _start_element_impl
+ //
+
+ os << "bool " << name << "::" << endl
+ << "_start_element_impl (const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "* t)"
+ << "{"
+ << "XSD_UNUSED (t);"
+ << endl;
+
+ os << "v_state_& vs = *static_cast< v_state_* > (" <<
+ "this->v_state_stack_.top ());"
+ << "v_state_descr_* vd = vs.data + (vs.size - 1);"
+ << endl;
+
+ //@@ OPT: I don't really need to call parser_base since it always
+ // returns false.
+ //
+ // In case of an inheritance-by-extension, call our base first.
+ // We don't need to generate this code for the 'all' compositor
+ // because it can only inherit from the empty content model.
+ // States of the root machine for sequence and choice:
+ //
+ // 0 - calling base
+ // 1 - base returned false
+ // ~0 - terminal state
+ //
+ if (!restriction && !comp.is_a<SemanticGraph::All> ())
+ {
+ os << "if (vd->func == 0 && vd->state == 0)"
+ << "{"
+ << "if (this->";
+
+ if (c.inherits_p ())
+ os << fq_name (c.inherits ().base ());
+ else
+ os << complex_base;
+
+
+ os << "::_start_element_impl (ns, n, t))" << endl
+ << "return true;"
+ << "else" << endl
+ << "vd->state = 1;"
+ << "}";
+ }
+
+ {
+ CompositorStartElement t (*this, c);
+ t.dispatch (comp);
+ }
+
+ os << "return true;"
+ << "}";
+
+
+ // _end_element_impl
+ //
+
+ os << "bool " << name << "::" << endl
+ << "_end_element_impl (const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n)"
+ << "{";
+
+ os << "v_state_& vs = *static_cast< v_state_* > (" <<
+ "this->v_state_stack_.top ());"
+ << "v_state_descr_& vd = vs.data[vs.size - 1];"
+ << endl;
+
+ //@@ OPT: I don't really need to call parser_base since it always
+ // returns false.
+ //
+ // In case of an inheritance-by-extension, call our base first.
+ // We don't need to generate this code for the 'all' compositor
+ // because it can only inherit from the empty content model.
+ //
+ if (!restriction && !comp.is_a<SemanticGraph::All> ())
+ {
+ os << "if (vd.func == 0 && vd.state == 0)"
+ << "{"
+ << "if (!";
+
+ if (c.inherits_p ())
+ os << fq_name (c.inherits ().base ());
+ else
+ os << complex_base;
+
+ os << "::_end_element_impl (ns, n))" << endl
+ << "assert (false);" // Start and end should match.
+ << "return true;"
+ << "}";
+ }
+
+ {
+ CompositorEndElement t (*this, c);
+ t.dispatch (comp);
+ }
+
+ os << "return true;"
+ << "}";
+
+
+ // _pre_e_validate
+ //
+ os << "void " << name << "::" << endl
+ << "_pre_e_validate ()"
+ << "{"
+ << "this->v_state_stack_.push ();"
+ << "static_cast< v_state_* > (this->v_state_stack_.top ())->" <<
+ "size = 0;"
+ << endl;
+
+ {
+ CompositorPre t (*this, c);
+ t.dispatch (comp);
+ }
+
+ // In case of an inheritance-by-extension, call our base
+ // _pre_e_validate. We don't need to generate this code for the
+ // 'all' compositor because it can only inherit from the empty
+ // content model.
+ //
+ if (!restriction && !comp.is_a<SemanticGraph::All> ())
+ {
+ // We don't need to call parser_base's implementation
+ // since it does nothing.
+ //
+ if (c.inherits_p ())
+ {
+ os << endl
+ << fq_name (c.inherits ().base ()) << "::_pre_e_validate ();";
+ }
+ }
+
+ os << "}";
+
+
+ // _post_e_validate
+ //
+ os << "void " << name << "::" << endl
+ << "_post_e_validate ()"
+ << "{";
+
+ // In case of an inheritance-by-extension, call our base
+ // _post_e_validate. We don't need to generate this code for
+ // the 'all' compositor because it can only inherit from
+ // the empty content model.
+ //
+ if (!restriction && !comp.is_a<SemanticGraph::All> ())
+ {
+ // We don't need to call parser_base's implementation
+ // since it does nothing.
+ //
+ if (c.inherits_p ())
+ {
+ os << fq_name (c.inherits ().base ()) << "::_post_e_validate ();"
+ << endl;
+ }
+ }
+
+ {
+ CompositorPost t (*this, c);
+ t.dispatch (c.contains_compositor ().compositor ());
+ }
+
+ os << endl
+ << "this->v_state_stack_.pop ();"
+ << "}";
+
+ //
+ //
+ ParticleFunction t (*this, c);
+ t.dispatch (c.contains_compositor ().compositor ());
+ }
+ };
+ }
+
+ Void
+ generate_element_validation_source (Context& ctx)
+ {
+ ctx.os << "#include <cassert>" << endl
+ << endl;
+
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names schema_names;
+
+ Namespace ns (ctx);
+ Traversal::Names names;
+
+ schema >> sources >> schema;
+ schema >> schema_names >> ns >> names;
+
+ Complex complex (ctx);
+
+ names >> complex;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/parser/element-validation-source.hxx b/xsd/cxx/parser/element-validation-source.hxx
new file mode 100644
index 0000000..493c1ef
--- /dev/null
+++ b/xsd/cxx/parser/element-validation-source.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/parser/element-validation-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_ELEMENT_VALIDATION_SOURCE_HXX
+#define CXX_PARSER_ELEMENT_VALIDATION_SOURCE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/parser/elements.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ Void
+ generate_element_validation_source (Context&);
+ }
+}
+
+#endif // CXX_PARSER_ELEMENT_VALIDATION_SOURCE_HXX
diff --git a/xsd/cxx/parser/elements.cxx b/xsd/cxx/parser/elements.cxx
new file mode 100644
index 0000000..8a02ffb
--- /dev/null
+++ b/xsd/cxx/parser/elements.cxx
@@ -0,0 +1,262 @@
+// file : xsd/cxx/parser/elements.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/parser/elements.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ // Keep this symbol first to help HP-UX linker (long symbols?).
+ //
+ Content::Value Context::
+ content (SemanticGraph::Complex& c)
+ {
+ using namespace SemanticGraph;
+
+ if (c.mixed ())
+ return Content::mixed;
+
+ if (c.inherits_p ())
+ {
+ Type& base (c.inherits ().base ());
+
+ if (Complex* cb = dynamic_cast<Complex*> (&base))
+ return content (*cb);
+
+ if (base.is_a<AnyType> ())
+ return Content::complex;
+
+ // Everyhting else (built-in type and AnySimpleType) is simple
+ // content.
+ //
+ return Content::simple;
+ }
+ else
+ return Content::complex;
+ }
+
+ Context::
+ Context (std::wostream& o,
+ SemanticGraph::Schema& root,
+ CLI::Options const& ops,
+ Regex const* he,
+ Regex const* ie,
+ Regex const* hie)
+ : CXX::Context (o,
+ root,
+ ops.value<CLI::char_type> (),
+ ops.value<CLI::include_with_brackets> (),
+ ops.value<CLI::include_prefix> (),
+ ops.value<CLI::export_symbol> (),
+ ops.value<CLI::namespace_map> (),
+ ops.value<CLI::namespace_regex> (),
+ ops.value<CLI::namespace_regex_trace> (),
+ ops.value<CLI::include_regex> (),
+ ops.value<CLI::include_regex_trace> (),
+ ops.value<CLI::generate_inline> (),
+ ops.value<CLI::reserved_name> ()),
+ options (ops),
+ xml_parser (xml_parser_),
+ simple_base (simple_base_),
+ complex_base (complex_base_),
+ list_base (list_base_),
+ cout_inst (cout_inst_),
+ cerr_inst (cerr_inst_),
+ parser_map (parser_map_),
+ std_string_type (std_string_type_),
+ validation (validation_),
+ polymorphic (polymorphic_),
+ hxx_expr (he),
+ ixx_expr (ie),
+ hxx_impl_expr (hie),
+ xml_parser_ (ops.value<CLI::xml_parser> ()),
+ validation_ ((ops.value<CLI::xml_parser> () == "expat" ||
+ ops.value<CLI::generate_validation> ()) &&
+ !ops.value<CLI::suppress_validation> ()),
+ polymorphic_ (ops.value<CLI::generate_polymorphic> ())
+ {
+ if (char_type == L"char")
+ std_string_type = L"::std::string";
+ else if (char_type == L"wchar_t")
+ std_string_type = L"::std::wstring";
+ else
+ std_string_type = L"::std::basic_string< " + char_type + L" >";
+
+ String xs_ns (xs_ns_name ());
+
+ string_type = xs_ns + L"::ro_string";
+ simple_base = xs_ns + L"::simple_content";
+ complex_base = xs_ns + L"::complex_content";
+ list_base = xs_ns + L"::list_base";
+
+ cout_inst = (char_type == L"char" ? L"std::cout" : L"std::wcout");
+ cerr_inst = (char_type == L"char" ? L"std::cerr" : L"std::wcerr");
+
+ if (polymorphic)
+ parser_map_ = xs_ns + L"::parser_map";
+ }
+
+ Context::
+ Context (Context& c)
+ : CXX::Context (c),
+ options (c.options),
+ xml_parser (c.xml_parser),
+ simple_base (c.simple_base),
+ complex_base (c.complex_base),
+ list_base (c.list_base),
+ cout_inst (c.cout_inst),
+ cerr_inst (c.cerr_inst),
+ parser_map (c.parser_map),
+ std_string_type (c.std_string_type),
+ validation (c.validation),
+ polymorphic (c.polymorphic),
+ hxx_expr (c.hxx_expr),
+ ixx_expr (c.ixx_expr),
+ hxx_impl_expr (c.hxx_impl_expr)
+ {
+ }
+
+ Context::
+ Context (Context& c, std::wostream& o)
+ : CXX::Context (c, o),
+ options (c.options),
+ xml_parser (c.xml_parser),
+ simple_base (c.simple_base),
+ complex_base (c.complex_base),
+ list_base (c.list_base),
+ cout_inst (c.cout_inst),
+ cerr_inst (c.cerr_inst),
+ parser_map (c.parser_map),
+ std_string_type (c.std_string_type),
+ validation (c.validation),
+ polymorphic (c.polymorphic),
+ hxx_expr (c.hxx_expr),
+ ixx_expr (c.ixx_expr),
+ hxx_impl_expr (c.hxx_impl_expr)
+ {
+ }
+
+ Boolean Context::
+ anonymous (SemanticGraph::Type& t)
+ {
+ return t.context ().count ("anonymous");
+ }
+
+ String const& Context::
+ ret_type (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("ret-type");
+ }
+
+ String const& Context::
+ arg_type (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("arg-type");
+ }
+
+ String const& Context::
+ post_name (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("post");
+ }
+
+ String const& Context::
+ eparser (SemanticGraph::Member& m)
+ {
+ return m.context ().get<String> ("parser");
+ }
+
+ String const& Context::
+ emember (SemanticGraph::Member& m)
+ {
+ return m.context ().get<String> ("member");
+ }
+
+ String const& Context::
+ emember_cache (SemanticGraph::Member& m)
+ {
+ return m.context ().get<String> ("member-cache");
+ }
+
+ String const& Context::
+ emember_map (SemanticGraph::Member& m)
+ {
+ return m.context ().get<String> ("member-map");
+ }
+
+ String const& Context::
+ eimpl (SemanticGraph::Type& t)
+ {
+ return t.context ().get<String> ("impl");
+ }
+
+ // Includes
+ //
+ Void TypeForward::
+ traverse (SemanticGraph::Type& t)
+ {
+ os << "class " << t.context ().get<String> (name_key_) << ";";
+ }
+
+ Void Includes::
+ traverse_ (SemanticGraph::Uses& u)
+ {
+ // Support for weak (forward) inclusion used in the file-per-type
+ // compilation model.
+ //
+ Boolean weak (u.context ().count ("weak"));
+
+ if (weak && (type_ == header || type_ == impl_header))
+ {
+ // Generate forward declarations. We don't really need them
+ // in the impl files.
+ //
+ if (type_ == header)
+ schema_.dispatch (u.schema ());
+
+ return;
+ }
+
+ if (type_ == source && !weak)
+ return;
+
+ SemanticGraph::Path path (u.path ());
+
+ // Try to use the portable representation of the path. If that
+ // fails, fall back to the native representation.
+ //
+ NarrowString path_str;
+ try
+ {
+ path_str = path.string ();
+ }
+ catch (SemanticGraph::InvalidPath const&)
+ {
+ path_str = path.native_file_string ();
+ }
+
+ String inc_path;
+
+ switch (type_)
+ {
+ case header:
+ case source:
+ {
+ inc_path = ctx_.hxx_expr->merge (path_str);
+ break;
+ }
+ case impl_header:
+ {
+ inc_path = ctx_.hxx_impl_expr->merge (path_str);
+ break;
+ }
+ }
+
+ ctx_.os << "#include " << ctx_.process_include_path (inc_path) << endl
+ << endl;
+ }
+ }
+}
diff --git a/xsd/cxx/parser/elements.hxx b/xsd/cxx/parser/elements.hxx
new file mode 100644
index 0000000..cac1786
--- /dev/null
+++ b/xsd/cxx/parser/elements.hxx
@@ -0,0 +1,312 @@
+// file : xsd/cxx/parser/elements.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_ELEMENTS_HXX
+#define CXX_PARSER_ELEMENTS_HXX
+
+#include <sstream>
+
+#include <backend-elements/regex.hxx>
+
+#include <cxx/elements.hxx>
+
+#include <cxx/parser/cli.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ struct Content
+ {
+ enum Value
+ {
+ simple,
+ complex,
+ mixed
+ };
+ };
+
+ //
+ //
+ class Context: public CXX::Context
+ {
+ public:
+ typedef BackendElements::Regex::Expression<Char> Regex;
+
+ public:
+ Context (std::wostream&,
+ SemanticGraph::Schema&,
+ CLI::Options const&,
+ Regex const* hxx_expr,
+ Regex const* ixx_expr,
+ Regex const* hxx_impl_expr);
+
+ protected:
+ Context (Context& c);
+ Context (Context& c, std::wostream& o);
+
+ public:
+ Boolean
+ restriction_p (SemanticGraph::Complex& c) const
+ {
+ if (c.inherits_p () &&
+ c.inherits ().is_a<SemanticGraph::Restricts> ())
+ {
+ // Restriction of anyType is a special case.
+ //
+ return !c.inherits ().base ().is_a<SemanticGraph::AnyType> ();
+ }
+
+ return false;
+ }
+
+ public:
+ static Content::Value
+ content (SemanticGraph::Complex&);
+
+ public:
+ static Boolean
+ anonymous (SemanticGraph::Type&);
+
+ public:
+ static String const&
+ ret_type (SemanticGraph::Type&);
+
+ static String const&
+ arg_type (SemanticGraph::Type&);
+
+ static String const&
+ post_name (SemanticGraph::Type&);
+
+ public:
+ static String const&
+ eparser (SemanticGraph::Member&);
+
+ static String const&
+ emember (SemanticGraph::Member&);
+
+ static String const&
+ emember_cache (SemanticGraph::Member&);
+
+ static String const&
+ emember_map (SemanticGraph::Member&);
+
+ public:
+ static String const&
+ eimpl (SemanticGraph::Type&);
+
+ public:
+ CLI::Options const& options;
+ String& xml_parser;
+ String& simple_base;
+ String& complex_base;
+ String& list_base;
+ String& cout_inst;
+ String& cerr_inst;
+ String& parser_map;
+ String& std_string_type;
+ Boolean& validation;
+ Boolean& polymorphic;
+
+ Regex const* hxx_expr;
+ Regex const* ixx_expr;
+ Regex const* hxx_impl_expr;
+
+ private:
+ String xml_parser_;
+ String simple_base_;
+ String complex_base_;
+ String list_base_;
+ String cout_inst_;
+ String cerr_inst_;
+ String parser_map_;
+ String std_string_type_;
+ Boolean validation_;
+ Boolean polymorphic_;
+ };
+
+ //
+ //
+ struct RequiredAttributeTest: Traversal::Attribute
+ {
+ RequiredAttributeTest (Boolean& result)
+ : result_ (result)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ if (!result_ && !a.optional ())
+ result_ = true;
+ }
+
+ private:
+ Boolean& result_;
+ };
+
+ //
+ //
+ struct ParserParamDecl : Traversal::Complex,
+ Traversal::List,
+ Traversal::Member,
+ protected virtual Context
+ {
+ ParserParamDecl (Context& c, Boolean name_arg)
+ : Context (c), first_ (true), name_arg_ (name_arg)
+ {
+ inherits_ >> *this;
+ names_ >> *this;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ inherits (c, inherits_);
+
+ if (!restriction_p (c))
+ names (c, names_);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::List& l)
+ {
+ if (!first_)
+ os << "," << endl;
+ else
+ first_ = false;
+
+ os << fq_name (l.argumented ().type ()) << "&";
+
+ if (name_arg_)
+ os << " " << ename (l) << "_item";
+ else
+ os << " /* " << comment (l.name ()) << " item */";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Member& m)
+ {
+ if (skip (m)) return;
+
+ if (!first_)
+ os << "," << endl;
+ else
+ first_ = false;
+
+ os << fq_name (m.type ()) << "&";
+
+ if (name_arg_)
+ os << " " << ename (m);
+ else
+ os << " /* " << comment (m.name ()) << " */";
+ }
+
+ private:
+ Traversal::Inherits inherits_;
+ Traversal::Names names_;
+
+ Boolean first_;
+ Boolean name_arg_;
+ };
+
+
+ //
+ //
+ struct TypeForward: Traversal::Type, Context
+ {
+ TypeForward (Context& c, Char const* name_key)
+ : Context (c), name_key_ (name_key)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type& t);
+
+ private:
+ Char const* name_key_;
+ };
+
+ struct Includes : Traversal::Imports,
+ Traversal::Includes
+ {
+ enum Type
+ {
+ header,
+ source,
+ impl_header
+ };
+
+ Includes (Context& c, Type t)
+ : ctx_ (c),
+ type_ (t),
+ namespace_ (c),
+ type_forward_ (c, t == header ? "name" : "impl")
+ {
+ schema_ >> schema_names_ >> namespace_ >> names_ >> type_forward_;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Imports& i)
+ {
+ traverse_ (i);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Includes& i)
+ {
+ traverse_ (i);
+ }
+
+ private:
+ Void
+ traverse_ (SemanticGraph::Uses&);
+
+ private:
+ Context& ctx_;
+ Type type_;
+
+ Traversal::Schema schema_;
+ Traversal::Names schema_names_;
+ Namespace namespace_;
+ Traversal::Names names_;
+ TypeForward type_forward_;
+ };
+
+ // Find root element for the test driver.
+ //
+ struct RootElement: Traversal::Element
+ {
+ RootElement (CLI::Options const& options,
+ SemanticGraph::Element*& element)
+ : options_ (options), element_ (element)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (options_.value<CLI::root_element_first> ())
+ {
+ if (element_ == 0)
+ element_ = &e;
+ }
+ else if (String name = options_.value<CLI::root_element> ())
+ {
+ if (e.name () == name)
+ element_ = &e;
+ }
+ else
+ element_ = &e; // Cover root-element-last and no option.
+ }
+
+ private:
+ CLI::Options const& options_;
+ SemanticGraph::Element*& element_;
+ };
+ }
+}
+
+#endif // CXX_PARSER_ELEMENTS_HXX
diff --git a/xsd/cxx/parser/generator.cxx b/xsd/cxx/parser/generator.cxx
new file mode 100644
index 0000000..342e3f2
--- /dev/null
+++ b/xsd/cxx/parser/generator.cxx
@@ -0,0 +1,1450 @@
+// file : xsd/cxx/parser/generator.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <type-map/lexer.hxx>
+#include <type-map/parser.hxx>
+#include <type-map/type-map.hxx>
+
+#include <cxx/parser/elements.hxx>
+#include <cxx/parser/generator.hxx>
+
+#include <cxx/parser/validator.hxx>
+#include <cxx/parser/name-processor.hxx>
+#include <cxx/parser/state-processor.hxx>
+#include <cxx/parser/type-processor.hxx>
+
+#include <cxx/parser/parser-header.hxx>
+#include <cxx/parser/parser-inline.hxx>
+#include <cxx/parser/parser-source.hxx>
+#include <cxx/parser/parser-forward.hxx>
+
+#include <cxx/parser/impl-header.hxx>
+#include <cxx/parser/impl-source.hxx>
+#include <cxx/parser/driver-source.hxx>
+
+#include <cxx/parser/element-validation-source.hxx>
+#include <cxx/parser/attribute-validation-source.hxx>
+#include <cxx/parser/characters-validation-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+
+#include <backend-elements/regex.hxx>
+#include <backend-elements/indentation/cxx.hxx>
+#include <backend-elements/indentation/sloc.hxx>
+#include <backend-elements/indentation/clip.hxx>
+
+#include <cult/containers/set.hxx>
+#include <cult/containers/vector.hxx>
+
+#include <boost/filesystem/fstream.hpp>
+
+#include <iostream>
+
+#include <usage.hxx>
+
+#include "../../../libxsd/xsd/cxx/version.hxx"
+
+using std::endl;
+using std::wcerr;
+
+using namespace XSDFrontend::SemanticGraph;
+
+//
+//
+typedef
+boost::filesystem::wifstream
+WideInputFileStream;
+
+typedef
+boost::filesystem::wofstream
+WideOutputFileStream;
+
+typedef
+boost::filesystem::ifstream
+NarrowInputFileStream;
+
+namespace CXX
+{
+ namespace
+ {
+ Char const copyright_gpl[] =
+ "// Copyright (C) 2005-2009 Code Synthesis Tools CC\n"
+ "//\n"
+ "// This program was generated by CodeSynthesis XSD, an XML Schema to\n"
+ "// C++ data binding compiler.\n"
+ "//\n"
+ "// This program is free software; you can redistribute it and/or modify\n"
+ "// it under the terms of the GNU General Public License version 2 as\n"
+ "// published by the Free Software Foundation.\n"
+ "//\n"
+ "// This program is distributed in the hope that it will be useful,\n"
+ "// but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "// GNU General Public License for more details.\n"
+ "//\n"
+ "// You should have received a copy of the GNU General Public License\n"
+ "// along with this program; if not, write to the Free Software\n"
+ "// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
+ "//\n"
+ "// In addition, as a special exception, Code Synthesis Tools CC gives\n"
+ "// permission to link this program with the Xerces-C++ library (or with\n"
+ "// modified versions of Xerces-C++ that use the same license as Xerces-C++),\n"
+ "// and distribute linked combinations including the two. You must obey\n"
+ "// the GNU General Public License version 2 in all respects for all of\n"
+ "// the code used other than Xerces-C++. If you modify this copy of the\n"
+ "// program, you may extend this exception to your version of the program,\n"
+ "// but you are not obligated to do so. If you do not wish to do so, delete\n"
+ "// this exception statement from your version.\n"
+ "//\n"
+ "// Furthermore, Code Synthesis Tools CC makes a special exception for\n"
+ "// the Free/Libre and Open Source Software (FLOSS) which is described\n"
+ "// in the accompanying FLOSSE file.\n"
+ "//\n\n";
+
+ Char const copyright_proprietary[] =
+ "// Copyright (C) 2005-2009 Code Synthesis Tools CC\n"
+ "//\n"
+ "// This program was generated by CodeSynthesis XSD, an XML Schema\n"
+ "// to C++ data binding compiler, in the Proprietary License mode.\n"
+ "// You should have received a proprietary license from Code Synthesis\n"
+ "// Tools CC prior to generating this code. See the license text for\n"
+ "// conditions.\n"
+ "//\n\n";
+
+ Char const copyright_impl[] =
+ "// Not copyrighted - public domain.\n"
+ "//\n"
+ "// This sample parser implementation was generated by CodeSynthesis XSD,\n"
+ "// an XML Schema to C++ data binding compiler. You may use it in your\n"
+ "// programs without any restrictions.\n"
+ "//\n\n";
+ }
+
+ namespace Parser
+ {
+ namespace CLI
+ {
+ extern Key char_type;
+ extern Key type_map = "type-map";
+ extern Key char_type = "char-type";
+ extern Key output_dir = "output-dir";
+ extern Key xml_parser = "xml-parser";
+ extern Key generate_inline = "generate-inline";
+ extern Key generate_validation = "generate-validation";
+ extern Key suppress_validation = "suppress-validation";
+ extern Key generate_polymorphic = "generate-polymorphic";
+ extern Key generate_noop_impl = "generate-noop-impl";
+ extern Key generate_print_impl = "generate-print-impl";
+ extern Key generate_test_driver = "generate-test-driver";
+ extern Key force_overwrite = "force-overwrite";
+ extern Key root_element_first = "root-element-first";
+ extern Key root_element_last = "root-element-last";
+ extern Key root_element = "root-element";
+ extern Key generate_xml_schema = "generate-xml-schema";
+ extern Key extern_xml_schema = "extern-xml-schema";
+ extern Key skel_type_suffix = "skel-type-suffix";
+ extern Key skel_file_suffix = "skel-file-suffix";
+ extern Key impl_type_suffix = "impl-type-suffix";
+ extern Key impl_file_suffix = "impl-file-suffix";
+ extern Key namespace_map = "namespace-map";
+ extern Key namespace_regex = "namespace-regex";
+ extern Key namespace_regex_trace = "namespace-regex-trace";
+ extern Key reserved_name = "reserved-name";
+ extern Key include_with_brackets = "include-with-brackets";
+ extern Key include_prefix = "include-prefix";
+ extern Key include_regex = "include-regex";
+ extern Key include_regex_trace = "include-regex-trace";
+ extern Key guard_prefix = "guard-prefix";
+ extern Key hxx_suffix = "hxx-suffix";
+ extern Key ixx_suffix = "ixx-suffix";
+ extern Key cxx_suffix = "cxx-suffix";
+ extern Key hxx_regex = "hxx-regex";
+ extern Key ixx_regex = "ixx-regex";
+ extern Key cxx_regex = "cxx-regex";
+ extern Key hxx_prologue = "hxx-prologue";
+ extern Key ixx_prologue = "ixx-prologue";
+ extern Key cxx_prologue = "cxx-prologue";
+ extern Key prologue = "prologue";
+ extern Key hxx_epilogue = "hxx-epilogue";
+ extern Key ixx_epilogue = "ixx-epilogue";
+ extern Key cxx_epilogue = "cxx-epilogue";
+ extern Key epilogue = "epilogue";
+ extern Key hxx_prologue_file = "hxx-prologue-file";
+ extern Key ixx_prologue_file = "ixx-prologue-file";
+ extern Key cxx_prologue_file = "cxx-prologue-file";
+ extern Key prologue_file = "prologue-file";
+ extern Key hxx_epilogue_file = "hxx-epilogue-file";
+ extern Key ixx_epilogue_file = "ixx-epilogue-file";
+ extern Key cxx_epilogue_file = "cxx-epilogue-file";
+ extern Key epilogue_file = "epilogue-file";
+ extern Key export_symbol = "export-symbol";
+ extern Key export_maps = "export-maps";
+ extern Key import_maps = "import-maps";
+ extern Key show_anonymous = "show-anonymous";
+ extern Key show_sloc = "show-sloc";
+ extern Key proprietary_license = "proprietary-license";
+ }
+ }
+
+ Void Parser::Generator::
+ usage ()
+ {
+ std::wostream& e (wcerr);
+ ::CLI::Indent::Clip< ::CLI::OptionsUsage, WideChar> clip (e);
+
+ e << "--type-map <mapfile>" << endl
+ << " Read XML Schema to C++ type mapping information\n"
+ << " from <mapfile>. Repeat this option to specify\n"
+ << " several type maps. Type maps are considered in\n"
+ << " order of appearance and the first match is used."
+ << endl;
+
+ e << "--char-type <type>" << endl
+ << " Use <type> as the base character type. Valid\n"
+ << " values are 'char' (default) and 'wchar_t'."
+ << endl;
+
+ e << "--output-dir <dir>" << endl
+ << " Write generated files to <dir> instead of current\n"
+ << " directory."
+ << endl;
+
+ e << "--xml-parser <parser>" << endl
+ << " Use <parser> as the underlying XML parser. Valid\n"
+ << " values are 'xerces' (default) and 'expat'."
+ << endl;
+
+ e << "--generate-inline" << endl
+ << " Generate certain functions inline."
+ << endl;
+
+ e << "--generate-validation" << endl
+ << " Generate validation code."
+ << endl;
+
+ e << "--suppress-validation" << endl
+ << " Suppress the generation of validation code."
+ << endl;
+
+ e << "--generate-polymorphic" << endl
+ << " Generate polymorphism-aware code. Specify this\n"
+ << " option if you use substitution groups or xsi:type."
+ << endl;
+
+ e << "--generate-noop-impl" << endl
+ << " Generate a sample parser implementation that\n"
+ << " does nothing (no operation)."
+ << endl;
+
+ e << "--generate-print-impl" << endl
+ << " Generate a sample parser implementation that\n"
+ << " prints the XML data to STDOUT."
+ << endl;
+
+ e << "--generate-test-driver" << endl
+ << " Generate a test driver for the sample parser\n"
+ << " implementation."
+ << endl;
+
+ e << "--force-overwrite" << endl
+ << " Force overwriting of the existing implementation\n"
+ << " and test driver files."
+ << endl;
+
+ e << "--root-element-first" << endl
+ << " Indicate that the first global element is the\n"
+ << " document root."
+ << endl;
+
+ e << "--root-element-last" << endl
+ << " Indicate that the last global element is the\n"
+ << " document root."
+ << endl;
+
+ e << "--root-element <element>" << endl
+ << " Indicate that <element> is the document root."
+ << endl;
+
+ e << "--generate-xml-schema" << endl
+ << " Generate a C++ header file as if the schema being\n"
+ << " compiled defines the XML Schema namespace."
+ << endl;
+
+ e << "--extern-xml-schema <file>" << endl
+ << " Generate code as if the XML Schema namespace was\n"
+ << " defined in <file> and xsd:included in the schema\n"
+ << " being compiled."
+ << endl;
+
+ e << "--skel-type-suffix <suffix>" << endl
+ << " Use <suffix> instead of the default '_pskel' to\n"
+ << " construct the names of generated parser skeletons."
+ << endl;
+
+ e << "--skel-file-suffix <suffix>" << endl
+ << " Use <suffix> instead of the default '-pskel' to\n"
+ << " construct the names of generated parser skeleton\n"
+ << " files."
+ << endl;
+
+ e << "--impl-type-suffix <suffix>" << endl
+ << " Use <suffix> instead of the default '_pimpl' to\n"
+ << " construct the names of parser implementations for\n"
+ << " the built-in XML Schema types and sample parser\n"
+ << " implementations."
+ << endl;
+
+ e << "--impl-file-suffix <suffix>" << endl
+ << " Use <suffix> instead of the default '-pimpl' to\n"
+ << " construct the names of generated sample parser\n"
+ << " implementation files."
+ << endl;
+
+ e << "--namespace-map <xns>=<cns>" << endl
+ << " Map XML Schema namespace <xns> to C++ namespace\n"
+ << " <cns>. Repeat this option to specify mapping for\n"
+ << " more than one XML Schema namespace."
+ << endl;
+
+ e << "--namespace-regex <regex>" << endl
+ << " Add <regex> to the list of regular expressions\n"
+ << " used to translate XML Schema namespace names to\n"
+ << " C++ namespace names."
+ << endl;
+
+ e << "--namespace-regex-trace" << endl
+ << " Trace the process of applying regular expressions\n"
+ << " specified with the --namespace-regex option."
+ << endl;
+
+ e << "--reserved-name <name>" << endl
+ << " Add <name> to the list of names that should not\n"
+ << " be used as identifiers. The name can optionally\n"
+ << " be followed by '=' and the replacement name that\n"
+ << " should be used instead."
+ << endl;
+
+ e << "--include-with-brackets" << endl
+ << " Use angle brackets (<>) instead of quotes (\"\") in\n"
+ << " generated #include directives."
+ << endl;
+
+ e << "--include-prefix <prefix>" << endl
+ << " Add <prefix> to generated #include directive\n"
+ << " paths."
+ << endl;
+
+ e << "--include-regex <regex>" << endl
+ << " Add <regex> to the list of regular expressions\n"
+ << " used to transform #include directive paths."
+ << endl;
+
+ e << "--include-regex-trace" << endl
+ << " Trace the process of applying regular expressions\n"
+ << " specified with the --include-regex option."
+ << endl;
+
+ e << "--guard-prefix <prefix>" << endl
+ << " Add <prefix> to generated header inclusion guards."
+ << endl;
+
+ e << "--hxx-suffix <suffix>" << endl
+ << " Use <suffix> instead of the default '.hxx' to\n"
+ << " construct the name of the header file."
+ << endl;
+
+ e << "--ixx-suffix <suffix>" << endl
+ << " Use <suffix> instead of the default '.ixx' to\n"
+ << " construct the name of the inline file."
+ << endl;
+
+ e << "--cxx-suffix <suffix>" << endl
+ << " Use <suffix> instead of the default '.cxx' to\n"
+ << " construct the name of the source file."
+ << endl;
+
+ e << "--hxx-regex <regex>" << endl
+ << " Use <regex> to construct the name of the header\n"
+ << " file."
+ << endl;
+
+ e << "--ixx-regex <regex>" << endl
+ << " Use <regex> to construct the name of the inline\n"
+ << " file."
+ << endl;
+
+ e << "--cxx-regex <regex>" << endl
+ << " Use <regex> to construct the name of the source\n"
+ << " file."
+ << endl;
+
+
+ // Prologues.
+ //
+ e << "--hxx-prologue <text>" << endl
+ << " Insert <text> at the beginning of the header file."
+ << endl;
+
+ e << "--ixx-prologue <text>" << endl
+ << " Insert <text> at the beginning of the inline file."
+ << endl;
+
+ e << "--cxx-prologue <text>" << endl
+ << " Insert <text> at the beginning of the source file."
+ << endl;
+
+ e << "--prologue <text>" << endl
+ << " Insert <text> at the beginning of each generated\n"
+ << " file for which there is no file-specific prologue."
+ << endl;
+
+
+ // Epilogues.
+ //
+ e << "--hxx-epilogue <text>" << endl
+ << " Insert <text> at the end of the header file."
+ << endl;
+
+ e << "--ixx-epilogue <text>" << endl
+ << " Insert <text> at the end of the inline file."
+ << endl;
+
+ e << "--cxx-epilogue <text>" << endl
+ << " Insert <text> at the end of the source file."
+ << endl;
+
+ e << "--epilogue <text>" << endl
+ << " Insert <text> at the end of each generated file\n"
+ << " for which there is no file-specific epilogue."
+ << endl;
+
+
+ // Prologue files.
+ //
+ e << "--hxx-prologue-file <file>" << endl
+ << " Insert the content of the <file> at the beginning\n"
+ << " of the header file."
+ << endl;
+
+ e << "--ixx-prologue-file <file>" << endl
+ << " Insert the content of the <file> at the beginning\n"
+ << " of the inline file."
+ << endl;
+
+ e << "--cxx-prologue-file <file>" << endl
+ << " Insert the content of the <file> at the beginning\n"
+ << " of the source file."
+ << endl;
+
+ e << "--prologue-file <file>" << endl
+ << " Insert the content of the <file> at the beginning\n"
+ << " of each generated file for which there is no file-\n"
+ << " specific prologue file."
+ << endl;
+
+
+ // Epilogue files.
+ //
+ e << "--hxx-epilogue-file <file>" << endl
+ << " Insert the content of the <file> at the end of\n"
+ << " the header file."
+ << endl;
+
+ e << "--ixx-epilogue-file <file>" << endl
+ << " Insert the content of the <file> at the end of\n"
+ << " the inline file."
+ << endl;
+
+ e << "--cxx-epilogue-file <file>" << endl
+ << " Insert the content of the <file> at the end of\n"
+ << " the source file."
+ << endl;
+
+ e << "--epilogue-file <file>" << endl
+ << " Insert the content of the <file> at the end of\n"
+ << " each generated file for which there is no file-\n"
+ << " specific epilogue file."
+ << endl;
+
+
+ // Misc.
+ //
+ e << "--export-symbol <symbol>" << endl
+ << " Export symbol for Win32 DLL export/import control."
+ << endl;
+
+ e << "--export-maps" << endl
+ << " Export polymorphism support maps from Win32 DLL."
+ << endl;
+
+ e << "--import-maps" << endl
+ << " Import polymorphism support maps from Win32 DLL."
+ << endl;
+
+ e << "--show-anonymous" << endl
+ << " Show elements and attributes that are of anonymous\n"
+ << " types."
+ << endl;
+
+ e << "--show-sloc" << endl
+ << " Show the number of generated physical source lines\n"
+ << " of code (SLOC)."
+ << endl;
+
+ e << "--sloc-limit <num>" << endl
+ << " Check that the number of generated physical source\n"
+ << " lines of code (SLOC) does not exceed <num>."
+ << endl;
+
+ e << "--options-file <file>" << endl
+ << " Read additional options from <file>. Each option\n"
+ << " should appear on a separate line optionally\n"
+ << " followed by space and an argument."
+ << endl;
+
+ e << "--proprietary-license" << endl
+ << " Indicate that the generated code is licensed under\n"
+ << " a proprietary license instead of the GPL."
+ << endl;
+ }
+
+ Parser::CLI::OptionsSpec Parser::Generator::
+ options_spec ()
+ {
+ CLI::OptionsSpec spec;
+
+ spec.option<CLI::char_type> ().default_value ("char");
+ spec.option<CLI::xml_parser> ().default_value ("xerces");
+
+ spec.option<CLI::skel_file_suffix> ().default_value ("-pskel");
+ spec.option<CLI::skel_type_suffix> ().default_value ("_pskel");
+ spec.option<CLI::impl_file_suffix> ().default_value ("-pimpl");
+ spec.option<CLI::impl_type_suffix> ().default_value ("_pimpl");
+
+ spec.option<CLI::hxx_suffix> ().default_value (".hxx");
+ spec.option<CLI::ixx_suffix> ().default_value (".ixx");
+ spec.option<CLI::cxx_suffix> ().default_value (".cxx");
+
+ return spec;
+ }
+
+
+ namespace
+ {
+ template <typename S>
+ Void
+ open (S& ifs, NarrowString const& path)
+ {
+ try
+ {
+ Path fs_path (path, boost::filesystem::native);
+ ifs.open (fs_path, std::ios_base::in | std::ios_base::binary);
+
+ if (!ifs.is_open ())
+ {
+ wcerr << path.c_str () << ": error: unable to open in read mode"
+ << endl;
+
+ throw Parser::Generator::Failed ();
+ }
+ }
+ catch (InvalidPath const&)
+ {
+ wcerr << "error: '" << path.c_str () << "' is not a valid "
+ << "filesystem path" << endl;
+
+ throw Parser::Generator::Failed ();
+ }
+ }
+
+ Void
+ append (WideOutputFileStream& os,
+ NarrowString const& path,
+ WideInputFileStream& default_is)
+ {
+ using std::ios_base;
+
+ if (path)
+ {
+ WideInputFileStream is;
+ open (is, path);
+ os << is.rdbuf ();
+ }
+ else if (default_is.is_open ())
+ {
+ os << default_is.rdbuf ();
+ default_is.seekg (0, ios_base::beg);
+ }
+ }
+
+ Void
+ append (WideOutputFileStream& os,
+ Cult::Containers::Vector<NarrowString> const& primary,
+ Cult::Containers::Vector<NarrowString> const& def)
+ {
+ Cult::Containers::Vector<NarrowString> const& v (
+ primary.empty () ? def : primary);
+
+ for (Containers::Vector<NarrowString>::ConstIterator
+ i (v.begin ()), e (v.end ()); i != e; ++i)
+ {
+ os << i->c_str () << endl;
+ }
+ }
+ }
+
+
+ UnsignedLong Parser::Generator::
+ generate (Parser::CLI::Options const& ops,
+ Schema& schema,
+ Path const& file_path,
+ Boolean gen_driver,
+ const WarningSet& disabled_warnings,
+ FileList& file_list,
+ AutoUnlinks& unlinks)
+ {
+ using std::ios_base;
+ namespace Indentation = BackendElements::Indentation;
+
+ typedef BackendElements::Regex::Expression<Char> Regex;
+
+ try
+ {
+ Boolean generate_xml_schema (ops.value<CLI::generate_xml_schema> ());
+
+ // We could be compiling several schemas at once in which case
+ // handling of the --generate-xml-schema option gets tricky: we
+ // will need to rely on the presence of the --extern-xml-schema
+ // to tell us which (fake) schema file corresponds to XML Schema.
+ //
+ if (generate_xml_schema)
+ {
+ if (NarrowString name = ops.value<CLI::extern_xml_schema> ())
+ {
+ if (file_path.native_file_string () != name)
+ generate_xml_schema = false;
+ }
+ }
+
+ Boolean impl (!generate_xml_schema &&
+ (ops.value<CLI::generate_noop_impl> () ||
+ ops.value<CLI::generate_print_impl> ()));
+
+ Boolean driver (gen_driver && !generate_xml_schema &&
+ ops.value<CLI::generate_test_driver> ());
+
+ // Evaluate the graph for possibility of generating something useful.
+ //
+ {
+ Validator validator;
+ if (!validator.validate (
+ ops, schema, file_path, driver, disabled_warnings))
+ throw Failed ();
+ }
+
+ // Process names.
+ //
+ {
+ NameProcessor proc;
+ proc.process (ops, schema, file_path);
+ }
+
+ Boolean validation ((ops.value<CLI::xml_parser> () == "expat" ||
+ ops.value<CLI::generate_validation> ()) &&
+ !ops.value<CLI::suppress_validation> ());
+
+ // Compute state machine info.
+ //
+ if (validation)
+ {
+ StateProcessor proc;
+ proc.process (schema, file_path);
+ }
+
+ // Read-in type maps.
+ //
+ TypeMap::Namespaces type_map;
+ {
+ using namespace TypeMap;
+ typedef Containers::Vector<NarrowString> Files;
+
+ Files const& files (ops.value<CLI::type_map> ());
+
+ for (Files::ConstIterator f (files.begin ()); f != files.end (); ++f )
+ {
+ NarrowInputFileStream ifs;
+ open (ifs, *f);
+
+ Lexer l (ifs, *f);
+ TypeMap::Parser p (l, *f);
+
+ if (!p.parse (type_map))
+ throw Failed ();
+ }
+
+ // Add the built-in mappings at the end.
+ //
+
+ // String-based types.
+ //
+ String char_type (ops.value<CLI::char_type> ());
+ String string_type;
+
+ if (char_type == L"char")
+ string_type = L"::std::string";
+ else if (char_type == L"wchar_t")
+ string_type = L"::std::wstring";
+ else
+ string_type = L"::std::basic_string< " + char_type + L" >";
+
+ String xns;
+ {
+ Context ctx (std::wcerr, schema, ops, 0, 0, 0);
+ xns = ctx.xs_ns_name ();
+ }
+
+ String buffer (L"::std::auto_ptr< " + xns + L"::buffer >");
+ TypeMap::Namespace xsd ("http://www\\.w3\\.org/2001/XMLSchema");
+
+ xsd.types_push_back ("string", string_type);
+ xsd.types_push_back ("normalizedString", string_type);
+ xsd.types_push_back ("token", string_type);
+ xsd.types_push_back ("Name", string_type);
+ xsd.types_push_back ("NMTOKEN", string_type);
+ xsd.types_push_back ("NMTOKENS", xns + L"::string_sequence");
+ xsd.types_push_back ("NCName", string_type);
+
+ xsd.types_push_back ("ID", string_type);
+ xsd.types_push_back ("IDREF", string_type);
+ xsd.types_push_back ("IDREFS", xns + L"::string_sequence");
+
+ xsd.types_push_back ("language", string_type);
+ xsd.types_push_back ("anyURI", string_type);
+ xsd.types_push_back ("QName", xns + L"::qname");
+
+ xsd.types_push_back ("base64Binary", buffer, buffer);
+ xsd.types_push_back ("hexBinary", buffer, buffer);
+
+ xsd.types_push_back ("gDay", xns + L"::gday");
+ xsd.types_push_back ("gMonth", xns + L"::gmonth");
+ xsd.types_push_back ("gYear", xns + L"::gyear");
+ xsd.types_push_back ("gMonthDay", xns + L"::gmonth_day");
+ xsd.types_push_back ("gYearMonth", xns + L"::gyear_month");
+ xsd.types_push_back ("date", xns + L"::date");
+ xsd.types_push_back ("time", xns + L"::time");
+ xsd.types_push_back ("dateTime", xns + L"::date_time");
+ xsd.types_push_back ("duration", xns + L"::duration");
+
+ // Fundamental C++ types.
+ //
+ xsd.types_push_back ("boolean", "bool", "bool");
+
+ xsd.types_push_back ("byte", "signed char", "signed char");
+ xsd.types_push_back ("unsignedByte",
+ "unsigned char",
+ "unsigned char");
+
+ xsd.types_push_back ("short", "short", "short");
+ xsd.types_push_back ("unsignedShort",
+ "unsigned short",
+ "unsigned short");
+
+ xsd.types_push_back ("int", "int", "int");
+ xsd.types_push_back ("unsignedInt", "unsigned int", "unsigned int");
+
+ xsd.types_push_back ("long", "long long", "long long");
+ xsd.types_push_back ("unsignedLong",
+ "unsigned long long",
+ "unsigned long long");
+
+ xsd.types_push_back ("integer", "long long", "long long");
+
+ xsd.types_push_back ("negativeInteger", "long long", "long long");
+ xsd.types_push_back ("nonPositiveInteger", "long long", "long long");
+
+ xsd.types_push_back ("positiveInteger",
+ "unsigned long long",
+ "unsigned long long");
+ xsd.types_push_back ("nonNegativeInteger",
+ "unsigned long long",
+ "unsigned long long");
+
+ xsd.types_push_back ("float", "float", "float");
+ xsd.types_push_back ("double", "double", "double");
+ xsd.types_push_back ("decimal", "double", "double");
+
+ type_map.push_back (xsd);
+
+ // Everyhting else maps to void.
+ //
+ TypeMap::Namespace rest (".*");
+ rest.types_push_back (".*", "void", "void");
+ type_map.push_back (rest);
+ }
+
+ // Process types.
+ //
+ {
+ TypeProcessor proc;
+ proc.process (ops, schema, gen_driver, type_map);
+ }
+
+ //
+ //
+ Boolean inline_ (ops.value<CLI::generate_inline> () &&
+ !generate_xml_schema);
+
+ Boolean source (!generate_xml_schema);
+
+ // Generate code.
+ //
+ NarrowString name (file_path.leaf ());
+ NarrowString skel_suffix (ops.value <CLI::skel_file_suffix> ());
+ NarrowString impl_suffix (ops.value <CLI::impl_file_suffix> ());
+
+ NarrowString hxx_suffix (ops.value <CLI::hxx_suffix> ());
+ NarrowString ixx_suffix (ops.value <CLI::ixx_suffix> ());
+ NarrowString cxx_suffix (ops.value <CLI::cxx_suffix> ());
+
+ Regex hxx_expr (
+ ops.value <CLI::hxx_regex> ().empty ()
+ ? "#^(.+?)(\\.[^./\\\\]+)?$#$1" + skel_suffix + hxx_suffix + "#"
+ : ops.value <CLI::hxx_regex> ());
+
+ Regex ixx_expr (
+ ops.value <CLI::ixx_regex> ().empty ()
+ ? "#^(.+?)(\\.[^./\\\\]+)?$#$1" + skel_suffix + ixx_suffix + "#"
+ : ops.value <CLI::ixx_regex> ());
+
+ Regex cxx_expr (
+ ops.value <CLI::cxx_regex> ().empty ()
+ ? "#^(.+?)(\\.[^./\\\\]+)?$#$1" + skel_suffix + cxx_suffix + "#"
+ : ops.value <CLI::cxx_regex> ());
+
+
+ Regex hxx_impl_expr;
+ Regex cxx_impl_expr;
+ Regex cxx_driver_expr;
+
+ if (impl || driver)
+ {
+ hxx_impl_expr =
+ "#^(.+?)(\\.[^./\\\\]+)?$#$1" + impl_suffix + hxx_suffix + "#";
+
+ cxx_impl_expr =
+ "#^(.+?)(\\.[^./\\\\]+)?$#$1" + impl_suffix + cxx_suffix + "#";
+
+ cxx_driver_expr =
+ "#^(.+?)(\\.[^./\\\\]+)?$#$1-driver" + cxx_suffix + "#";
+ }
+
+ if (!hxx_expr.match (name))
+ {
+ wcerr << "error: header expression '" <<
+ hxx_expr.pattern () << "' does not match '" <<
+ name.c_str () << "'" << endl;
+ throw Failed ();
+ }
+
+ if (inline_ && !ixx_expr.match (name))
+ {
+ wcerr << "error: inline expression '" <<
+ ixx_expr.pattern () << "' does not match '" <<
+ name.c_str () << "'" << endl;
+ throw Failed ();
+ }
+
+ if (source && !cxx_expr.match (name))
+ {
+ wcerr << "error: source expression '" <<
+ cxx_expr.pattern () << "' does not match '" <<
+ name.c_str () << "'" << endl;
+ throw Failed ();
+ }
+
+ if (impl || driver)
+ {
+ if (!hxx_impl_expr.match (name))
+ {
+ wcerr << "error: implementation header expression '" <<
+ hxx_impl_expr.pattern () << "' does not match '" <<
+ name.c_str () << "'" << endl;
+ throw Failed ();
+ }
+
+ if (!cxx_impl_expr.match (name))
+ {
+ wcerr << "error: implementation source expression '" <<
+ cxx_impl_expr.pattern () << "' does not match '" <<
+ name.c_str () << "'" << endl;
+ throw Failed ();
+ }
+
+ if (!cxx_driver_expr.match (name))
+ {
+ wcerr << "error: driver source expression '" <<
+ cxx_driver_expr.pattern () << "' does not match '" <<
+ name.c_str () << "'" << endl;
+ throw Failed ();
+ }
+ }
+
+ NarrowString hxx_name (hxx_expr.merge (name));
+ NarrowString ixx_name (inline_ ? ixx_expr.merge (name) : NarrowString ());
+ NarrowString cxx_name (source ? cxx_expr.merge (name) : NarrowString ());
+
+ NarrowString hxx_impl_name;
+ NarrowString cxx_impl_name;
+ NarrowString cxx_driver_name;
+
+ if (impl || driver)
+ {
+ hxx_impl_name = hxx_impl_expr.merge (name);
+ cxx_impl_name = cxx_impl_expr.merge (name);
+ cxx_driver_name = cxx_driver_expr.merge (name);
+ }
+
+ Path hxx_path (hxx_name, boost::filesystem::native);
+ Path ixx_path (ixx_name, boost::filesystem::native);
+ Path cxx_path (cxx_name, boost::filesystem::native);
+
+ Path hxx_impl_path;
+ Path cxx_impl_path;
+ Path cxx_driver_path;
+
+ if (impl || driver)
+ {
+ hxx_impl_path = Path (hxx_impl_name, boost::filesystem::native);
+ cxx_impl_path = Path (cxx_impl_name, boost::filesystem::native);
+ cxx_driver_path = Path (cxx_driver_name, boost::filesystem::native);
+ }
+
+ if (NarrowString dir = ops.value<CLI::output_dir> ())
+ {
+ try
+ {
+ Path path (dir, boost::filesystem::native);
+
+ hxx_path = path / hxx_path;
+ ixx_path = path / ixx_path;
+ cxx_path = path / cxx_path;
+
+ if (impl || driver)
+ {
+ hxx_impl_path = path / hxx_impl_path;
+ cxx_impl_path = path / cxx_impl_path;
+ cxx_driver_path = path /cxx_driver_path;
+ }
+ }
+ catch (InvalidPath const&)
+ {
+ wcerr << dir.c_str () << ": error: invalid path" << endl;
+ throw Failed ();
+ }
+ }
+
+ // Open the impl files first so that if open fails, the skel files
+ // are not deleted.
+ //
+ WideOutputFileStream hxx_impl;
+ WideOutputFileStream cxx_impl;
+ WideOutputFileStream cxx_driver;
+
+ if (impl)
+ {
+ if (!ops.value<CLI::force_overwrite> ())
+ {
+ WideInputFileStream tmp (hxx_impl_path, ios_base::in);
+
+ if (tmp.is_open ())
+ {
+ wcerr << hxx_impl_path << ": error: cowardly refusing to " <<
+ "overwrite an existing file" << endl;
+ throw Failed ();
+ }
+
+ tmp.close ();
+ }
+
+ hxx_impl.open (hxx_impl_path, ios_base::out);
+
+ if (!hxx_impl.is_open ())
+ {
+ wcerr << hxx_impl_path << ": error: unable to open in write mode"
+ << endl;
+ throw Failed ();
+ }
+
+ unlinks.add (hxx_impl_path);
+ file_list.push_back (hxx_impl_path.native_file_string ());
+
+ if (!ops.value<CLI::force_overwrite> ())
+ {
+ WideInputFileStream tmp (cxx_impl_path, ios_base::in);
+
+ if (tmp.is_open ())
+ {
+ wcerr << cxx_impl_path << ": error: cowardly refusing to " <<
+ "overwrite an existing file" << endl;
+ throw Failed ();
+ }
+
+ tmp.close ();
+ }
+
+ cxx_impl.open (cxx_impl_path, ios_base::out);
+
+ if (!cxx_impl.is_open ())
+ {
+ wcerr << cxx_impl_path << ": error: unable to open in write mode"
+ << endl;
+ throw Failed ();
+ }
+
+ unlinks.add (cxx_impl_path);
+ file_list.push_back (cxx_impl_path.native_file_string ());
+ }
+
+ if (driver)
+ {
+ if (!ops.value<CLI::force_overwrite> ())
+ {
+ WideInputFileStream tmp (cxx_driver_path, ios_base::in);
+
+ if (tmp.is_open ())
+ {
+ wcerr << cxx_driver_path << ": error: cowardly refusing to " <<
+ "overwrite an existing file" << endl;
+ throw Failed ();
+ }
+
+ tmp.close ();
+ }
+
+ cxx_driver.open (cxx_driver_path, ios_base::out);
+
+ if (!cxx_driver.is_open ())
+ {
+ wcerr << cxx_driver_path << ": error: unable to open in write " <<
+ "mode" << endl;
+ throw Failed ();
+ }
+
+ unlinks.add (cxx_driver_path);
+ file_list.push_back (cxx_driver_path.native_file_string ());
+ }
+
+ // Open the skel files.
+ //
+ WideOutputFileStream hxx (hxx_path, ios_base::out);
+ WideOutputFileStream ixx;
+ WideOutputFileStream cxx;
+
+ if (!hxx.is_open ())
+ {
+ wcerr << hxx_path << ": error: unable to open in write mode" << endl;
+ throw Failed ();
+ }
+
+ unlinks.add (hxx_path);
+ file_list.push_back (hxx_path.native_file_string ());
+
+ if (inline_)
+ {
+ ixx.open (ixx_path, ios_base::out);
+
+ if (!ixx.is_open ())
+ {
+ wcerr << ixx_path << ": error: unable to open in write mode" << endl;
+ throw Failed ();
+ }
+
+ unlinks.add (ixx_path);
+ file_list.push_back (ixx_path.native_file_string ());
+ }
+
+
+ if (source)
+ {
+ cxx.open (cxx_path, ios_base::out);
+
+ if (!cxx.is_open ())
+ {
+ wcerr << cxx_path << ": error: unable to open in write mode" << endl;
+ throw Failed ();
+ }
+
+ unlinks.add (cxx_path);
+ file_list.push_back (cxx_path.native_file_string ());
+ }
+
+ // Print copyright and license.
+ //
+ Char const* copyright (
+ ops.value<CLI::proprietary_license> ()
+ ? copyright_proprietary
+ : copyright_gpl);
+
+ hxx << copyright;
+
+ if (inline_)
+ ixx << copyright;
+
+ if (source)
+ cxx << copyright;
+
+ if (impl)
+ {
+ hxx_impl << copyright_impl;
+ cxx_impl << copyright_impl;
+ }
+
+ if (driver)
+ cxx_driver << copyright_impl;
+
+ // Prologue.
+ //
+ WideInputFileStream prologue;
+ {
+ NarrowString name (ops.value<CLI::prologue_file> ());
+
+ if (name)
+ open (prologue, name);
+ }
+
+ // Epilogue.
+ //
+ WideInputFileStream epilogue;
+ {
+ NarrowString name (ops.value<CLI::epilogue_file> ());
+
+ if (name)
+ open (epilogue, name);
+ }
+
+ // SLOC counter.
+ //
+ UnsignedLong sloc (0);
+ Boolean show_sloc (ops.value<CLI::show_sloc> ());
+
+ //
+ //
+ Regex guard_expr ("/([a-z])([A-Z])/$1_$2/"); // Split words.
+
+ NarrowString guard_prefix (ops.value<CLI::guard_prefix> ());
+
+ if (!guard_prefix)
+ guard_prefix = file_path.branch_path ().native_directory_string ();
+
+ if (guard_prefix)
+ guard_prefix += '_';
+
+ // HXX
+ //
+ {
+ Context ctx (hxx, schema, ops, &hxx_expr, &ixx_expr, &hxx_impl_expr);
+
+ Indentation::Clip<Indentation::SLOC, WideChar> hxx_sloc (hxx);
+
+ String guard (guard_expr.merge (guard_prefix + hxx_name));
+ guard = ctx.escape (guard); // Make it a C++ id.
+ std::transform (guard.begin (), guard.end(), guard.begin (), upcase);
+
+ hxx << "#ifndef " << guard << endl
+ << "#define " << guard << endl
+ << endl;
+
+ // Copy prologue.
+ //
+ hxx << "// Begin prologue." << endl
+ << "//" << endl;
+
+ append (
+ hxx, ops.value<CLI::hxx_prologue> (), ops.value<CLI::prologue> ());
+ append (hxx, ops.value<CLI::hxx_prologue_file> (), prologue);
+
+ hxx << "//" << endl
+ << "// End prologue." << endl
+ << endl;
+
+ // Version check.
+ //
+ hxx << "#include <xsd/cxx/config.hxx>" << endl
+ << endl
+ << "#if (XSD_INT_VERSION != " << XSD_INT_VERSION << "L)" << endl
+ << "#error XSD runtime version mismatch" << endl
+ << "#endif" << endl
+ << endl;
+
+ {
+ hxx << "#include <xsd/cxx/pre.hxx>" << endl
+ << endl;
+
+ // Set auto-indentation.
+ //
+ Indentation::Clip<Indentation::CXX, WideChar> hxx_clip (hxx);
+
+
+ // Generate.
+ //
+ if (!generate_xml_schema)
+ generate_parser_forward (ctx);
+
+ generate_parser_header (ctx, generate_xml_schema);
+
+
+ if (inline_)
+ hxx << "#include " << ctx.process_include_path (ixx_name) << endl;
+
+ hxx << "#include <xsd/cxx/post.hxx>" << endl
+ << endl;
+ }
+
+ // Copy epilogue.
+ //
+ hxx << "// Begin epilogue." << endl
+ << "//" << endl;
+
+ append (hxx, ops.value<CLI::hxx_epilogue_file> (), epilogue);
+ append (
+ hxx, ops.value<CLI::hxx_epilogue> (), ops.value<CLI::epilogue> ());
+
+ hxx << "//" << endl
+ << "// End epilogue." << endl
+ << endl;
+
+ hxx << "#endif // " << guard << endl;
+
+ if (show_sloc)
+ {
+ wcerr << hxx_path << ": "
+ << hxx_sloc.buffer ().count () << endl;
+
+ sloc += hxx_sloc.buffer ().count ();
+ }
+ }
+
+
+ // IXX
+ //
+ if (inline_)
+ {
+ Context ctx (ixx, schema, ops, &hxx_expr, &ixx_expr, &hxx_impl_expr);
+
+ Indentation::Clip<Indentation::SLOC, WideChar> ixx_sloc (ixx);
+
+
+ // Copy prologue.
+ //
+ ixx << "// Begin prologue." << endl
+ << "//" << endl;
+
+ append (
+ ixx, ops.value<CLI::ixx_prologue> (), ops.value<CLI::prologue> ());
+ append (ixx, ops.value<CLI::ixx_prologue_file> (), prologue);
+
+ ixx << "//" << endl
+ << "// End prologue." << endl
+ << endl;
+
+ {
+ // Set auto-indentation.
+ //
+ Indentation::Clip<Indentation::CXX, WideChar> ixx_clip (ixx);
+
+
+ // Generate.
+ //
+ generate_parser_inline (ctx);
+ }
+
+ // Copy epilogue.
+ //
+ ixx << "// Begin epilogue." << endl
+ << "//" << endl;
+
+ append (ixx, ops.value<CLI::ixx_epilogue_file> (), epilogue);
+ append (
+ ixx, ops.value<CLI::ixx_epilogue> (), ops.value<CLI::epilogue> ());
+
+ ixx << "//" << endl
+ << "// End epilogue." << endl
+ << endl;
+
+ if (show_sloc)
+ {
+ wcerr << ixx_path << ": "
+ << ixx_sloc.buffer ().count () << endl;
+
+ sloc += ixx_sloc.buffer ().count ();
+ }
+ }
+
+
+ // CXX
+ //
+ if (source)
+ {
+ Context ctx (cxx, schema, ops, &hxx_expr, &ixx_expr, &hxx_impl_expr);
+
+ Indentation::Clip<Indentation::SLOC, WideChar> cxx_sloc (cxx);
+
+ // Copy prologue.
+ //
+ cxx << "// Begin prologue." << endl
+ << "//" << endl;
+
+ append (
+ cxx, ops.value<CLI::cxx_prologue> (), ops.value<CLI::prologue> ());
+ append (cxx, ops.value<CLI::cxx_prologue_file> (), prologue);
+
+ cxx << "//" << endl
+ << "// End prologue." << endl
+ << endl;
+
+ {
+ // Set auto-indentation.
+ //
+ Indentation::Clip<Indentation::CXX, WideChar> cxx_clip (cxx);
+
+ cxx << "#include " << ctx.process_include_path (hxx_name) << endl
+ << endl;
+
+ if (!inline_)
+ generate_parser_inline (ctx);
+
+ generate_parser_source (ctx);
+
+ if (validation)
+ {
+ generate_element_validation_source (ctx);
+ generate_attribute_validation_source (ctx);
+ generate_characters_validation_source (ctx);
+ }
+ }
+
+ // Copy epilogue.
+ //
+ cxx << "// Begin epilogue." << endl
+ << "//" << endl;
+
+ append (cxx, ops.value<CLI::cxx_epilogue_file> (), epilogue);
+ append (
+ cxx, ops.value<CLI::cxx_epilogue> (), ops.value<CLI::epilogue> ());
+
+ cxx << "//" << endl
+ << "// End epilogue." << endl
+ << endl;
+
+ if (show_sloc)
+ {
+ wcerr << cxx_path << ": "
+ << cxx_sloc.buffer ().count () << endl;
+
+ sloc += cxx_sloc.buffer ().count ();
+ }
+ }
+
+ // HXX impl
+ //
+ if (impl)
+ {
+ Context ctx (hxx_impl, schema, ops,
+ &hxx_expr, &ixx_expr, &hxx_impl_expr);
+
+ String guard (guard_expr.merge (guard_prefix + hxx_impl_name));
+ guard = ctx.escape (guard); // Make it a C++ id.
+ std::transform (guard.begin (), guard.end(), guard.begin (), upcase);
+
+ hxx_impl << "#ifndef " << guard << endl
+ << "#define " << guard << endl
+ << endl;
+
+ {
+ // Set auto-indentation.
+ //
+ Indentation::Clip<Indentation::CXX, WideChar> clip (hxx_impl);
+
+ hxx_impl << "#include " << ctx.process_include_path (hxx_name)
+ << endl << endl;
+
+ generate_impl_header (ctx);
+ }
+
+ hxx_impl << "#endif // " << guard << endl;
+ }
+
+ // CXX impl
+ //
+ if (impl)
+ {
+ Context ctx (cxx_impl, schema, ops,
+ &hxx_expr, &ixx_expr, &hxx_impl_expr);
+
+ // Set auto-indentation.
+ //
+ Indentation::Clip<Indentation::CXX, WideChar> clip (cxx_impl);
+
+ cxx_impl << "#include " << ctx.process_include_path (hxx_impl_name)
+ << endl << endl;
+
+ generate_impl_source (ctx);
+ }
+
+ // CXX driver
+ //
+ if (driver)
+ {
+ Context ctx (cxx_driver, schema, ops,
+ &hxx_expr, &ixx_expr, &hxx_impl_expr);
+
+ // Set auto-indentation.
+ //
+ Indentation::Clip<Indentation::CXX, WideChar> clip (cxx_driver);
+
+ cxx_driver << "#include " << ctx.process_include_path (hxx_impl_name)
+ << endl << endl;
+
+ generate_driver_source (ctx);
+ }
+
+ return sloc;
+ }
+ catch (NoNamespaceMapping const& e)
+ {
+ wcerr << e.file () << ":" << e.line () << ":" << e.column ()
+ << ": error: unable to map XML Schema namespace '" << e.ns ()
+ << "' to C++ namespace" << endl;
+
+ wcerr << e.file () << ":" << e.line () << ":" << e.column ()
+ << ": info: use the --namespace-map or --namespace-regex option "
+ << "to provide custom mapping" << endl;
+
+ throw Failed ();
+ }
+ catch (InvalidNamespaceMapping const& e)
+ {
+ wcerr << "error: invalid XML to C++ namespace mapping specified: "
+ << "'" << e.mapping () << "': " << e.reason () << endl;
+
+ throw Failed ();
+ }
+ catch (BackendElements::Regex::Format<Char> const& e)
+ {
+ wcerr << "error: invalid regex: '" <<
+ e.expression ().c_str () << "': " <<
+ e.description ().c_str () << endl;
+
+ throw Failed ();
+ }
+ catch (BackendElements::Regex::Format<WideChar> const& e)
+ {
+ wcerr << "error: invalid regex: '" <<
+ e.expression () << "': " << e.description () << endl;
+
+ throw Failed ();
+ }
+ }
+}
diff --git a/xsd/cxx/parser/generator.hxx b/xsd/cxx/parser/generator.hxx
new file mode 100644
index 0000000..aaab3b8
--- /dev/null
+++ b/xsd/cxx/parser/generator.hxx
@@ -0,0 +1,55 @@
+// file : xsd/cxx/parser/generator.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_GENERATOR_HXX
+#define CXX_PARSER_GENERATOR_HXX
+
+#include <cult/types.hxx>
+
+#include <cult/containers/vector.hxx>
+
+#include <cult/cli/options.hxx>
+#include <cult/cli/options-spec.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx> // Path
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <xsd.hxx>
+
+#include <cxx/parser/cli.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ using namespace Cult::Types;
+
+ class Generator
+ {
+ public:
+ static Void
+ usage ();
+
+ static CLI::OptionsSpec
+ options_spec ();
+
+ struct Failed {};
+
+ static UnsignedLong
+ generate (CLI::Options const& options,
+ XSDFrontend::SemanticGraph::Schema&,
+ XSDFrontend::SemanticGraph::Path const& file,
+ Boolean gen_driver,
+ const WarningSet& disabled_warnings,
+ FileList& file_list,
+ AutoUnlinks& unlinks);
+
+ private:
+ Generator ();
+ };
+ }
+}
+
+#endif // CXX_PARSER_GENERATOR_HXX
diff --git a/xsd/cxx/parser/impl-header.cxx b/xsd/cxx/parser/impl-header.cxx
new file mode 100644
index 0000000..8a52254
--- /dev/null
+++ b/xsd/cxx/parser/impl-header.cxx
@@ -0,0 +1,237 @@
+// file : xsd/cxx/parser/impl-header.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/parser/impl-header.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace
+ {
+ struct Enumeration: Traversal::Enumeration,
+ protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String const& name (eimpl (e));
+ String const& ret (ret_type (e));
+ SemanticGraph::Type& base (e.inherits ().base ());
+
+ os << "class " << type_exp << name << ": " <<
+ "public virtual " << ename (e) << "," << endl
+ << " public " << fq_name (base, "impl")
+ << "{"
+ << "public:" << endl
+ << "virtual void" << endl
+ << "pre ();"
+ << endl
+ << "virtual " << ret << endl
+ << post_name (e) << " ();"
+ << "};";
+ }
+ };
+
+ //
+ //
+ struct List: Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String const& name (eimpl (l));
+ SemanticGraph::Type& t (l.argumented ().type ());
+
+ String item (unclash (ename (l), "item"));
+
+ os << "class " << type_exp << name << ": public virtual " <<
+ ename (l)
+ << "{"
+ << "public:" << endl
+ << "virtual void" << endl
+ << "pre ();"
+ << endl;
+
+ // item
+ //
+ String const& arg (arg_type (t));
+
+ os << "virtual void" << endl
+ << item;
+
+ if (arg == L"void")
+ os << " ();";
+ else
+ os << " (" << arg << ");";
+
+ os << endl;
+
+ // post
+ //
+ String const& ret (ret_type (l));
+
+ os << "virtual " << ret << endl
+ << post_name (l) << " ();"
+ << "};";
+ }
+ };
+
+ struct Union: Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String const& name (eimpl (u));
+ String const& ret (ret_type (u));
+
+ os << "class " << type_exp << name << ": public virtual " <<
+ ename (u)
+ << "{"
+ << "public:" << endl
+ << "virtual void" << endl
+ << "pre ();"
+ << endl
+ << "virtual void" << endl
+ << "_characters (const " << string_type << "&);"
+ << endl
+ << "virtual " << ret << endl
+ << post_name (u) << " ();"
+ << "};";
+ }
+ };
+
+
+ //
+ //
+ struct ParserCallback: Traversal::Member,
+ protected virtual Context
+ {
+ ParserCallback (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m))
+ return;
+
+ String const& arg (arg_type (m.type ()));
+
+ os << "virtual void" << endl
+ << ename (m);
+
+ if (arg == L"void")
+ os << " ();";
+ else
+ os << " (" << arg << ");";
+
+ os << endl;
+ }
+ };
+
+ //
+ //
+ struct Complex : Traversal::Complex,
+ protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c),
+ parser_callback_ (c)
+ {
+ names_parser_callback_ >> parser_callback_;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String const& name (eimpl (c));
+ String const& ret (ret_type (c));
+
+ os << "class " << type_exp << name << ": public virtual " <<
+ ename (c);
+
+ if (c.inherits_p ())
+ os << "," << endl
+ << " public " << fq_name (c.inherits ().base (), "impl");
+
+ os << "{"
+ << "public:" << endl
+ << "virtual void" << endl
+ << "pre ();"
+ << endl;
+
+ // In case of an inheritance-by-restriction, we don't need to
+ // generate parser callbacks, etc. since they are the same as in
+ // the base.
+ //
+ if (!restriction_p (c))
+ {
+ names (c, names_parser_callback_);
+ }
+
+ os << "virtual " << ret << endl
+ << post_name (c) << " ();"
+ << "};";
+ }
+
+ private:
+ //
+ //
+ ParserCallback parser_callback_;
+ Traversal::Names names_parser_callback_;
+ };
+ }
+
+ Void
+ generate_impl_header (Context& ctx)
+ {
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Includes includes (ctx, Includes::impl_header);
+ Traversal::Names schema_names;
+
+ Namespace ns (ctx);
+ Traversal::Names names;
+
+ schema >> includes;
+ schema >> sources >> schema;
+ schema >> schema_names >> ns >> names;
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/parser/impl-header.hxx b/xsd/cxx/parser/impl-header.hxx
new file mode 100644
index 0000000..d69c65a
--- /dev/null
+++ b/xsd/cxx/parser/impl-header.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/parser/impl-header.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_IMPL_HEADER_HXX
+#define CXX_PARSER_IMPL_HEADER_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/parser/elements.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ Void
+ generate_impl_header (Context&);
+ }
+}
+
+#endif // CXX_PARSER_IMPL_HEADER_HXX
diff --git a/xsd/cxx/parser/impl-source.cxx b/xsd/cxx/parser/impl-source.cxx
new file mode 100644
index 0000000..00b9456
--- /dev/null
+++ b/xsd/cxx/parser/impl-source.cxx
@@ -0,0 +1,389 @@
+// file : xsd/cxx/parser/impl-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/parser/impl-source.hxx>
+#include <cxx/parser/print-impl-common.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace
+ {
+ struct Enumeration: Traversal::Enumeration,
+ protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String const& name (eimpl (e));
+ String const& ret (ret_type (e));
+ SemanticGraph::Type& base (e.inherits ().base ());
+ String const& base_ret (ret_type (base));
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ // pre
+ //
+ os << "void " << name << "::" << endl
+ << "pre ()"
+ << "{"
+ << "}";
+
+ // post
+ //
+ os << ret << " " << name << "::" << endl
+ << post_name (e) << " ()"
+ << "{";
+
+ if (ret == base_ret)
+ {
+ os << (ret != L"void" ? "return " : "") <<
+ post_name (base) << " ();";
+ }
+ else if (ret == L"void")
+ {
+ os << arg_type (base) << " v (" << post_name (base) << " ());"
+ << endl;
+
+ if (options.value<CLI::generate_print_impl> ())
+ {
+ PrintCall t (*this, e.name (), "v");
+ t.dispatch (base);
+ }
+ else
+ os << "// TODO" << endl
+ << "//" << endl;
+ }
+ else
+ {
+ if (base_ret == L"void")
+ os << post_name (base) << " ();";
+ else
+ os << arg_type (base) << " v (" << post_name (base) << " ());"
+ << endl
+ << "// TODO" << endl
+ << "//" << endl
+ << "// return ... ;" << endl;
+ }
+
+ os << "}";
+ }
+ };
+
+ //
+ //
+ struct List: Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String const& name (eimpl (l));
+ SemanticGraph::Type& type (l.argumented ().type ());
+
+ String item (unclash (ename (l), "item"));
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ // pre
+ //
+ os << "void " << name << "::" << endl
+ << "pre ()"
+ << "{"
+ << "}";
+
+ // item
+ //
+ String const& arg (arg_type (type));
+
+ os << "void " << name << "::" << endl
+ << item;
+
+ if (arg == L"void")
+ os << " ()";
+ else
+ os << " (" << arg << " " << item << ")";
+
+ os << "{";
+
+ if (arg != L"void")
+ {
+ if (options.value<CLI::generate_print_impl> ())
+ {
+ PrintCall t (*this, type.name (), item);
+ t.dispatch (type);
+ }
+ else
+ os << "// TODO" << endl
+ << "//" << endl;
+ }
+
+ os << "}";
+
+ // post
+ //
+ String const& ret (ret_type (l));
+
+ os << ret << " " << name << "::" << endl
+ << post_name (l) << " ()"
+ << "{";
+
+ if (ret != L"void")
+ os << "// TODO" << endl
+ << "//" << endl
+ << "// return ... ;" << endl;
+
+ os << "}";
+ }
+ };
+
+ //
+ //
+ struct Union: Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String const& name (eimpl (u));
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ // pre
+ //
+ os << "void " << name << "::" << endl
+ << "pre ()"
+ << "{"
+ << "}";
+
+ // _characters
+ //
+ os << "void " << name << "::" << endl
+ << "_characters (const " << string_type << "& s)"
+ << "{";
+
+ if (options.value<CLI::generate_print_impl> ())
+ os << cout_inst << " << " << L << strlit (u.name () + L": ") <<
+ " << s << std::endl;";
+ else
+ os << "// TODO" << endl
+ << "//" << endl;
+
+ os << "}";
+
+ // post
+ //
+ String const& ret (ret_type (u));
+
+ os << ret << " " << name << "::" << endl
+ << post_name (u) << " ()"
+ << "{";
+
+ if (ret != L"void")
+ os << "// TODO" << endl
+ << "//" << endl
+ << "// return ... ;" << endl;
+
+ os << "}";
+ }
+ };
+
+ //
+ //
+ struct ParserCallback: Traversal::Member,
+ protected virtual Context
+ {
+ ParserCallback (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m))
+ return;
+
+ String const& name (ename (m));
+ String const& arg (arg_type (m.type ()));
+
+ os << "void " <<
+ eimpl (dynamic_cast<SemanticGraph::Complex&> (m.scope ())) <<
+ "::" << endl
+ << name;
+
+ if (arg == L"void")
+ os << " ()";
+ else
+ os << " (" << arg << " " << name << ")";
+
+ os << "{";
+
+ if (arg != L"void")
+ {
+ if (options.value<CLI::generate_print_impl> ())
+ {
+ PrintCall t (*this, m.name (), name);
+ t.dispatch (m.type ());
+ }
+ else
+ os << "// TODO" << endl
+ << "//" << endl;
+ }
+
+ os << "}";
+ }
+ };
+
+ //
+ //
+ struct Complex : Traversal::Complex,
+ protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c), parser_callback_ (c)
+ {
+ names_parser_callback_ >> parser_callback_;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String const& name (eimpl (c));
+
+ Boolean restriction (restriction_p (c));
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ // pre
+ //
+ os << "void " << name << "::" << endl
+ << "pre ()"
+ << "{"
+ << "}";
+
+ // Parser callbacks.
+ //
+ if (!restriction)
+ names (c, names_parser_callback_);
+
+ // post
+ //
+ String const& ret (ret_type (c));
+
+ os << ret << " " << name << "::" << endl
+ << post_name (c) << " ()"
+ << "{";
+
+ if (c.inherits_p ())
+ {
+ SemanticGraph::Type& base (c.inherits ().base ());
+ String const& base_ret (ret_type (base));
+
+ if (ret == base_ret)
+ {
+ os << (ret != L"void" ? "return " : "") <<
+ post_name (base) << " ();";
+ }
+ else if (ret == L"void")
+ {
+ os << arg_type (base) << " v (" << post_name (base) << " ());"
+ << endl;
+
+ if (options.value<CLI::generate_print_impl> ())
+ {
+ PrintCall t (*this, c.name (), "v");
+ t.dispatch (base);
+ }
+ else
+ os << "// TODO" << endl
+ << "//" << endl;
+ }
+ else
+ {
+ if (base_ret == L"void")
+ os << post_name (base) << " ();";
+ else
+ os << arg_type (base) << " v (" << post_name (base) << " ());"
+ << endl
+ << "// TODO" << endl
+ << "//" << endl
+ << "// return ... ;" << endl;
+ }
+ }
+ else
+ {
+ if (ret != L"void")
+ os << "// TODO" << endl
+ << "//" << endl
+ << "// return ... ;" << endl;
+ }
+
+ os << "}";
+ }
+
+ private:
+ //
+ //
+ ParserCallback parser_callback_;
+ Traversal::Names names_parser_callback_;
+ };
+ }
+
+ Void
+ generate_impl_source (Context& ctx)
+ {
+ if (ctx.options.value<CLI::generate_print_impl> ())
+ ctx.os << "#include <iostream>" << endl
+ << endl;
+
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+ Traversal::Names schema_names;
+ Namespace ns (ctx);
+ Traversal::Names names;
+
+ schema >> sources >> schema;
+ schema >> schema_names >> ns >> names;
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/parser/impl-source.hxx b/xsd/cxx/parser/impl-source.hxx
new file mode 100644
index 0000000..68a5f5e
--- /dev/null
+++ b/xsd/cxx/parser/impl-source.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/parser/impl-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_IMPL_SOURCE_HXX
+#define CXX_PARSER_IMPL_SOURCE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/parser/elements.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ Void
+ generate_impl_source (Context&);
+ }
+}
+
+#endif // CXX_PARSER_IMPL_SOURCE_HXX
diff --git a/xsd/cxx/parser/name-processor.cxx b/xsd/cxx/parser/name-processor.cxx
new file mode 100644
index 0000000..b40522b
--- /dev/null
+++ b/xsd/cxx/parser/name-processor.cxx
@@ -0,0 +1,1205 @@
+// file : xsd/cxx/parser/name-processor.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/elements.hxx>
+#include <cxx/parser/name-processor.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cult/containers/set.hxx>
+
+#include <sstream>
+#include <iostream>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ NameProcessor::
+ NameProcessor ()
+ {
+ // Dummy ctor, helps with long symbols on HP-UX.
+ }
+
+ namespace
+ {
+ //
+ //
+ typedef Cult::Containers::Set<String> NameSet;
+
+ class Context: public CXX::Context
+ {
+ public:
+ Context (CLI::Options const& ops,
+ SemanticGraph::Schema& root,
+ SemanticGraph::Path const& file)
+ : CXX::Context (std::wcerr,
+ root,
+ ops.value<CLI::char_type> (),
+ ops.value<CLI::include_with_brackets> (),
+ ops.value<CLI::include_prefix> (),
+ ops.value<CLI::export_symbol> (),
+ ops.value<CLI::namespace_map> (),
+ ops.value<CLI::namespace_regex> (),
+ ops.value<CLI::namespace_regex_trace> (),
+ ops.value<CLI::include_regex> (),
+ ops.value<CLI::include_regex_trace> (),
+ ops.value<CLI::generate_inline> (),
+ ops.value<CLI::reserved_name> ()),
+ schema_path_ (file),
+ skel_suffix_ (ops.value<CLI::skel_type_suffix> ()),
+ impl_suffix_ (ops.value<CLI::impl_type_suffix> ()),
+ schema (root),
+ schema_path (schema_path_),
+ impl (ops.value<CLI::generate_noop_impl> () ||
+ ops.value<CLI::generate_print_impl> () ||
+ ops.value<CLI::generate_test_driver> ()),
+ skel_suffix (skel_suffix_),
+ impl_suffix (impl_suffix_),
+ global_type_names (global_type_names_),
+ polymorphic (ops.value<CLI::generate_polymorphic> ())
+ {
+ }
+
+ protected:
+ Context (Context& c)
+ : CXX::Context (c),
+ schema (c.schema),
+ schema_path (c.schema_path),
+ impl (c.impl),
+ skel_suffix (c.skel_suffix),
+ impl_suffix (c.impl_suffix),
+ global_type_names (c.global_type_names),
+ polymorphic (c.polymorphic)
+ {
+ }
+
+ public:
+ String
+ find_name (String const& n, NameSet& set)
+ {
+ String base_name (escape (n));
+ String name (base_name);
+
+ for (UnsignedLong i (1); set.find (name) != set.end (); ++i)
+ {
+ std::wostringstream os;
+ os << i;
+ name = base_name + os.str ();
+ }
+
+ set.insert (name);
+ return name;
+ }
+
+ private:
+ SemanticGraph::Path const schema_path_;
+ String const skel_suffix_;
+ String const impl_suffix_;
+
+ Cult::Containers::Map<String, NameSet> global_type_names_;
+
+ public:
+ SemanticGraph::Schema& schema;
+ SemanticGraph::Path const& schema_path;
+ Boolean const impl;
+ String const& skel_suffix;
+ String const& impl_suffix;
+
+ Cult::Containers::Map<String, NameSet>& global_type_names;
+
+ Boolean polymorphic;
+ };
+
+
+ //
+ //
+ struct PrimaryMember: Traversal::Member, Context
+ {
+ PrimaryMember (Context& c, NameSet& set)
+ : Context (c), set_ (set)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (Parser::Context::skip (m))
+ return;
+
+ m.context ().set ("name", find_name (m.name (), set_));
+ }
+
+ private:
+ NameSet& set_;
+ };
+
+ struct DerivedMember: Traversal::Member, Context
+ {
+ DerivedMember (Context& c, NameSet& set)
+ : Context (c), set_ (set)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (Parser::Context::skip (m))
+ return;
+
+ m.context ().set ("parser",
+ find_name (m.name () + L"_parser", set_));
+
+ String const& base (m.context ().get<String> ("name"));
+ m.context ().set ("member", find_name (base + L"_parser_", set_));
+
+ if (polymorphic &&
+ m.is_a<SemanticGraph::Element> () &&
+ !m.type ().context ().count ("anonymous"))
+ {
+ m.context ().set (
+ "member-cache", find_name (base + L"_parser_cache_", set_));
+
+ m.context ().set (
+ "member-map", find_name (base + L"_parser_map_", set_));
+
+ m.context ().set (
+ "member-map-impl",
+ find_name (base + L"_parser_map_impl_", set_));
+ }
+ }
+
+ private:
+ NameSet& set_;
+ };
+
+
+ //
+ //
+ struct MemberInRestrictionBase: Traversal::Member
+ {
+ protected:
+ MemberInRestrictionBase (NameSet& set, SemanticGraph::Complex& base)
+ : set_ (set), base_ (base)
+ {
+ }
+
+ struct NotFound {};
+
+ Type&
+ find_member (SemanticGraph::Complex& c, Type& m)
+ {
+ using SemanticGraph::Complex;
+
+ Complex::NamesIteratorPair r (c.find (m.name ()));
+
+ for (; r.first != r.second; ++r.first)
+ {
+ if (r.first->named ().is_a<Type> ())
+ {
+ Type& bm (dynamic_cast<Type&> (r.first->named ()));
+
+ if (typeid (bm) != typeid (m))
+ continue;
+
+ if (m.qualified ())
+ {
+ if (bm.qualified () &&
+ m.name () == bm.name () &&
+ m.namespace_ ().name () == bm.namespace_ ().name ())
+ return bm;
+ }
+ else
+ {
+ if (!bm.qualified () && m.name () == bm.name ())
+ return bm;
+ }
+ }
+ }
+
+ // If we didn't find anything, try our base.
+ //
+ if (c.inherits_p ())
+ {
+ SemanticGraph::Type& base (c.inherits ().base ());
+
+ if (base.is_a<Complex> ())
+ return find_member (dynamic_cast<Complex&> (base), m);
+ }
+
+ //std::wcerr << "unable to find member " << m.name () << " in "
+ // << c.name () << std::endl;
+
+ throw NotFound ();
+ }
+
+ protected:
+ NameSet& set_;
+ SemanticGraph::Complex& base_;
+ };
+
+ struct PrimaryMemberInRestriction: MemberInRestrictionBase, Context
+ {
+ PrimaryMemberInRestriction (Context& c,
+ NameSet& set,
+ SemanticGraph::Complex& base)
+ : MemberInRestrictionBase (set, base), Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (Parser::Context::skip (m))
+ return;
+
+ String name;
+
+ try
+ {
+ // Try to find corresponding member in one of our bases.
+ // This may fail if we use an element that substitutes
+ // one in our base.
+ //
+ Type& bm (find_member (base_, m));
+ name = bm.context ().get<String> ("name");
+ }
+ catch (NotFound const&)
+ {
+ // Fall back to the standard name assignment.
+ //
+ name = find_name (m.name (), set_);
+ }
+
+ m.context ().set ("name", name);
+ }
+ };
+
+ struct DerivedMemberInRestriction: MemberInRestrictionBase, Context
+ {
+ DerivedMemberInRestriction (Context& c,
+ NameSet& set,
+ SemanticGraph::Complex& base)
+ : MemberInRestrictionBase (set, base), Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (Parser::Context::skip (m))
+ return;
+
+ Boolean poly (polymorphic &&
+ m.is_a<SemanticGraph::Element> () &&
+ !m.type ().context ().count ("anonymous"));
+
+ String parser, member, member_cache, member_map, member_map_impl;
+
+ try
+ {
+ // Try to find corresponding member in one of our bases.
+ // This may fail if we use an element that substitutes
+ // one in our base.
+ //
+ Type& bm (find_member (base_, m));
+ parser = bm.context ().get<String> ("parser");
+ member = bm.context ().get<String> ("member");
+
+ if (poly)
+ {
+ member_cache = bm.context ().get<String> ("member-cache");
+ member_map = bm.context ().get<String> ("member-map");
+ member_map_impl = bm.context ().get<String> ("member-map-impl");
+ }
+ }
+ catch (NotFound const&)
+ {
+ // Fall back to the standard name assignment.
+ //
+ String const& base (m.context ().get<String> ("name"));
+
+ parser = find_name (m.name () + L"_parser", set_);
+ member = find_name (base + L"_parser_", set_);
+
+ if (poly)
+ {
+ member_cache = find_name (base + L"_parser_cache_", set_);
+ member_map = find_name (base + L"_parser_map_", set_);
+ member_map_impl = find_name (base + L"_parser_map_impl_", set_);
+ }
+ }
+
+ m.context ().set ("parser", parser);
+ m.context ().set ("member", member);
+
+ if (poly)
+ {
+ m.context ().set ("member-cache", member_cache);
+ m.context ().set ("member-map", member_map);
+ m.context ().set ("member-map-impl", member_map_impl);
+ }
+ }
+ };
+
+ //
+ //
+ struct Complex: Traversal::Complex, Context
+ {
+ Complex (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ SemanticGraph::Context& cc (c.context ());
+
+ // Use processed name.
+ //
+ String const& name (cc.get<String> ("name"));
+
+ // We leave this set around to allow other mappings to use
+ // this information.
+ //
+ cc.set ("cxx-parser-name-processor-member-set", NameSet ());
+ NameSet& member_set (
+ cc.get<NameSet> ("cxx-parser-name-processor-member-set"));
+
+ member_set.insert (name);
+
+ // Add our base's members to the initial list unless we are
+ // inheriting by restriction in which case we need to have
+ // the same names as our base.
+ //
+ Boolean restriction (false);
+
+ if (c.inherits_p ())
+ {
+ // @@ What if this types name is the same as one of base's
+ // members?
+ //
+ SemanticGraph::Type& base (c.inherits ().base ());
+
+ if (base.is_a<SemanticGraph::Complex> ())
+ {
+ if (!base.context ().count (
+ "cxx-parser-name-processor-member-set"))
+ {
+ dispatch (base);
+ }
+
+ NameSet const& base_set (
+ base.context ().get<NameSet> (
+ "cxx-parser-name-processor-member-set"));
+
+ member_set.insert (base_set.begin (), base_set.end ());
+
+ // Inheritance by restriction from anyType is a special case.
+ //
+ restriction = c.inherits ().is_a<SemanticGraph::Restricts> () &&
+ !c.inherits ().base ().is_a<SemanticGraph::AnyType> ();
+ }
+ }
+
+ if (restriction)
+ {
+ // First assign the "primary" names.
+ //
+ {
+ PrimaryMemberInRestriction member (
+ *this,
+ member_set,
+ dynamic_cast<SemanticGraph::Complex&> (
+ c.inherits ().base ()));
+
+ Traversal::Names names (member);
+
+ Complex::names (c, names);
+ }
+
+ // Assign "derived" names.
+ //
+ {
+ DerivedMemberInRestriction member (
+ *this,
+ member_set,
+ dynamic_cast<SemanticGraph::Complex&> (
+ c.inherits ().base ()));
+
+ Traversal::Names names (member);
+
+ Complex::names (c, names);
+ }
+ }
+ else
+ {
+ // First assign the "primary" names.
+ //
+ {
+ PrimaryMember member (*this, member_set);
+ Traversal::Names names (member);
+
+ Complex::names (c, names);
+ }
+
+ // Assign "derived" names.
+ //
+ {
+ DerivedMember member (*this, member_set);
+ Traversal::Names names (member);
+
+ Complex::names (c, names);
+ }
+ }
+ }
+ };
+
+
+ //
+ //
+ struct GlobalType: Traversal::Type, Context
+ {
+ GlobalType (Context& c, NameSet& set)
+ : Context (c), set_ (set)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type& t)
+ {
+ SemanticGraph::Context& c (t.context ());
+ String const& n (t.name ());
+
+ String name (find_name (n + skel_suffix, set_));
+ c.set ("name", name);
+
+ // Assign the post_* name.
+ //
+ c.set ("post", find_post_name (t));
+
+ // Note that we do not add this name to the set so that it
+ // does not influence other names.
+ //
+ if (impl)
+ c.set ("impl", escape (n + impl_suffix));
+ }
+
+ private:
+ String
+ find_post_name (SemanticGraph::Type& t)
+ {
+ String const& n (t.name ());
+
+ // It is possible that our base has the same type name (just
+ // in a different namespaces). Avoid name clash in this case.
+ //
+ using SemanticGraph::Complex;
+
+ Complex* c = dynamic_cast<Complex*> (&t);
+
+ if (c == 0 || !c->inherits_p ())
+ {
+ return escape (L"post_" + n);
+ }
+ else
+ {
+ NameSet set;
+
+ // Collect all base's post_*. In some mutual inclusion cases it
+ // is possible that our base won't have the post name assigned
+ // yet. In this situation will will have to figure it out
+ // ourselves (we can do it since we use the "raw" type name).
+ //
+ SemanticGraph::Type* b (&c->inherits ().base ());
+
+ while (true)
+ {
+ if (b->context ().count ("post"))
+ set.insert (b->context ().get<String> ("post"));
+ else
+ set.insert (find_post_name (*b));
+
+ Complex* cb (dynamic_cast<Complex*> (b));
+
+ if (cb != 0 && cb->inherits_p ())
+ {
+ b = &cb->inherits ().base ();
+ continue;
+ }
+
+ break;
+ }
+
+ String base_name (escape (L"post_" + n));
+ String post (base_name);
+
+ for (UnsignedLong i (1); set.find (post) != set.end (); ++i)
+ {
+ std::wostringstream os;
+ os << i;
+ post = base_name + os.str ();
+ }
+
+ return post;
+ }
+ }
+
+ private:
+ NameSet& set_;
+ };
+
+
+ struct Namespace: Traversal::Namespace, Context
+ {
+ Namespace (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& ns)
+ {
+ NameSet& type_set (global_type_names[ns.name ()]);
+
+ GlobalType type (*this, type_set);
+ Traversal::Names names (type);
+
+ Traversal::Namespace::names (ns, names);
+ }
+ };
+
+
+ struct FundType : Traversal::AnyType,
+ Traversal::AnySimpleType,
+
+ Traversal::Fundamental::Byte,
+ Traversal::Fundamental::UnsignedByte,
+ Traversal::Fundamental::Short,
+ Traversal::Fundamental::UnsignedShort,
+ Traversal::Fundamental::Int,
+ Traversal::Fundamental::UnsignedInt,
+ Traversal::Fundamental::Long,
+ Traversal::Fundamental::UnsignedLong,
+ Traversal::Fundamental::Integer,
+ Traversal::Fundamental::NonPositiveInteger,
+ Traversal::Fundamental::NonNegativeInteger,
+ Traversal::Fundamental::PositiveInteger,
+ Traversal::Fundamental::NegativeInteger,
+
+ Traversal::Fundamental::Boolean,
+
+ Traversal::Fundamental::Float,
+ Traversal::Fundamental::Double,
+ Traversal::Fundamental::Decimal,
+
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NameTokens,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Language,
+
+ Traversal::Fundamental::QName,
+
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef,
+ Traversal::Fundamental::IdRefs,
+
+ Traversal::Fundamental::AnyURI,
+
+ Traversal::Fundamental::Base64Binary,
+ Traversal::Fundamental::HexBinary,
+
+ Traversal::Fundamental::Date,
+ Traversal::Fundamental::DateTime,
+ Traversal::Fundamental::Duration,
+ Traversal::Fundamental::Day,
+ Traversal::Fundamental::Month,
+ Traversal::Fundamental::MonthDay,
+ Traversal::Fundamental::Year,
+ Traversal::Fundamental::YearMonth,
+ Traversal::Fundamental::Time,
+
+ Traversal::Fundamental::Entity,
+ Traversal::Fundamental::Entities,
+
+ Context
+
+ {
+ FundType (Context& c)
+ : Context (c)
+ {
+ }
+
+ // anyType & anySimpleType.
+ //
+ virtual Void
+ traverse (SemanticGraph::AnyType& t)
+ {
+ t.context ().set ("name", make_skel_name ("any_type"));
+ t.context ().set ("impl", make_impl_name ("any_type"));
+ t.context ().set ("post", String ("post_any_type"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnySimpleType& t)
+ {
+ t.context ().set ("name", make_skel_name ("any_simple_type"));
+ t.context ().set ("impl", make_impl_name ("any_simple_type"));
+ t.context ().set ("post", String ("post_any_simple_type"));
+ }
+
+ // Boolean.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Boolean& t)
+ {
+ t.context ().set ("name", make_skel_name ("boolean"));
+ t.context ().set ("impl", make_impl_name ("boolean"));
+ t.context ().set ("post", String ("post_boolean"));
+ }
+
+ // Integral types.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Byte& t)
+ {
+ t.context ().set ("name", make_skel_name ("byte"));
+ t.context ().set ("impl", make_impl_name ("byte"));
+ t.context ().set ("post", String ("post_byte"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedByte& t)
+ {
+ t.context ().set ("name", make_skel_name ("unsigned_byte"));
+ t.context ().set ("impl", make_impl_name ("unsigned_byte"));
+ t.context ().set ("post", String ("post_unsigned_byte"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Short& t)
+ {
+ t.context ().set ("name", make_skel_name ("short"));
+ t.context ().set ("impl", make_impl_name ("short"));
+ t.context ().set ("post", String ("post_short"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedShort& t)
+ {
+ t.context ().set ("name", make_skel_name ("unsigned_short"));
+ t.context ().set ("impl", make_impl_name ("unsigned_short"));
+ t.context ().set ("post", String ("post_unsigned_short"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Int& t)
+ {
+ t.context ().set ("name", make_skel_name ("int"));
+ t.context ().set ("impl", make_impl_name ("int"));
+ t.context ().set ("post", String ("post_int"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedInt& t)
+ {
+ t.context ().set ("name", make_skel_name ("unsigned_int"));
+ t.context ().set ("impl", make_impl_name ("unsigned_int"));
+ t.context ().set ("post", String ("post_unsigned_int"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Long& t)
+ {
+ t.context ().set ("name", make_skel_name ("long"));
+ t.context ().set ("impl", make_impl_name ("long"));
+ t.context ().set ("post", String ("post_long"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedLong& t)
+ {
+ t.context ().set ("name", make_skel_name ("unsigned_long"));
+ t.context ().set ("impl", make_impl_name ("unsigned_long"));
+ t.context ().set ("post", String ("post_unsigned_long"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Integer& t)
+ {
+ t.context ().set ("name", make_skel_name ("integer"));
+ t.context ().set ("impl", make_impl_name ("integer"));
+ t.context ().set ("post", String ("post_integer"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger& t)
+ {
+ t.context ().set ("name", make_skel_name ("non_positive_integer"));
+ t.context ().set ("impl", make_impl_name ("non_positive_integer"));
+ t.context ().set ("post", String ("post_non_positive_integer"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger& t)
+ {
+ t.context ().set ("name", make_skel_name ("non_negative_integer"));
+ t.context ().set ("impl", make_impl_name ("non_negative_integer"));
+ t.context ().set ("post", String ("post_non_negative_integer"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::PositiveInteger& t)
+ {
+ t.context ().set ("name", make_skel_name ("positive_integer"));
+ t.context ().set ("impl", make_impl_name ("positive_integer"));
+ t.context ().set ("post", String ("post_positive_integer"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NegativeInteger& t)
+ {
+ t.context ().set ("name", make_skel_name ("negative_integer"));
+ t.context ().set ("impl", make_impl_name ("negative_integer"));
+ t.context ().set ("post", String ("post_negative_integer"));
+ }
+
+ // Floats.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Float& t)
+ {
+ t.context ().set ("name", make_skel_name ("float"));
+ t.context ().set ("impl", make_impl_name ("float"));
+ t.context ().set ("post", String ("post_float"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Double& t)
+ {
+ t.context ().set ("name", make_skel_name ("double"));
+ t.context ().set ("impl", make_impl_name ("double"));
+ t.context ().set ("post", String ("post_double"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Decimal& t)
+ {
+ t.context ().set ("name", make_skel_name ("decimal"));
+ t.context ().set ("impl", make_impl_name ("decimal"));
+ t.context ().set ("post", String ("post_decimal"));
+ }
+
+ // Strings.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String& t)
+ {
+ t.context ().set ("name", make_skel_name ("string"));
+ t.context ().set ("impl", make_impl_name ("string"));
+ t.context ().set ("post", String ("post_string"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString& t)
+ {
+ t.context ().set ("name", make_skel_name ("normalized_string"));
+ t.context ().set ("impl", make_impl_name ("normalized_string"));
+ t.context ().set ("post", String ("post_normalized_string"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token& t)
+ {
+ t.context ().set ("name", make_skel_name ("token"));
+ t.context ().set ("impl", make_impl_name ("token"));
+ t.context ().set ("post", String ("post_token"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken& t)
+ {
+ t.context ().set ("name", make_skel_name ("nmtoken"));
+ t.context ().set ("impl", make_impl_name ("nmtoken"));
+ t.context ().set ("post", String ("post_nmtoken"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameTokens& t)
+ {
+ t.context ().set ("name", make_skel_name ("nmtokens"));
+ t.context ().set ("impl", make_impl_name ("nmtokens"));
+ t.context ().set ("post", String ("post_nmtokens"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name& t)
+ {
+ t.context ().set ("name", make_skel_name ("name"));
+ t.context ().set ("impl", make_impl_name ("name"));
+ t.context ().set ("post", String ("post_name"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName& t)
+ {
+ t.context ().set ("name", make_skel_name ("ncname"));
+ t.context ().set ("impl", make_impl_name ("ncname"));
+ t.context ().set ("post", String ("post_ncname"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Language& t)
+ {
+ t.context ().set ("name", make_skel_name ("language"));
+ t.context ().set ("impl", make_impl_name ("language"));
+ t.context ().set ("post", String ("post_language"));
+ }
+
+
+ // Qualified name.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::QName& t)
+ {
+ t.context ().set ("name", make_skel_name ("qname"));
+ t.context ().set ("impl", make_impl_name ("qname"));
+ t.context ().set ("post", String ("post_qname"));
+ }
+
+
+ // ID/IDREF.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id& t)
+ {
+ t.context ().set ("name", make_skel_name ("id"));
+ t.context ().set ("impl", make_impl_name ("id"));
+ t.context ().set ("post", String ("post_id"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef& t)
+ {
+ t.context ().set ("name", make_skel_name ("idref"));
+ t.context ().set ("impl", make_impl_name ("idref"));
+ t.context ().set ("post", String ("post_idref"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRefs& t)
+ {
+ t.context ().set ("name", make_skel_name ("idrefs"));
+ t.context ().set ("impl", make_impl_name ("idrefs"));
+ t.context ().set ("post", String ("post_idrefs"));
+ }
+
+ // URI.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::AnyURI& t)
+ {
+ t.context ().set ("name", make_skel_name ("uri"));
+ t.context ().set ("impl", make_impl_name ("uri"));
+ t.context ().set ("post", String ("post_uri"));
+ }
+
+ // Binary.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Base64Binary& t)
+ {
+ t.context ().set ("name", make_skel_name ("base64_binary"));
+ t.context ().set ("impl", make_impl_name ("base64_binary"));
+ t.context ().set ("post", String ("post_base64_binary"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::HexBinary& t)
+ {
+ t.context ().set ("name", make_skel_name ("hex_binary"));
+ t.context ().set ("impl", make_impl_name ("hex_binary"));
+ t.context ().set ("post", String ("post_hex_binary"));
+ }
+
+
+ // Date/time.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Date& t)
+ {
+ t.context ().set ("name", make_skel_name ("date"));
+ t.context ().set ("impl", make_impl_name ("date"));
+ t.context ().set ("post", String ("post_date"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::DateTime& t)
+ {
+ t.context ().set ("name", make_skel_name ("date_time"));
+ t.context ().set ("impl", make_impl_name ("date_time"));
+ t.context ().set ("post", String ("post_date_time"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Duration& t)
+ {
+ t.context ().set ("name", make_skel_name ("duration"));
+ t.context ().set ("impl", make_impl_name ("duration"));
+ t.context ().set ("post", String ("post_duration"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Day& t)
+ {
+ t.context ().set ("name", make_skel_name ("gday"));
+ t.context ().set ("impl", make_impl_name ("gday"));
+ t.context ().set ("post", String ("post_gday"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Month& t)
+ {
+ t.context ().set ("name", make_skel_name ("gmonth"));
+ t.context ().set ("impl", make_impl_name ("gmonth"));
+ t.context ().set ("post", String ("post_gmonth"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::MonthDay& t)
+ {
+ t.context ().set ("name", make_skel_name ("gmonth_day"));
+ t.context ().set ("impl", make_impl_name ("gmonth_day"));
+ t.context ().set ("post", String ("post_gmonth_day"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Year& t)
+ {
+ t.context ().set ("name", make_skel_name ("gyear"));
+ t.context ().set ("impl", make_impl_name ("gyear"));
+ t.context ().set ("post", String ("post_gyear"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::YearMonth& t)
+ {
+ t.context ().set ("name", make_skel_name ("gyear_month"));
+ t.context ().set ("impl", make_impl_name ("gyear_month"));
+ t.context ().set ("post", String ("post_gyear_month"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Time& t)
+ {
+ t.context ().set ("name", make_skel_name ("time"));
+ t.context ().set ("impl", make_impl_name ("time"));
+ t.context ().set ("post", String ("post_time"));
+ }
+
+ // Entity.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entity& t)
+ {
+ t.context ().set ("name", make_skel_name ("entity"));
+ t.context ().set ("impl", make_impl_name ("entity"));
+ t.context ().set ("post", String ("post_entity"));
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entities& t)
+ {
+ t.context ().set ("name", make_skel_name ("entities"));
+ t.context ().set ("impl", make_impl_name ("entities"));
+ t.context ().set ("post", String ("post_entities"));
+ }
+
+ private:
+ String
+ make_skel_name (String const& base)
+ {
+ return escape (base + skel_suffix);
+ }
+
+ String
+ make_impl_name (String const& base)
+ {
+ return escape (base + impl_suffix);
+ }
+ };
+
+ // Go into sourced/included/imported schemas while making sure
+ // we don't process the same stuff more than once.
+ //
+ struct Uses: Traversal::Sources,
+ Traversal::Includes,
+ Traversal::Imports
+ {
+ virtual Void
+ traverse (SemanticGraph::Sources& sr)
+ {
+ SemanticGraph::Schema& s (sr.schema ());
+
+ if (!s.context ().count ("cxx-parser-name-processor-seen"))
+ {
+ s.context ().set ("cxx-parser-name-processor-seen", true);
+ Traversal::Sources::traverse (sr);
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Includes& i)
+ {
+ SemanticGraph::Schema& s (i.schema ());
+
+ if (!s.context ().count ("cxx-parser-name-processor-seen"))
+ {
+ s.context ().set ("cxx-parser-name-processor-seen", true);
+ Traversal::Includes::traverse (i);
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Imports& i)
+ {
+ SemanticGraph::Schema& s (i.schema ());
+
+ if (!s.context ().count ("cxx-parser-name-processor-seen"))
+ {
+ s.context ().set ("cxx-parser-name-processor-seen", true);
+ Traversal::Imports::traverse (i);
+ }
+ }
+ };
+
+ // Go into implied schemas while making sure we don't process
+ // the same stuff more than once.
+ //
+ struct Implies: Traversal::Implies
+ {
+ virtual Void
+ traverse (SemanticGraph::Implies& i)
+ {
+ SemanticGraph::Schema& s (i.schema ());
+
+ if (!s.context ().count ("cxx-parser-name-processor-seen"))
+ {
+ s.context ().set ("cxx-parser-name-processor-seen", true);
+ Traversal::Implies::traverse (i);
+ }
+ }
+ };
+
+ Void
+ process_impl (CLI::Options const& ops,
+ SemanticGraph::Schema& tu,
+ SemanticGraph::Path const& file)
+ {
+ Context ctx (ops, tu, file);
+
+ if (tu.names_begin ()->named ().name () ==
+ L"http://www.w3.org/2001/XMLSchema")
+ {
+ // XML Schema namespace.
+ //
+ Traversal::Schema schema;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ FundType fund_type (ctx);
+
+ schema >> schema_names >> ns >> ns_names >> fund_type;
+
+ schema.dispatch (tu);
+ }
+ else
+ {
+
+ // Pass one - assign names to fundamental types.
+ //
+ {
+ Traversal::Schema schema;
+ Implies implies;
+ Traversal::Schema xs_schema;
+
+ schema >> implies >> xs_schema;
+
+ Traversal::Names xs_schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ FundType fund_type (ctx);
+
+ xs_schema >> xs_schema_names >> ns >> ns_names >> fund_type;
+
+ schema.dispatch (tu);
+ }
+
+ // Pass two - assign names to global types. This pass cannot
+ // be combined with pass three because of possible recursive
+ // schema inclusions. Also note that we check first if this
+ // schema has already been processed which may happen in the
+ // file-per-type compilation mode.
+ //
+ if (!tu.context ().count ("cxx-parser-name-processor-seen"))
+ {
+ Traversal::Schema schema;
+ Uses uses;
+
+ schema >> uses >> schema;
+
+ Traversal::Names schema_names;
+ Namespace ns (ctx);
+
+ schema >> schema_names >> ns;
+
+ // Some twisted schemas do recusive self-inclusion.
+ //
+ tu.context ().set ("cxx-parser-name-processor-seen", true);
+
+ schema.dispatch (tu);
+ }
+
+ // Pass three - assign names inside complex types. Here we don't
+ // need to go into included/imported schemas.
+ //
+ {
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+
+ schema >> sources >> schema;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+
+ schema >> schema_names >> ns >> ns_names;
+
+ Complex complex (ctx);
+
+ ns_names >> complex;
+
+ schema.dispatch (tu);
+ }
+ }
+ }
+ }
+
+ Void NameProcessor::
+ process (CLI::Options const& ops,
+ SemanticGraph::Schema& tu,
+ SemanticGraph::Path const& file)
+ {
+ process_impl (ops, tu, file);
+ }
+ }
+}
diff --git a/xsd/cxx/parser/name-processor.hxx b/xsd/cxx/parser/name-processor.hxx
new file mode 100644
index 0000000..f7849c8
--- /dev/null
+++ b/xsd/cxx/parser/name-processor.hxx
@@ -0,0 +1,34 @@
+// file : xsd/cxx/parser/name-processor.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_NAME_PROCESSOR_HXX
+#define CXX_PARSER_NAME_PROCESSOR_HXX
+
+#include <cult/types.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+
+#include <cxx/parser/cli.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ using namespace Cult::Types;
+
+ class NameProcessor
+ {
+ public:
+ NameProcessor (); // Dummy ctor, helps with long symbols on HP-UX.
+
+ Void
+ process (CLI::Options const& ops,
+ XSDFrontend::SemanticGraph::Schema&,
+ XSDFrontend::SemanticGraph::Path const& file);
+ };
+ }
+}
+
+#endif // CXX_PARSER_NAME_PROCESSOR_HXX
diff --git a/xsd/cxx/parser/parser-forward.cxx b/xsd/cxx/parser/parser-forward.cxx
new file mode 100644
index 0000000..4d97e23
--- /dev/null
+++ b/xsd/cxx/parser/parser-forward.cxx
@@ -0,0 +1,115 @@
+// file : xsd/cxx/parser/parser-forward.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/parser/parser-forward.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace
+ {
+ struct Enumeration: Traversal::Enumeration,
+ protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ os << "class " << ename (e) << ";";
+ }
+ };
+
+ //
+ //
+ struct List: Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ os << "class " << ename (l) << ";";
+ }
+ };
+
+ //
+ //
+ struct Union: Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ os << "class " << ename (u) << ";";
+ }
+ };
+
+ //
+ //
+ struct Complex : Traversal::Complex,
+ protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ os << "class " << ename (c) << ";";
+ }
+ };
+ }
+
+ Void
+ generate_parser_forward (Context& ctx)
+ {
+ ctx.os << "// Forward declarations" << endl
+ << "//" << endl;
+
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names schema_names;
+
+ Namespace ns (ctx);
+ Traversal::Names names;
+
+ schema >> sources >> schema;
+ schema >> schema_names >> ns >> names;
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ schema.dispatch (ctx.schema_root);
+
+ ctx.os << endl;
+ }
+ }
+}
+
diff --git a/xsd/cxx/parser/parser-forward.hxx b/xsd/cxx/parser/parser-forward.hxx
new file mode 100644
index 0000000..a4c23f2
--- /dev/null
+++ b/xsd/cxx/parser/parser-forward.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/parser/parser-forward.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_PARSER_FORWARD_HXX
+#define CXX_PARSER_PARSER_FORWARD_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/parser/elements.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ Void
+ generate_parser_forward (Context&);
+ }
+}
+
+#endif // CXX_PARSER_PARSER_FORWARD_HXX
diff --git a/xsd/cxx/parser/parser-header.cxx b/xsd/cxx/parser/parser-header.cxx
new file mode 100644
index 0000000..f8ca090
--- /dev/null
+++ b/xsd/cxx/parser/parser-header.cxx
@@ -0,0 +1,1440 @@
+// file : xsd/cxx/parser/parser-header.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/parser/parser-header.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace
+ {
+ struct Enumeration: Traversal::Enumeration,
+ protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String const& name (ename (e));
+ SemanticGraph::Type& base (e.inherits ().base ());
+
+ os << "class " << type_exp << name << ": public virtual " <<
+ fq_name (base)
+ << "{"
+ << "public:" << endl
+ << "// Parser callbacks. Override them in your " <<
+ "implementation." << endl
+ << "//" << endl;
+
+ os << "// virtual void" << endl
+ << "// pre ();" << endl
+ << endl;
+
+ String const& ret (ret_type (e));
+
+ Boolean same (ret == ret_type (base));
+
+ os << "virtual " << ret << endl
+ << post_name (e) << " ()" <<
+ (same || ret == L"void" ? ";" : " = 0;");
+
+ if (polymorphic)
+ {
+ os << endl
+ << "public:" << endl
+ << "static const " << char_type << "*" << endl
+ << "_static_type ();"
+ << endl
+ << "virtual const " << char_type << "*" << endl
+ << "_dynamic_type () const;";
+ }
+
+ os << "};";
+ }
+ };
+
+ //
+ //
+ struct List: Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String const& name (ename (l));
+ SemanticGraph::Type& t (l.argumented ().type ());
+
+ String item (unclash (name, "item"));
+
+ os << "class " << type_exp << name << ": public " << list_base
+ << "{"
+ << "public:" << endl
+ << "// Parser callbacks. Override them in your " <<
+ "implementation." << endl
+ << "//" << endl;
+
+ // pre
+ //
+ os << "// virtual void" << endl
+ << "// pre ();" << endl
+ << endl;
+
+ // item
+ //
+ String const& arg (arg_type (t));
+
+ os << "virtual void" << endl
+ << item;
+
+ if (arg == L"void")
+ os << " ();";
+ else
+ os << " (" << arg << ");";
+
+ os << endl;
+
+ // post
+ //
+ String const& ret (ret_type (l));
+
+ os << "virtual " << ret << endl
+ << post_name (l) << " ()" << (ret == L"void" ? ";" : " = 0;")
+ << endl;
+
+ //
+ //
+ os << "// Parser construction API." << endl
+ << "//" << endl;
+
+ // item_parser
+ //
+ os << "void" << endl
+ << unclash (name, "item_parser") << " (" << fq_name (t) << "&);"
+ << endl;
+
+ // parsers
+ //
+ os << "void" << endl
+ << "parsers (" << fq_name (t) << "& /* item */);"
+ << endl;
+
+ // c-tor
+ //
+ os << "// Constructor." << endl
+ << "//" << endl
+ << name << " ();"
+ << endl;
+
+
+ if (polymorphic)
+ {
+ os << "public:" << endl
+ << "static const " << char_type << "*" << endl
+ << "_static_type ();"
+ << endl
+ << "virtual const " << char_type << "*" << endl
+ << "_dynamic_type () const;"
+ << endl;
+ }
+
+ //
+ //
+ os << "// Implementation." << endl
+ << "//" << endl
+ << "protected:" << endl;
+
+ os << "virtual void" << endl
+ << "_xsd_parse_item (const " << string_type << "&);"
+ << endl;
+
+ os << "protected:" << endl
+ << fq_name (t) << "* _xsd_" << item << "_;"
+ << "};";
+ }
+ };
+
+ struct Union: Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String const& name (ename (u));
+
+ os << "class " << type_exp << name << ": public " << simple_base
+ << "{"
+ << "public:" << endl
+ << "// Parser callbacks. Override them in your " <<
+ "implementation." << endl
+ << "//" << endl;
+
+ os << "// virtual void" << endl
+ << "// pre ();" << endl
+ << "//" << endl
+ << "// virtual void" << endl
+ << "// _characters (const " << string_type << "&);" << endl
+ << endl;
+
+ String const& ret (ret_type (u));
+
+ os << "virtual " << ret << endl
+ << post_name (u) << " ()" << (ret == L"void" ? ";" : " = 0;");
+
+ if (polymorphic)
+ {
+ os << endl
+ << "public:" << endl
+ << "static const " << char_type << "*" << endl
+ << "_static_type ();"
+ << endl
+ << "virtual const " << char_type << "*" << endl
+ << "_dynamic_type () const;";
+ }
+
+ os << "};";
+ }
+ };
+
+
+ //
+ //
+ struct ParserCallback: Traversal::Member,
+ protected virtual Context
+ {
+ ParserCallback (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m)) return;
+
+ String const& arg (arg_type (m.type ()));
+
+ os << "virtual void" << endl
+ << ename (m);
+
+ if (arg == L"void")
+ os << " ();";
+ else
+ os << " (" << arg << ");";
+
+ os << endl;
+ }
+ };
+
+
+ //
+ //
+ struct ParserModifier: Traversal::Member,
+ protected virtual Context
+ {
+ ParserModifier (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m))
+ return;
+
+ os << "void" << endl
+ << eparser (m) << " (" << fq_name (m.type ()) << "&);"
+ << endl;
+
+ if (polymorphic &&
+ m.is_a<SemanticGraph::Element> () &&
+ !anonymous (m.type ()))
+ {
+ os << "void" << endl
+ << eparser (m) << " (const " << parser_map << "&);"
+ << endl;
+ }
+ }
+ };
+
+ //
+ //
+ struct ParserMember: Traversal::Member,
+ protected virtual Context
+ {
+ ParserMember (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m))
+ return;
+
+ String type (fq_name (m.type ()));
+
+ os << type << "* " << emember (m) << ";";
+
+ if (polymorphic &&
+ m.is_a<SemanticGraph::Element> () &&
+ !anonymous (m.type ()))
+ {
+ os << type << "* " << emember_cache (m) << ";"
+ << "const " << parser_map << "* " << emember_map (m) << ";"
+ << endl;
+ }
+ }
+ };
+
+ //
+ //
+ struct Particle: Traversal::All,
+ Traversal::Choice,
+ Traversal::Sequence,
+ protected virtual Context
+ {
+ Particle (Context& c)
+ : Context (c)
+ {
+ *this >> contains_particle_ >> *this;
+ }
+
+
+ virtual Void
+ traverse (SemanticGraph::All& a)
+ {
+ if (!a.context().count ("comp-number"))
+ return;
+
+ UnsignedLong state_count (
+ a.context().get<UnsignedLong> ("state-count"));
+
+ os << "void" << endl
+ << "all_0 (unsigned long& state," << endl
+ << "unsigned char* count," << endl
+ << "const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "* t," << endl
+ << "bool start);"
+ << endl
+ << "unsigned char v_all_first_[" << state_count << "UL];"
+ << "::xsd::cxx::parser::validating::all_stack v_all_count_;"
+ << endl;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Choice& c)
+ {
+ if (!c.context().count ("comp-number"))
+ return;
+
+ UnsignedLong n (c.context ().get<UnsignedLong> ("comp-number"));
+
+ os << "void" << endl
+ << "choice_" << n << " (unsigned long& state," << endl
+ << "unsigned long& count," << endl
+ << "const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "* t," << endl
+ << "bool start);"
+ << endl;
+
+ Traversal::Choice::traverse (c);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Sequence& s)
+ {
+ if (!s.context().count ("comp-number"))
+ return;
+
+ UnsignedLong n (s.context ().get<UnsignedLong> ("comp-number"));
+
+ os << "void" << endl
+ << "sequence_" << n << " (unsigned long& state," << endl
+ << "unsigned long& count," << endl
+ << "const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "* t," << endl
+ << "bool start);"
+ << endl;
+
+ Traversal::Sequence::traverse (s);
+ }
+
+ private:
+ Traversal::ContainsParticle contains_particle_;
+ };
+
+
+ //
+ //
+ struct AttributeValidationState: Traversal::Attribute,
+ protected virtual Context
+ {
+ AttributeValidationState (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ if (!a.optional ())
+ {
+ os << "bool " << ename (a) << ";";
+ }
+ }
+ };
+
+ //
+ //
+ struct Complex : Traversal::Complex,
+ protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c),
+ parser_callback_ (c),
+ parser_member_ (c),
+ parser_modifier_ (c),
+ attribute_validation_state_ (c)
+ {
+ names_parser_callback_ >> parser_callback_;
+ names_parser_member_ >> parser_member_;
+ names_parser_modifier_ >> parser_modifier_;
+ names_attribute_validation_state_ >> attribute_validation_state_;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String const& name (ename (c));
+
+ // In case of an inheritance-by-restriction, we don't need to
+ // generate parser callbacks, etc. since they are the same as in
+ // the base. We only need the parsing/validation code.
+ //
+ Boolean restriction (restriction_p (c));
+
+ Boolean he (has<Traversal::Element> (c));
+ Boolean ha (has<Traversal::Attribute> (c));
+
+ Boolean hae (has_particle<Traversal::Any> (c));
+ Boolean haa (has<Traversal::AnyAttribute> (c));
+
+ Boolean hra (false); // Has required attribute.
+ if (ha)
+ {
+ RequiredAttributeTest test (hra);
+ Traversal::Names names_test (test);
+ names (c, names_test);
+ }
+
+
+ //
+ //
+ os << "class " << type_exp << name << ": public ";
+
+ if (c.inherits_p ())
+ os << "virtual " << fq_name (c.inherits ().base ());
+ else
+ os << complex_base;
+
+ os << "{"
+ << "public:" << endl
+ << "// Parser callbacks. Override them in your " <<
+ "implementation." << endl
+ << "//" << endl;
+
+ os << "// virtual void" << endl
+ << "// pre ();" << endl
+ << endl;
+
+
+ if (!restriction && (ha || he))
+ {
+ names (c, names_parser_callback_);
+ }
+
+ String const& ret (ret_type (c));
+
+ Boolean same (c.inherits_p () &&
+ ret == ret_type (c.inherits ().base ()));
+
+ os << "virtual " << ret << endl
+ << post_name (c) << " ()" <<
+ (same || ret == L"void" ? ";" : " = 0;")
+ << endl;
+
+ //
+ //
+ if (!restriction && (he || ha))
+ {
+ os << "// Parser construction API." << endl
+ << "//" << endl;
+
+ names (c, names_parser_modifier_);
+
+ os << "void" << endl
+ << "parsers (";
+
+ {
+ ParserParamDecl decl (*this, false);
+ decl.traverse (c);
+ }
+
+ os << ");"
+ << endl;
+ }
+
+ // Default c-tor.
+ //
+ if ((!restriction && (he || ha)) ||
+ (validation && (he || hae || hra)))
+ {
+ os << "// Constructor." << endl
+ << "//" << endl
+ << name << " ();"
+ << endl;
+ }
+
+ if (polymorphic)
+ {
+ os << "public:" << endl
+ << "static const " << char_type << "*" << endl
+ << "_static_type ();"
+ << endl
+ << "virtual const " << char_type << "*" << endl
+ << "_dynamic_type () const;"
+ << endl;
+ }
+
+ // Implementation.
+ //
+ if (he || ha || (validation && (hae || haa)))
+ {
+ os << "// Implementation." << endl
+ << "//" << endl
+ << "protected:" << endl;
+ }
+
+ // element
+ //
+ if (he || (validation && hae))
+ {
+ // _start_element_impl
+ //
+ os << "virtual bool" << endl
+ << "_start_element_impl (const " << string_type << "&," << endl
+ << "const " << string_type << "&," << endl
+ << "const " << string_type << "*);"
+ << endl;
+
+ // end_element
+ //
+ os << "virtual bool" << endl
+ << "_end_element_impl (const " << string_type << "&," << endl
+ << "const " << string_type << "&);"
+ << endl;
+ }
+
+ // attribute
+ //
+ if (validation)
+ {
+ if (ha)
+ {
+ os << "virtual bool" << endl
+ << "_attribute_impl_phase_one (const " << string_type <<
+ "&," << endl
+ << "const " << string_type << "&," << endl
+ << "const " << string_type << "&);" << endl
+ << endl;
+ }
+
+ if (haa)
+ {
+ os << "virtual bool" << endl
+ << "_attribute_impl_phase_two (const " << string_type <<
+ "&," << endl
+ << "const " << string_type << "&," << endl
+ << "const " << string_type << "&);"
+ << endl;
+ }
+ }
+ else
+ {
+ if (ha)
+ {
+ os << "virtual bool" << endl
+ << "_attribute_impl (const " << string_type << "&," << endl
+ << "const " << string_type << "&," << endl
+ << "const " << string_type << "&);"
+ << endl;
+ }
+ }
+
+ // characters
+ //
+ if (validation && c.mixed ())
+ {
+ os << "virtual bool" << endl
+ << "_characters_impl (const " << string_type << "&);"
+ << endl;
+ }
+
+ if (!restriction && (he || ha))
+ {
+ os << "protected:" << endl;
+ names (c, names_parser_member_);
+ os << endl;
+ }
+
+ if (validation && (he || hae))
+ {
+ UnsignedLong depth (c.context ().get<UnsignedLong> ("depth"));
+
+ os << "protected:" << endl;
+
+ os << "struct v_state_descr_"
+ << "{"
+ << "void (" << fq_name (c) << "::*func) (" << endl
+ << "unsigned long&," << endl
+ << "unsigned long&," << endl
+ << "const " << string_type << "&," << endl
+ << "const " << string_type << "&," << endl
+ << "const " << string_type << "*," << endl
+ << "bool);"
+ << "unsigned long state;"
+ << "unsigned long count;"
+ << "};";
+
+ // Allocate one extra slot for the special state.
+ //
+ os << "struct v_state_"
+ << "{"
+ << "v_state_descr_ data[" << depth + 1 << "UL];"
+ << "unsigned long size;"
+ << "};";
+
+ os << "v_state_ v_state_first_;"
+ << "::xsd::cxx::parser::pod_stack v_state_stack_;"
+ << endl;
+
+ os << "virtual void" << endl
+ << "_pre_e_validate ();"
+ << endl;
+
+ os << "virtual void" << endl
+ << "_post_e_validate ();"
+ << endl;
+
+ Particle t (*this);
+ t.dispatch (c.contains_compositor ().compositor ());
+ }
+
+ if (validation && hra)
+ {
+ os << "protected:" << endl;
+
+ os << "struct v_state_attr_"
+ << "{";
+
+ names (c, names_attribute_validation_state_);
+
+ os << "};";
+
+ os << "v_state_attr_ v_state_attr_first_;"
+ << "::xsd::cxx::parser::pod_stack v_state_attr_stack_;"
+ << endl;
+
+ os << "virtual void" << endl
+ << "_pre_a_validate ();"
+ << endl;
+
+ os << "virtual void" << endl
+ << "_post_a_validate ();"
+ << endl;
+ }
+
+ os << "};";
+ }
+
+ private:
+ //
+ //
+ ParserCallback parser_callback_;
+ Traversal::Names names_parser_callback_;
+
+ //
+ //
+ ParserMember parser_member_;
+ Traversal::Names names_parser_member_;
+
+ //
+ //
+ ParserModifier parser_modifier_;
+ Traversal::Names names_parser_modifier_;
+
+ //
+ //
+ AttributeValidationState attribute_validation_state_;
+ Traversal::Names names_attribute_validation_state_;
+ };
+
+ struct FundType : Context,
+
+ Traversal::AnyType,
+ Traversal::AnySimpleType,
+
+ Traversal::Fundamental::Byte,
+ Traversal::Fundamental::UnsignedByte,
+ Traversal::Fundamental::Short,
+ Traversal::Fundamental::UnsignedShort,
+ Traversal::Fundamental::Int,
+ Traversal::Fundamental::UnsignedInt,
+ Traversal::Fundamental::Long,
+ Traversal::Fundamental::UnsignedLong,
+ Traversal::Fundamental::Integer,
+ Traversal::Fundamental::NonPositiveInteger,
+ Traversal::Fundamental::NonNegativeInteger,
+ Traversal::Fundamental::PositiveInteger,
+ Traversal::Fundamental::NegativeInteger,
+
+ Traversal::Fundamental::Boolean,
+
+ Traversal::Fundamental::Float,
+ Traversal::Fundamental::Double,
+ Traversal::Fundamental::Decimal,
+
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NameTokens,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Language,
+
+ Traversal::Fundamental::QName,
+
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef,
+ Traversal::Fundamental::IdRefs,
+
+ Traversal::Fundamental::AnyURI,
+
+ Traversal::Fundamental::Base64Binary,
+ Traversal::Fundamental::HexBinary,
+
+ Traversal::Fundamental::Date,
+ Traversal::Fundamental::DateTime,
+ Traversal::Fundamental::Duration,
+ Traversal::Fundamental::Day,
+ Traversal::Fundamental::Month,
+ Traversal::Fundamental::MonthDay,
+ Traversal::Fundamental::Year,
+ Traversal::Fundamental::YearMonth,
+ Traversal::Fundamental::Time,
+
+ Traversal::Fundamental::Entity,
+ Traversal::Fundamental::Entities
+ {
+ FundType (Context& c)
+ : Context (c), xs_ns_ (xs_ns_name ())
+ {
+ impl_ns_ = "::xsd::cxx::parser::";
+ impl_ns_ += (validation ? L"validating" : L"non_validating");
+
+ if (char_type == L"char")
+ string_type_ = L"::std::string";
+ else if (char_type == L"wchar_t")
+ string_type_ = L"::std::wstring";
+ else
+ string_type_ = L"::std::basic_string< " + char_type + L" >";
+ }
+
+ // anyType & anySimpleType.
+ //
+ virtual Void
+ traverse (SemanticGraph::AnyType& t)
+ {
+ gen_typedef (t, "void", "any_type_pskel", "any_type_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnySimpleType& t)
+ {
+ gen_typedef (t, "void",
+ "any_simple_type_pskel", "any_simple_type_pimpl");
+ }
+
+ // Boolean.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Boolean& t)
+ {
+ gen_typedef (t, "bool", "boolean_pskel", "boolean_pimpl");
+ }
+
+ // Integral types.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Byte& t)
+ {
+ gen_typedef (t, "signed char", "byte_pskel", "byte_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedByte& t)
+ {
+ gen_typedef (t, "unsigned char",
+ "unsigned_byte_pskel", "unsigned_byte_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Short& t)
+ {
+ gen_typedef (t, "short", "short_pskel", "short_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedShort& t)
+ {
+ gen_typedef (t, "unsigned short",
+ "unsigned_short_pskel", "unsigned_short_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Int& t)
+ {
+ gen_typedef (t, "int", "int_pskel", "int_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedInt& t)
+ {
+ gen_typedef (t, "unsigned int",
+ "unsigned_int_pskel", "unsigned_int_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Long& t)
+ {
+ gen_typedef (t, "long long", "long_pskel", "long_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedLong& t)
+ {
+ gen_typedef (t, "unsigned long long",
+ "unsigned_long_pskel", "unsigned_long_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Integer& t)
+ {
+ gen_typedef (t, "long long", "integer_pskel", "integer_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NegativeInteger& t)
+ {
+ gen_typedef (t, "long long",
+ "negative_integer_pskel", "negative_integer_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger& t)
+ {
+ gen_typedef (t, "long long",
+ "non_positive_integer_pskel",
+ "non_positive_integer_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::PositiveInteger& t)
+ {
+ gen_typedef (t, "unsigned long long",
+ "positive_integer_pskel", "positive_integer_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger& t)
+ {
+ gen_typedef (t, "unsigned long long",
+ "non_negative_integer_pskel",
+ "non_negative_integer_pimpl");
+ }
+
+ // Floats.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Float& t)
+ {
+ gen_typedef (t, "float", "float_pskel", "float_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Double& t)
+ {
+ gen_typedef (t, "double", "double_pskel", "double_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Decimal& t)
+ {
+ gen_typedef (t, "double", "decimal_pskel", "decimal_pimpl");
+ }
+
+ // Strings.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String& t)
+ {
+ gen_typedef (t, string_type_, "string_pskel", "string_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString& t)
+ {
+ gen_typedef (t, string_type_,
+ "normalized_string_pskel", "normalized_string_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token& t)
+ {
+ gen_typedef (t, string_type_, "token_pskel", "token_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken& t)
+ {
+ nmtoken_ = gen_typedef (t, string_type_,
+ "nmtoken_pskel", "nmtoken_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameTokens& t)
+ {
+ // NMTOKENS uses NMTOKEN implementation to parse individual items.
+ // As a result, we don't generate NMTOKENS if we didn't generate
+ // NMTOKEN. Here we assume NMTOKEN is handled before NMTOKENS.
+ //
+ if(nmtoken_)
+ gen_typedef (t, xs_ns_ + L"::string_sequence",
+ "nmtokens_pskel", "nmtokens_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name& t)
+ {
+ gen_typedef (t, string_type_, "name_pskel", "name_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName& t)
+ {
+ gen_typedef (t, string_type_, "ncname_pskel", "ncname_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Language& t)
+ {
+ gen_typedef (t, string_type_, "language_pskel", "language_pimpl");
+ }
+
+ // Qualified name.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::QName& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::qname", "qname_pskel", "qname_pimpl");
+ }
+
+ // ID/IDREF.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id& t)
+ {
+ gen_typedef (t, string_type_, "id_pskel", "id_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef& t)
+ {
+ idref_ = gen_typedef (t, string_type_, "idref_pskel", "idref_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRefs& t)
+ {
+ // IDREFS uses IDREF implementation to parse individual items.
+ // As a result, we don't generate IDREFS if we didn't generate
+ // IDREF. Here we assume IDREF is handled before IDREFS.
+ //
+ if (idref_)
+ gen_typedef (t, xs_ns_ + L"::string_sequence",
+ "idrefs_pskel", "idrefs_pimpl");
+ }
+
+ // URI.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::AnyURI& t)
+ {
+ gen_typedef (t, string_type_, "uri_pskel", "uri_pimpl");
+ }
+
+ // Binary.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Base64Binary& t)
+ {
+ String buffer (L"::std::auto_ptr< " + xs_ns_ + L"::buffer >");
+ gen_typedef (t, buffer,
+ "base64_binary_pskel", "base64_binary_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::HexBinary& t)
+ {
+ String buffer (L"::std::auto_ptr< " + xs_ns_ + L"::buffer >");
+ gen_typedef (t, buffer, "hex_binary_pskel", "hex_binary_pimpl");
+ }
+
+
+ // Date/time.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Date& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::date", "date_pskel", "date_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::DateTime& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::date_time",
+ "date_time_pskel", "date_time_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Duration& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::duration",
+ "duration_pskel", "duration_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Day& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::gday", "gday_pskel", "gday_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Month& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::gmonth",
+ "gmonth_pskel", "gmonth_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::MonthDay& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::gmonth_day",
+ "gmonth_day_pskel", "gmonth_day_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Year& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::gyear", "gyear_pskel", "gyear_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::YearMonth& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::gyear_month",
+ "gyear_month_pskel", "gyear_month_pimpl");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Time& t)
+ {
+ gen_typedef (t, xs_ns_ + L"::time", "time_pskel", "time_pimpl");
+ }
+
+ // Entity.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entity&)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entities&)
+ {
+ }
+
+ private:
+ Boolean
+ gen_typedef (SemanticGraph::Type& t,
+ String const& type,
+ String const& pskel,
+ String const& pimpl)
+ {
+ if (ret_type (t) == type)
+ {
+ os << "typedef " << impl_ns_ << "::" << pskel << "< " <<
+ char_type << " > " << ename (t) << ";";
+
+ String const& pimpl_name (t.context ().get<String> ("impl"));
+
+ os << "typedef " << impl_ns_ << "::" << pimpl << "< " <<
+ char_type << " > " << pimpl_name << ";"
+ << endl;
+
+ return true;
+ }
+
+ return false;
+ }
+
+ String xs_ns_;
+ String impl_ns_;
+ String string_type_;
+
+ Boolean idref_;
+ Boolean nmtoken_;
+ };
+
+ struct FundNamespace : Namespace,
+ protected virtual Context
+ {
+ FundNamespace (Context& c)
+ : Context (c), Namespace (c)
+ {
+ }
+
+ void
+ traverse (Type& ns)
+ {
+ pre (ns);
+
+ String impl ("::xsd::cxx::parser::");
+ impl += (validation ? L"validating" : L"non_validating");
+
+ String const c (char_type);
+
+ os << "// Built-in XML Schema types mapping." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::string_sequence< " << c <<
+ " > string_sequence;"
+ << "typedef ::xsd::cxx::parser::qname< " << c << " > qname;"
+ << "typedef ::xsd::cxx::parser::buffer buffer;"
+ << "typedef ::xsd::cxx::parser::time_zone time_zone;"
+ << "typedef ::xsd::cxx::parser::gday gday;"
+ << "typedef ::xsd::cxx::parser::gmonth gmonth;"
+ << "typedef ::xsd::cxx::parser::gyear gyear;"
+ << "typedef ::xsd::cxx::parser::gmonth_day gmonth_day;"
+ << "typedef ::xsd::cxx::parser::gyear_month gyear_month;"
+ << "typedef ::xsd::cxx::parser::date date;"
+ << "typedef ::xsd::cxx::parser::time time;"
+ << "typedef ::xsd::cxx::parser::date_time date_time;"
+ << "typedef ::xsd::cxx::parser::duration duration;"
+ << endl;
+
+ os << "// Base parser skeletons." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::parser_base< " << c <<
+ " > parser_base;"
+ << "typedef " << impl << "::empty_content< " << c <<
+ " > empty_content;"
+ << "typedef " << impl << "::simple_content< " << c <<
+ " > simple_content;"
+ << "typedef " << impl << "::complex_content< " << c <<
+ " > complex_content;"
+ << "typedef " << impl << "::list_base< " << c << " > list_base;"
+ << endl;
+
+ if (polymorphic)
+ {
+ os << "// Parser map interface and default implementation." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::parser_map< " << c <<
+ " > parser_map;"
+ << "typedef ::xsd::cxx::parser::parser_map_impl< " << c <<
+ " > parser_map_impl;"
+ << endl;
+ }
+
+ os << "// Parser skeletons and implementations for the XML Schema" << endl
+ << "// built-in types." << endl
+ << "//" << endl;
+
+ names (ns);
+
+ os << "// Exceptions. See libxsd/xsd/cxx/parser/exceptions.hxx " <<
+ "for details." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::exception< " <<
+ char_type << " > exception;"
+ << endl
+ << "// Parsing diagnostics." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::severity severity;"
+ << "typedef ::xsd::cxx::parser::error< " << c << " > error;"
+ << "typedef ::xsd::cxx::parser::diagnostics< " << c <<
+ " > diagnostics;"
+ << "typedef ::xsd::cxx::parser::parsing< " << c << " > parsing;"
+ << endl;
+
+ os << "// Error handler. See " <<
+ "libxsd/xsd/cxx/xml/error-handler.hxx for details." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::xml::error_handler< " << c <<
+ " > error_handler;"
+ << endl;
+
+ os << "// Read-only string." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::ro_string< " << c << " > ro_string;"
+ << endl;
+
+ if (xml_parser == L"xerces")
+ {
+ os << "// Parsing flags. See " <<
+ "libxsd/xsd/cxx/parser/xerces/elements.hxx" << endl
+ << "// for details." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::xerces::flags flags;"
+ << endl;
+
+ os << "// Parsing properties. See " <<
+ "libxsd/xsd/cxx/parser/xerces/elements.hxx" << endl
+ << "// for details." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::xerces::properties< " << c <<
+ " > properties;"
+ << endl;
+
+ os << "// Document type. See " <<
+ "libxsd/xsd/cxx/parser/xerces/elements.hxx" << endl
+ << "// for details." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::xerces::document< " << c <<
+ " > document;"
+ << endl;
+
+ }
+ else if (xml_parser == L"expat")
+ {
+ os << "// Document type. See " <<
+ "libxsd/xsd/cxx/parser/expat/elements.hxx" << endl
+ << "// for details." << endl
+ << "//" << endl
+ << "typedef ::xsd::cxx::parser::expat::document< " << c <<
+ " > document;"
+ << endl;
+ }
+
+ post (ns);
+ }
+ };
+ }
+
+ Void
+ generate_parser_header (Context& ctx, Boolean generate_xml_schema)
+ {
+ String c (ctx.char_type);
+
+ //
+ //
+ if (c == L"char")
+ {
+ ctx.os << "#ifndef XSD_USE_CHAR" << endl
+ << "#define XSD_USE_CHAR" << endl
+ << "#endif" << endl
+ << endl;
+
+ ctx.os << "#ifndef XSD_CXX_PARSER_USE_CHAR" << endl
+ << "#define XSD_CXX_PARSER_USE_CHAR" << endl
+ << "#endif" << endl
+ << endl;
+ }
+ else if (c == L"wchar_t")
+ {
+ ctx.os << "#ifndef XSD_USE_WCHAR" << endl
+ << "#define XSD_USE_WCHAR" << endl
+ << "#endif" << endl
+ << endl;
+
+ ctx.os << "#ifndef XSD_CXX_PARSER_USE_WCHAR" << endl
+ << "#define XSD_CXX_PARSER_USE_WCHAR" << endl
+ << "#endif" << endl
+ << endl;
+ }
+
+ //
+ //
+ NarrowString extern_xml_schema;
+
+ if (!generate_xml_schema)
+ extern_xml_schema = ctx.options.value<CLI::extern_xml_schema> ();
+
+ if (extern_xml_schema)
+ {
+ String name (ctx.hxx_expr->merge (extern_xml_schema));
+
+ ctx.os << "#include " << ctx.process_include_path (name) << endl
+ << endl;
+
+ // Generate includes that came from the type map.
+ //
+ if (ctx.schema_root.context ().count ("includes"))
+ {
+ typedef Cult::Containers::Set<String> Includes;
+
+ Includes const& is (
+ ctx.schema_root.context ().get<Includes> ("includes"));
+
+ for (Includes::ConstReverseIterator i (is.rbegin ());
+ i != is.rend (); ++i)
+ {
+ ctx.os << "#include " << *i << endl;
+ }
+
+ ctx.os << endl;
+ }
+ }
+ else
+ {
+ ctx.os << "#include <xsd/cxx/xml/error-handler.hxx>" << endl
+ << "#include <xsd/cxx/parser/exceptions.hxx>" << endl
+ << "#include <xsd/cxx/parser/elements.hxx>" << endl
+ << "#include <xsd/cxx/parser/xml-schema.hxx>" << endl;
+
+ if (ctx.polymorphic)
+ ctx.os << "#include <xsd/cxx/parser/map.hxx>" << endl;
+
+ if (ctx.validation)
+ ctx.os << "#include <xsd/cxx/parser/validating/parser.hxx>" << endl
+ << "#include <xsd/cxx/parser/validating/exceptions.hxx>" << endl
+ << "#include <xsd/cxx/parser/validating/xml-schema-pskel.hxx>" << endl
+ << "#include <xsd/cxx/parser/validating/xml-schema-pimpl.hxx>" << endl;
+ else
+ ctx.os << "#include <xsd/cxx/parser/non-validating/parser.hxx>" << endl
+ << "#include <xsd/cxx/parser/non-validating/xml-schema-pskel.hxx>" << endl
+ << "#include <xsd/cxx/parser/non-validating/xml-schema-pimpl.hxx>" << endl;
+
+ ctx.os << "#include <xsd/cxx/parser/" << ctx.xml_parser <<
+ "/elements.hxx>" << endl
+ << endl;
+
+ // Generate includes that came from the type map.
+ //
+ if (ctx.schema_root.context ().count ("includes"))
+ {
+ typedef Cult::Containers::Set<String> Includes;
+
+ Includes const& is (
+ ctx.schema_root.context ().get<Includes> ("includes"));
+
+ for (Includes::ConstReverseIterator i (is.rbegin ());
+ i != is.rend (); ++i)
+ {
+ ctx.os << "#include " << *i << endl;
+ }
+
+ ctx.os << endl;
+ }
+
+ // Generate fundamental types.
+ //
+ if (generate_xml_schema)
+ {
+ Traversal::Schema schema;
+ Traversal::Names names;
+ FundNamespace ns (ctx);
+
+ schema >> names >> ns;
+
+ Traversal::Names ns_names;
+ FundType type (ctx);
+
+ ns >> ns_names >> type;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ else
+ {
+ Traversal::Schema schema, xsd;
+ Traversal::Implies implies;
+ Traversal::Names names;
+ FundNamespace ns (ctx);
+
+ schema >> implies >> xsd >> names >> ns;
+
+ Traversal::Names ns_names;
+ FundType type (ctx);
+
+ ns >> ns_names >> type;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+
+ // Generate user type mapping.
+ //
+ if (!generate_xml_schema)
+ {
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Includes includes (ctx, Includes::header);
+ Traversal::Names schema_names;
+
+ Namespace ns (ctx);
+ Traversal::Names names;
+
+ schema >> includes;
+ schema >> sources >> schema;
+ schema >> schema_names >> ns >> names;
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+ }
+}
diff --git a/xsd/cxx/parser/parser-header.hxx b/xsd/cxx/parser/parser-header.hxx
new file mode 100644
index 0000000..348acdf
--- /dev/null
+++ b/xsd/cxx/parser/parser-header.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/parser/parser-header.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_PARSER_HEADER_HXX
+#define CXX_PARSER_PARSER_HEADER_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/parser/elements.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ Void
+ generate_parser_header (Context&, Boolean generate_xml_schema);
+ }
+}
+
+#endif // CXX_PARSER_PARSER_HEADER_HXX
diff --git a/xsd/cxx/parser/parser-inline.cxx b/xsd/cxx/parser/parser-inline.cxx
new file mode 100644
index 0000000..f2d3bd8
--- /dev/null
+++ b/xsd/cxx/parser/parser-inline.cxx
@@ -0,0 +1,407 @@
+// file : xsd/cxx/parser/parser-inline.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/parser/parser-inline.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace
+ {
+ //
+ //
+ struct List: Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String const& name (ename (l));
+ SemanticGraph::Type& t (l.argumented ().type ());
+
+ String item (unclash (name, "item"));
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ // item_parser
+ //
+ os << inl
+ << "void " << name << "::" << endl
+ << unclash (name, "item_parser") << " (" <<
+ fq_name (t) << "& " << item << ")"
+ << "{"
+ << "this->_xsd_" << item << "_ = &" << item << ";"
+ << "}";
+
+ // parsers
+ //
+ os << inl
+ << "void " << name << "::" << endl
+ << "parsers (" << fq_name (t) << "& " << item << ")"
+ << "{"
+ << "this->_xsd_" << item << "_ = &" << item << ";"
+ << "}";
+
+ // c-tor
+ //
+ os << inl
+ << name << "::" << endl
+ << name << " ()" << endl
+ << ": _xsd_" << item << "_ (0)"
+ << "{"
+ << "}";
+ }
+ };
+
+
+ //
+ //
+ struct ParserModifier: Traversal::Member,
+ protected virtual Context
+ {
+ ParserModifier (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m))
+ return;
+
+ String const& scope (ename (m.scope ()));
+ String const& parser (eparser (m));
+
+ Boolean poly (polymorphic &&
+ m.is_a<SemanticGraph::Element> () &&
+ !anonymous (m.type ()));
+
+ os << inl
+ << "void " << scope << "::" << endl
+ << parser << " (" << fq_name (m.type ()) << "& p)"
+ << "{"
+ << "this->" << emember (m) << " = &p;"
+ << "}";
+
+ if (poly)
+ {
+ os << inl
+ << "void " << scope << "::" << endl
+ << parser << " (const " << parser_map << "& m)"
+ << "{"
+ << "this->" << emember_map (m) << " = &m;"
+ << "}";
+ }
+ }
+ };
+
+
+ //
+ //
+ struct ParserMemberSet: Traversal::Member,
+ protected virtual Context
+ {
+ ParserMemberSet (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m)) return;
+
+ String const& name (ename (m));
+
+ os << "this->" << emember (m) << " = &" << name << ";";
+ }
+ };
+
+
+ //
+ //
+ struct ParserMemberInit: Traversal::Member,
+ protected virtual Context
+ {
+ ParserMemberInit (Context& c)
+ : Context (c), first_ (true)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m)) return;
+
+ if (first_)
+ first_ = false;
+ else
+ os << "," << endl << " ";
+
+ os << emember (m) << " (0)";
+
+ if (polymorphic &&
+ m.is_a<SemanticGraph::Element> () &&
+ !anonymous (m.type ()))
+ {
+ os << "," << endl
+ << " " << emember_map (m) << " (0)";
+ }
+ }
+
+ Boolean
+ comma () const
+ {
+ return !first_;
+ }
+
+ private:
+ Boolean first_;
+ };
+
+ struct ParserBaseSet: Traversal::Complex,
+ Traversal::List,
+ protected virtual Context
+ {
+ ParserBaseSet (Context& c)
+ : Context (c), member_ (c)
+ {
+ inherits_ >> *this;
+ names_ >> member_;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ inherits (c, inherits_);
+
+ if (!restriction_p (c))
+ names (c, names_);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::List& l)
+ {
+ String const& name (ename (l));
+ String item (unclash (name, "item"));
+
+ os << "this->_xsd_" << item << "_ = &" << name << "_item;";
+ }
+
+ private:
+ Traversal::Inherits inherits_;
+
+ ParserMemberSet member_;
+ Traversal::Names names_;
+ };
+
+ struct Particle: Traversal::All,
+ protected virtual Context
+ {
+ Particle (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::All& a)
+ {
+ if (!a.context().count ("comp-number"))
+ return;
+
+ UnsignedLong state_count (
+ a.context().get<UnsignedLong> ("state-count"));
+
+ os << "," << endl
+ << " v_all_count_ (" << state_count << "UL, v_all_first_)";
+ }
+ };
+
+ //
+ //
+ struct Complex: Traversal::Complex,
+ protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c),
+ parser_modifier_ (c),
+ parser_base_set_ (c),
+ parser_member_set_ (c),
+ particle_ (c)
+ {
+ names_parser_modifier_ >> parser_modifier_;
+ inherits_parser_base_set_ >> parser_base_set_;
+ names_parser_member_set_ >> parser_member_set_;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ Boolean he (has<Traversal::Element> (c));
+ Boolean ha (has<Traversal::Attribute> (c));
+
+ Boolean hae (has_particle<Traversal::Any> (c));
+
+ Boolean hra (false); // Has required attribute.
+ if (ha)
+ {
+ RequiredAttributeTest test (hra);
+ Traversal::Names names_test (test);
+ names (c, names_test);
+ }
+
+ Boolean restriction (restriction_p (c));
+
+ if (!((!restriction && (he || ha)) ||
+ (validation && (he || hae || hra))))
+ return;
+
+ String const& name (ename (c));
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ if (!restriction && (he || ha))
+ {
+ // <name>_parser ()
+ //
+ names (c, names_parser_modifier_);
+
+
+ // parsers ()
+ //
+
+ os << inl
+ << "void " << name << "::" << endl
+ << "parsers (";
+
+ {
+ ParserParamDecl decl (*this, true);
+ decl.traverse (c);
+ }
+
+ os << ")"
+ << "{";
+
+ inherits (c, inherits_parser_base_set_);
+ names (c, names_parser_member_set_);
+
+ os << "}";
+ }
+
+ // Default c-tor.
+ //
+ os << inl
+ << name << "::" << endl
+ << name << " ()" << endl
+ << ": ";
+
+ Boolean comma (false);
+
+ if (!restriction && (he || ha))
+ {
+ ParserMemberInit member_init (*this);
+ Traversal::Names names_member_init (member_init);
+
+ names (c, names_member_init);
+
+ comma = member_init.comma ();
+ }
+
+ if (validation && (he || hae))
+ {
+ if (comma)
+ os << "," << endl << " ";
+
+ os << "v_state_stack_ (sizeof (v_state_), &v_state_first_)";
+
+ particle_.dispatch (c.contains_compositor ().compositor ());
+
+ comma = true;
+ }
+
+ if (validation && (hra))
+ {
+ if (comma)
+ os << "," << endl << " ";
+
+ os << "v_state_attr_stack_ (sizeof (v_state_attr_), " <<
+ "&v_state_attr_first_)";
+ }
+
+ os << "{"
+ << "}";
+ }
+
+ private:
+ //
+ //
+ ParserModifier parser_modifier_;
+ Traversal::Names names_parser_modifier_;
+
+ //
+ //
+ ParserBaseSet parser_base_set_;
+ Traversal::Inherits inherits_parser_base_set_;
+
+ //
+ //
+ ParserMemberSet parser_member_set_;
+ Traversal::Names names_parser_member_set_;
+
+ //
+ //
+ Particle particle_;
+ };
+ }
+
+ Void
+ generate_parser_inline (Context& ctx)
+ {
+ // Emit "weak" header includes that are used in the file-per-type
+ // compilation model.
+ //
+ if (!ctx.options.value<CLI::generate_inline> ())
+ {
+ Traversal::Schema schema;
+ Includes includes (ctx, Includes::source);
+
+ schema >> includes;
+ schema.dispatch (ctx.schema_root);
+ }
+
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names schema_names;
+
+ Namespace ns (ctx);
+ Traversal::Names names;
+
+ schema >> sources >> schema;
+ schema >> schema_names >> ns >> names;
+
+ List list (ctx);
+ Complex complex (ctx);
+
+ names >> list;
+ names >> complex;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/parser/parser-inline.hxx b/xsd/cxx/parser/parser-inline.hxx
new file mode 100644
index 0000000..2016828
--- /dev/null
+++ b/xsd/cxx/parser/parser-inline.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/parser/parser-inline.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_PARSER_INLINE_HXX
+#define CXX_PARSER_PARSER_INLINE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/parser/elements.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ Void
+ generate_parser_inline (Context&);
+ }
+}
+
+#endif // CXX_PARSER_PARSER_INLINE_HXX
diff --git a/xsd/cxx/parser/parser-source.cxx b/xsd/cxx/parser/parser-source.cxx
new file mode 100644
index 0000000..be6c8df
--- /dev/null
+++ b/xsd/cxx/parser/parser-source.cxx
@@ -0,0 +1,924 @@
+// file : xsd/cxx/parser/parser-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/parser/parser-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace
+ {
+ struct Enumeration: Traversal::Enumeration,
+ protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String const& name (ename (e));
+ String const& ret (ret_type (e));
+
+ SemanticGraph::Type& base (e.inherits ().base ());
+
+ Boolean same (ret == ret_type (base));
+
+ if (same || ret == L"void" || polymorphic)
+ {
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+ }
+
+ if (same || ret == L"void")
+ {
+ os << ret << " " << name << "::" << endl
+ << post_name (e) << " ()"
+ << "{";
+
+ if (same)
+ {
+ if (ret == L"void")
+ os << post_name (base) << " ();";
+ else
+ os << "return " << post_name (base) << " ();";
+ }
+
+ os << "}";
+ }
+
+ if (polymorphic)
+ {
+ String id (e.name ());
+
+ if (String ns = xml_ns_name (e))
+ {
+ id += L' ';
+ id += ns;
+ }
+
+ os << "const " << char_type << "* " << name << "::" << endl
+ << "_static_type ()"
+ << "{"
+ << "return " << L << strlit (id) << ";"
+ << "}";
+
+ os << "const " << char_type << "* " << name << "::" << endl
+ << "_dynamic_type () const"
+ << "{"
+ << "return _static_type ();"
+ << "}";
+
+ if (validation)
+ {
+ Boolean gen (!anonymous (e));
+
+ // We normally don't need to enter anonymous types into
+ // the inheritance map. The only exception is when an
+ // anonymous types is defined inside an element that
+ // is a member of a substitution group.
+ //
+ if (!gen)
+ {
+ // The first instance that this anonymous type classifies
+ // is the prototype for others if any.
+ //
+ SemanticGraph::Instance& i (
+ e.classifies_begin ()->instance ());
+
+ if (SemanticGraph::Element* e =
+ dynamic_cast<SemanticGraph::Element*> (&i))
+ {
+ if (e->substitutes_p ())
+ gen = true;
+ }
+ }
+
+ if (gen)
+ {
+ os << "static" << endl
+ << "const ::xsd::cxx::parser::validating::inheritance_map_entry< " <<
+ char_type << " >" << endl
+ << "_xsd_" << name << "_inheritance_map_entry_ (" << endl
+ << name << "::_static_type ()," << endl
+ << fq_name (base) << "::_static_type ());"
+ << endl;
+ }
+ }
+ }
+ }
+ };
+
+ //
+ //
+ struct List: Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String const& name (ename (l));
+ SemanticGraph::Type& t (l.argumented ().type ());
+
+ String item (unclash (name, "item"));
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ // item
+ //
+ String const& arg (arg_type (t));
+
+ os << "void " << name << "::" << endl
+ << item;
+
+ if (arg == L"void")
+ os << " ()";
+ else
+ os << " (" << arg << ")";
+
+ os << "{"
+ << "}";
+
+ // post
+ //
+ if (ret_type (l) == L"void")
+ os << "void " << name << "::" << endl
+ << post_name (l) << " ()"
+ << "{"
+ << "}";
+
+ // parse_item
+ //
+ String inst (L"_xsd_" + item + L"_");
+ String const& post (post_name (t));
+
+ os << "void " << name << "::" << endl
+ << "_xsd_parse_item (const " << string_type << "& v)"
+ << "{"
+ << "if (this->" << inst << ")"
+ << "{"
+ << "this->" << inst << "->pre ();"
+ << "this->" << inst << "->_pre_impl ();"
+ << "this->" << inst << "->_characters (v);"
+ << "this->" << inst << "->_post_impl ();";
+
+ if (ret_type (t) == L"void")
+ os << "this->" << inst << "->" << post << " ();"
+ << "this->" << item << " ();";
+ else
+ os << "this->" << item << " (this->" << inst << "->" <<
+ post << " ());";
+
+ os << "}"
+ << "}";
+
+ //
+ //
+ if (polymorphic)
+ {
+ String id (l.name ());
+
+ if (String ns = xml_ns_name (l))
+ {
+ id += L' ';
+ id += ns;
+ }
+
+ os << "const " << char_type << "* " << name << "::" << endl
+ << "_static_type ()"
+ << "{"
+ << "return " << L << strlit (id) << ";"
+ << "}";
+
+ os << "const " << char_type << "* " << name << "::" << endl
+ << "_dynamic_type () const"
+ << "{"
+ << "return _static_type ();"
+ << "}";
+ }
+ }
+ };
+
+ //
+ //
+ struct Union: Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String const& name (ename (u));
+ String const& ret (ret_type (u));
+
+ if (ret == L"void" || polymorphic)
+ {
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+ }
+
+ if (ret == L"void")
+ {
+ os << "void " << name << "::" << endl
+ << post_name (u) << " ()"
+ << "{"
+ << "}";
+ }
+
+ if (polymorphic)
+ {
+ String id (u.name ());
+
+ if (String ns = xml_ns_name (u))
+ {
+ id += L' ';
+ id += ns;
+ }
+
+ os << "const " << char_type << "* " << name << "::" << endl
+ << "_static_type ()"
+ << "{"
+ << "return " << L << strlit (id) << ";"
+ << "}";
+
+ os << "const " << char_type << "* " << name << "::" << endl
+ << "_dynamic_type () const"
+ << "{"
+ << "return _static_type ();"
+ << "}";
+ }
+ }
+ };
+
+ //
+ //
+ struct StartElement : Traversal::Element,
+ protected virtual Context
+ {
+ StartElement (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (skip (e))
+ return;
+
+ Boolean poly (polymorphic && !anonymous (e.type ()));
+
+ String const& inst (poly ? emember_cache (e) : emember (e));
+
+ os << "if (";
+
+ if (poly && e.global ())
+ os << "(";
+
+ if (e.qualified () && e.namespace_ ().name ())
+ {
+ os << "n == " << L << strlit (e.name ()) << " && " <<
+ "ns == " << L << strlit (e.namespace_ ().name ());
+ }
+ else
+ {
+ os << "n == " << L << strlit (e.name ()) << " && ns.empty ()";
+ }
+
+ // Only a globally-defined element can be a subst-group root.
+ //
+ if (poly && e.global ())
+ {
+ os << ") ||" << endl
+ << "::xsd::cxx::parser::substitution_map_instance< " <<
+ char_type << " > ().check (" << endl
+ << "ns, n, " << L << strlit (e.namespace_ ().name ()) <<
+ ", " << L << strlit (e.name ()) << ", t)";
+ }
+
+ os << ")"
+ << "{";
+
+ if (poly)
+ {
+ SemanticGraph::Type& t (e.type ());
+
+ // For pre-computing length.
+ //
+ String type_id (t.name ());
+
+ if (String type_ns = xml_ns_name (t))
+ {
+ type_id += L' ';
+ type_id += type_ns;
+ }
+
+ String fq_type (fq_name (t));
+ String const& member (emember (e));
+ String const& member_map (emember_map (e));
+
+ os << "if (t == 0 && this->" << member << " != 0)" << endl
+ << "this->" << inst << " = this->" << member << ";"
+ << "else"
+ << "{"
+ << string_type << " ts (" << fq_type <<
+ "::_static_type (), " << type_id.size () << "UL);"
+ << endl
+ << "if (t == 0)" << endl
+ << "t = &ts;"
+ << endl
+ << "if (this->" << member << " != 0 && *t == ts)" << endl
+ << "this->" << inst << " = this->" << member << ";"
+ << "else if (this->" << member_map << " != 0)" << endl
+ << "this->" << inst << " = dynamic_cast< " << fq_type <<
+ "* > (" << endl
+ << "this->" << member_map << "->find (*t));"
+ << "else" << endl
+ << "this->" << inst << " = 0;"
+ << "}";
+ }
+
+ os << "this->" << complex_base << "::context_.top ().parser_ = " <<
+ "this->" << inst << ";"
+ << endl
+ << "if (this->" << inst << ")" << endl
+ << "this->" << inst << "->pre ();" // _start_element calls _pre
+ << endl
+ << "return true;"
+ << "}";
+ }
+ };
+
+
+ //
+ //
+ struct EndElement : Traversal::Element,
+ protected virtual Context
+ {
+ EndElement (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (skip (e))
+ return;
+
+ Boolean poly (polymorphic && !anonymous (e.type ()));
+
+ String const& name (ename (e));
+ String const& inst (poly ? emember_cache (e) : emember (e));
+
+ os << "if (";
+
+ if (poly && e.global ())
+ os << "(";
+
+ if (e.qualified () && e.namespace_ ().name ())
+ {
+ os << "n == " << L << strlit (e.name ()) << " && " <<
+ "ns == " << L << strlit (e.namespace_ ().name ());
+ }
+ else
+ {
+ os << "n == " << L << strlit (e.name ()) << " && ns.empty ()";
+ }
+
+ // Only a globally-defined element can be a subst-group root.
+ //
+ if (poly && e.global ())
+ {
+ os << ") ||" << endl
+ << "::xsd::cxx::parser::substitution_map_instance< " <<
+ char_type << " > ().check (" << endl
+ << "ns, n, " << L << strlit (e.namespace_ ().name ()) <<
+ ", " << L << strlit (e.name ()) << ")";
+ }
+
+ os << ")"
+ << "{";
+
+ // _end_element calls post
+ //
+
+ SemanticGraph::Type& type (e.type ());
+ String const& post (post_name (type));
+
+ os << "if (this->" << inst << ")";
+
+ if (ret_type (type) == L"void")
+ os << "{"
+ << "this->" << inst << "->" << post << " ();"
+ << "this->" << name << " ();"
+ << "}";
+ else
+ os << endl
+ << "this->" << name << " (this->" << inst << "->" <<
+ post << " ());"
+ << endl;
+
+ os << "return true;"
+ << "}";
+ }
+ };
+
+ //
+ //
+ struct Attribute : Traversal::Attribute,
+ protected virtual Context
+ {
+ Attribute (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ String const& name (ename (a));
+ String const& inst (emember (a));
+
+ if (a.qualified () && a.namespace_ ().name ())
+ {
+ os << "if (n == " << L << strlit (a.name ()) << " && " <<
+ "ns == " << L << strlit (a.namespace_ ().name ()) << ")"
+ << "{";
+ }
+ else
+ {
+ os << "if (n == " << L << strlit (a.name ()) << " && ns.empty ())"
+ << "{";
+ }
+
+ SemanticGraph::Type& type (a.type ());
+ String const& post (post_name (type));
+ String const& ret (ret_type (type));
+
+ os << "if (this->" << inst << ")"
+ << "{"
+ << "this->" << inst << "->pre ();"
+ << "this->" << inst << "->_pre_impl ();"
+ << "this->" << inst << "->_characters (v);"
+ << "this->" << inst << "->_post_impl ();";
+
+ if (ret == L"void")
+ os << "this->" << inst << "->" << post << " ();"
+ << "this->" << name << " ();";
+ else
+ os << "this->" << name << " (this->" << inst << "->" <<
+ post << " ());";
+
+ os << "}"
+ << "return true;"
+ << "}";
+ }
+ };
+
+ //
+ //
+ struct ParserCallback: Traversal::Member,
+ protected virtual Context
+ {
+ ParserCallback (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m))
+ return;
+
+ String const& arg (arg_type (m.type ()));
+
+ os << "void " << ename (m.scope ()) << "::" << endl
+ << ename (m);
+
+ if (arg == L"void")
+ os << " ()";
+ else
+ os << " (" << arg << ")";
+
+ os << "{"
+ << "}";
+ }
+ };
+
+ //
+ //
+ struct Complex : Traversal::Complex,
+ protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c),
+ parser_callback_ (c),
+ start_element_ (c),
+ end_element_ (c),
+ attribute_ (c)
+ {
+ names_parser_callback_ >> parser_callback_;
+ names_start_element_ >> start_element_;
+ names_end_element_ >> end_element_;
+ names_attribute_ >> attribute_;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ Boolean he (has<Traversal::Element> (c));
+ Boolean ha (has<Traversal::Attribute> (c));
+
+ String const& ret (ret_type (c));
+ Boolean same (c.inherits_p () &&
+ ret == ret_type (c.inherits ().base ()));
+
+ String const& name (ename (c));
+
+ if ((he || ha || same || ret == L"void") || polymorphic)
+ {
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+ }
+
+ if (polymorphic)
+ {
+ String id (c.name ());
+
+ if (String ns = xml_ns_name (c))
+ {
+ id += L' ';
+ id += ns;
+ }
+
+ os << "const " << char_type << "* " << name << "::" << endl
+ << "_static_type ()"
+ << "{"
+ << "return " << L << strlit (id) << ";"
+ << "}";
+
+ os << "const " << char_type << "* " << name << "::" << endl
+ << "_dynamic_type () const"
+ << "{"
+ << "return _static_type ();"
+ << "}";
+
+ if (c.inherits_p () && validation)
+ {
+ Boolean gen (!anonymous (c));
+
+ // We normally don't need to enter anonymous types into
+ // the inheritance map. The only exception is when an
+ // anonymous types is defined inside an element that
+ // is a member of a substitution group.
+ //
+ if (!gen)
+ {
+ // The first instance that this anonymous type classifies
+ // is the prototype for others if any.
+ //
+ SemanticGraph::Instance& i (
+ c.classifies_begin ()->instance ());
+
+ if (SemanticGraph::Element* e =
+ dynamic_cast<SemanticGraph::Element*> (&i))
+ {
+ if (e->substitutes_p ())
+ gen = true;
+ }
+ }
+
+ if (gen)
+ {
+ SemanticGraph::Type& base (c.inherits ().base ());
+
+ os << "static" << endl
+ << "const ::xsd::cxx::parser::validating::inheritance_map_entry< " <<
+ char_type << " >" << endl
+ << "_xsd_" << name << "_inheritance_map_entry_ (" << endl
+ << name << "::_static_type ()," << endl
+ << fq_name (base) << "::_static_type ());"
+ << endl;
+ }
+ }
+ }
+
+ if (!(he || ha || same || ret == L"void"))
+ return;
+
+ // Parser callbacks.
+ //
+ if (!restriction_p (c))
+ names (c, names_parser_callback_);
+
+ if (same || ret == L"void")
+ {
+ os << ret << " " << name << "::" << endl
+ << post_name (c) << " ()"
+ << "{";
+
+ if (same)
+ {
+ SemanticGraph::Type& base (c.inherits ().base ());
+
+ if (ret == L"void")
+ os << post_name (base) << " ();";
+ else
+ os << "return " << post_name (base) << " ();";
+ }
+
+ os << "}";
+ }
+
+ // The rest is parsing/validation code which is generated in
+ // *-validation-source.cxx.
+ //
+ if (validation)
+ return;
+
+ // Don't use restriction_p here since we don't want special
+ // treatment of anyType.
+ //
+ Boolean restriction (
+ c.inherits_p () &&
+ c.inherits ().is_a<SemanticGraph::Restricts> ());
+
+ // _start_element_impl & _end_element_impl
+ //
+ if (he)
+ {
+ os << "bool " << name << "::" << endl
+ << "_start_element_impl (const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "* t)"
+ << "{"
+ << "XSD_UNUSED (t);"
+ << endl;
+
+ if (!restriction)
+ {
+ os << "if (this->";
+
+ if (c.inherits_p ())
+ os << fq_name (c.inherits ().base ());
+ else
+ os << complex_base;
+
+ os << "::_start_element_impl (ns, n, t))" << endl
+ << "return true;"
+ << endl;
+ }
+
+ names (c, names_start_element_);
+
+ os << "return false;"
+ << "}";
+
+
+ // _end_element_impl
+ //
+ os << "bool " << name << "::" << endl
+ << "_end_element_impl (const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n)"
+ << "{";
+
+ if (!restriction)
+ {
+ os << "if (this->";
+
+ if (c.inherits_p () && !restriction)
+ os << fq_name (c.inherits ().base ());
+ else
+ os << complex_base;
+
+ os << "::_end_element_impl (ns, n))" << endl
+ << "return true;"
+ << endl;
+ }
+
+ names (c, names_end_element_);
+
+ os << "return false;"
+ << "}";
+ }
+
+
+ if (ha)
+ {
+ // _attribute_impl
+ //
+ os << "bool " << name << "::" << endl
+ << "_attribute_impl (const " << string_type << "& ns," << endl
+ << "const " << string_type << "& n," << endl
+ << "const " << string_type << "& v)"
+ << "{";
+
+ if (!restriction)
+ {
+ os << "if (this->";
+
+ if (c.inherits_p ())
+ os << fq_name (c.inherits ().base ());
+ else
+ os << complex_base;
+
+ os << "::_attribute_impl (ns, n, v))" << endl
+ << "return true;"
+ << endl;
+ }
+
+ names (c, names_attribute_);
+
+ os << "return false;"
+ << "}";
+ }
+ }
+
+ private:
+ //
+ //
+ ParserCallback parser_callback_;
+ Traversal::Names names_parser_callback_;
+
+ //
+ //
+ StartElement start_element_;
+ Traversal::Names names_start_element_;
+
+ //
+ //
+ EndElement end_element_;
+ Traversal::Names names_end_element_;
+
+ //
+ //
+ Attribute attribute_;
+ Traversal::Names names_attribute_;
+ };
+
+
+ // Generate substitution group map entries.
+ //
+ struct GlobalElement: Traversal::Element,
+ protected virtual Context
+ {
+ GlobalElement (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (e.substitutes_p ())
+ {
+ String name (escape (e.name ()));
+ Type& r (e.substitutes ().root ());
+
+ SemanticGraph::Type& type (e.type ());
+
+ os << "// Substitution map entry for " << comment (e.name ()) << "." << endl
+ << "//" << endl
+ << "static" << endl
+ << "const ::xsd::cxx::parser::substitution_map_entry< " <<
+ char_type << " >" << endl
+ << "_xsd_" << name << "_substitution_map_entry_ (" << endl
+ << L << strlit (e.namespace_ ().name ()) << "," << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (r.namespace_ ().name ()) << "," << endl
+ << L << strlit (r.name ()) << "," << endl
+ << fq_name (type) << "::_static_type ());"
+ << endl;
+ }
+ }
+ };
+ }
+
+ Void
+ generate_parser_source (Context& ctx)
+ {
+ if (ctx.polymorphic)
+ {
+ ctx.os << "#include <xsd/cxx/parser/substitution-map.hxx>" << endl;
+
+ if (ctx.validation)
+ ctx.os << "#include <xsd/cxx/parser/validating/inheritance-map.hxx>" << endl
+ << endl;
+ else
+ ctx.os << endl;
+
+ Boolean import_maps (ctx.options.value<CLI::import_maps> ());
+ Boolean export_maps (ctx.options.value<CLI::export_maps> ());
+
+ if (import_maps || export_maps)
+ {
+ ctx.os << "#ifdef _MSC_VER" << endl
+ << endl
+ << "namespace xsd"
+ << "{"
+ << "namespace cxx"
+ << "{"
+ << "namespace parser"
+ << "{";
+
+ if (export_maps)
+ ctx.os << "template struct __declspec (dllexport) " <<
+ "substitution_map_init< " << ctx.char_type << " >;";
+
+ if (import_maps)
+ ctx.os << "template struct __declspec (dllimport) " <<
+ "substitution_map_init< " << ctx.char_type << " >;";
+
+ if (ctx.validation && export_maps)
+ ctx.os << "template struct __declspec (dllexport) " <<
+ "inheritance_map_init< " << ctx.char_type << " >;";
+
+ if (ctx.validation && import_maps)
+ ctx.os << "template struct __declspec (dllimport) " <<
+ "inheritance_map_init< " << ctx.char_type << " >;";
+
+ ctx.os << "}" // parser
+ << "}" // cxx
+ << "}" // xsd
+ << "#endif // _MSC_VER" << endl
+ << endl;
+ }
+
+ ctx.os << "static" << endl
+ << "const ::xsd::cxx::parser::substitution_map_init< " <<
+ ctx.char_type << " >" << endl
+ << "_xsd_substitution_map_init_;"
+ << endl;
+
+ if (ctx.validation)
+ {
+ ctx.os << "static" << endl
+ << "const ::xsd::cxx::parser::validating::inheritance_map_init< " <<
+ ctx.char_type << " >" << endl
+ << "_xsd_inheritance_map_init_;"
+ << endl;
+ }
+ }
+
+ // Emit "weak" header includes that are used in the file-per-type
+ // compilation model.
+ //
+ if (ctx.options.value<CLI::generate_inline> ())
+ {
+ Traversal::Schema schema;
+ Includes includes (ctx, Includes::source);
+
+ schema >> includes;
+ schema.dispatch (ctx.schema_root);
+ }
+
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+ Traversal::Names schema_names;
+
+ Namespace ns (ctx);
+ Traversal::Names names;
+
+ schema >> sources >> schema;
+ schema >> schema_names >> ns >> names;
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+ GlobalElement global_element (ctx);
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ if (ctx.polymorphic)
+ names >> global_element;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/parser/parser-source.hxx b/xsd/cxx/parser/parser-source.hxx
new file mode 100644
index 0000000..2281c24
--- /dev/null
+++ b/xsd/cxx/parser/parser-source.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/parser/parser-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_PARSER_SOURCE_HXX
+#define CXX_PARSER_PARSER_SOURCE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/parser/elements.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ Void
+ generate_parser_source (Context&);
+ }
+}
+
+#endif // CXX_PARSER_PARSER_SOURCE_HXX
diff --git a/xsd/cxx/parser/print-impl-common.hxx b/xsd/cxx/parser/print-impl-common.hxx
new file mode 100644
index 0000000..9e501ac
--- /dev/null
+++ b/xsd/cxx/parser/print-impl-common.hxx
@@ -0,0 +1,643 @@
+// file : xsd/cxx/parser/print-impl-common.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_PRINT_IMPL_COMMON_HXX
+#define CXX_PARSER_PRINT_IMPL_COMMON_HXX
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cxx/parser/elements.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ struct PrintCall: Traversal::Type,
+
+ Traversal::Fundamental::Boolean,
+
+ Traversal::Fundamental::Byte,
+ Traversal::Fundamental::UnsignedByte,
+ Traversal::Fundamental::Short,
+ Traversal::Fundamental::UnsignedShort,
+ Traversal::Fundamental::Int,
+ Traversal::Fundamental::UnsignedInt,
+ Traversal::Fundamental::Long,
+ Traversal::Fundamental::UnsignedLong,
+ Traversal::Fundamental::Integer,
+ Traversal::Fundamental::NonPositiveInteger,
+ Traversal::Fundamental::NonNegativeInteger,
+ Traversal::Fundamental::PositiveInteger,
+ Traversal::Fundamental::NegativeInteger,
+
+ Traversal::Fundamental::Float,
+ Traversal::Fundamental::Double,
+ Traversal::Fundamental::Decimal,
+
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NameTokens,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Language,
+
+ Traversal::Fundamental::QName,
+
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef,
+ Traversal::Fundamental::IdRefs,
+
+ Traversal::Fundamental::AnyURI,
+
+ Traversal::Fundamental::Base64Binary,
+ Traversal::Fundamental::HexBinary,
+
+ Traversal::Fundamental::Date,
+ Traversal::Fundamental::DateTime,
+ Traversal::Fundamental::Duration,
+ Traversal::Fundamental::Day,
+ Traversal::Fundamental::Month,
+ Traversal::Fundamental::MonthDay,
+ Traversal::Fundamental::Year,
+ Traversal::Fundamental::YearMonth,
+ Traversal::Fundamental::Time,
+
+ Context
+ {
+ PrintCall (Context& c, String const& tag, String const& arg)
+ : Context (c), tag_ (tag), arg_ (arg)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type&)
+ {
+ gen_user_type ();
+ }
+
+ // Boolean.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Boolean& t)
+ {
+ if (default_type (t, "bool"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ // Integral types.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Byte& t)
+ {
+ if (default_type (t, "signed char"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") <<
+ " << static_cast<short> (" << arg_ << ") << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedByte& t)
+ {
+ if (default_type (t, "unsigned char"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") <<
+ " << static_cast<unsigned short> (" << arg_ << ") << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Short& t)
+ {
+ if (default_type (t, "short"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedShort& t)
+ {
+ if (default_type (t, "unsigned short"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Int& t)
+ {
+ if (default_type (t, "int"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedInt& t)
+ {
+ if (default_type (t, "unsigned int"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Long& t)
+ {
+ if (default_type (t, "long long"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedLong& t)
+ {
+ if (default_type (t, "unsigned long long"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Integer& t)
+ {
+ if (default_type (t, "long long"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NegativeInteger& t)
+ {
+ if (default_type (t, "long long"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger& t)
+ {
+ if (default_type (t, "long long"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::PositiveInteger& t)
+ {
+ if (default_type (t, "unsigned long long"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger& t)
+ {
+ if (default_type (t, "unsigned long long"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ // Floats.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Float& t)
+ {
+ if (default_type (t, "float"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Double& t)
+ {
+ if (default_type (t, "double"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Decimal& t)
+ {
+ if (default_type (t, "double"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ // Strings.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String& t)
+ {
+ gen_string (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString& t)
+ {
+ gen_string (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token& t)
+ {
+ gen_string (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken& t)
+ {
+ gen_string (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name& t)
+ {
+ gen_string (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName& t)
+ {
+ gen_string (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Language& t)
+ {
+ gen_string (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id& t)
+ {
+ gen_string (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef& t)
+ {
+ gen_string (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::AnyURI& t)
+ {
+ gen_string (t);
+ }
+
+ // String sequences.
+ //
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameTokens& t)
+ {
+ gen_sequence (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRefs& t)
+ {
+ gen_sequence (t);
+ }
+
+ // QName
+ //
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::QName& t)
+ {
+ if (default_type (t, xs_ns_name () + L"::qname"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << ";"
+ << endl
+ << "if (" << arg_ << ".prefix ().empty ())" << endl
+ << cout_inst << " << " << arg_ << ".name ();"
+ << "else" << endl
+ << cout_inst << " << " << arg_ << ".prefix () << " << L <<
+ "':' << " << arg_ << ".name ();"
+ << endl
+ << cout_inst << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ // Binary.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Base64Binary& t)
+ {
+ gen_buffer (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::HexBinary& t)
+ {
+ gen_buffer (t);
+ }
+
+ // Date/time.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Date& t)
+ {
+ if (default_type (t, xs_ns_name () + L"::date"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << endl
+ << " << " << arg_ << ".year () << '-'" << endl
+ << " << " << arg_ << ".month () << '-'" << endl
+ << " << " << arg_ << ".day ();";
+
+ gen_time_zone ();
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::DateTime& t)
+ {
+ if (default_type (t, xs_ns_name () + L"::date_time"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << endl
+ << " << " << arg_ << ".year () << '-'" << endl
+ << " << " << arg_ << ".month () << '-'" << endl
+ << " << " << arg_ << ".day () << 'T'" << endl
+ << " << " << arg_ << ".hours () << ':'" << endl
+ << " << " << arg_ << ".minutes () << ':'" << endl
+ << " << " << arg_ << ".seconds ();";
+
+ gen_time_zone ();
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Duration& t)
+ {
+ if (default_type (t, xs_ns_name () + L"::duration"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << ";"
+ << endl
+ << "if (" << arg_ << ".negative ())" << endl
+ << cout_inst << " << '-';"
+ << endl
+ << cout_inst << " << 'P'" << endl
+ << " << " << arg_ << ".years () << 'Y'" << endl
+ << " << " << arg_ << ".months () << 'M'" << endl
+ << " << " << arg_ << ".days () << " << L << "\"DT\"" << endl
+ << " << " << arg_ << ".hours () << 'H'" << endl
+ << " << " << arg_ << ".minutes () << 'M'" << endl
+ << " << " << arg_ << ".seconds () << 'S'"
+ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Day& t)
+ {
+ if (default_type (t, xs_ns_name () + L"::gday"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ---") <<
+ " << " << arg_ << ".day ();";
+
+ gen_time_zone ();
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Month& t)
+ {
+ if (default_type (t, xs_ns_name () + L"::gmonth"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": --") <<
+ " << " << arg_ << ".month ();";
+
+ gen_time_zone ();
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::MonthDay& t)
+ {
+ if (default_type (t, xs_ns_name () + L"::gmonth_day"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": --") << endl
+ << " << " << arg_ << ".month () << '-'" << endl
+ << " << " << arg_ << ".day ();";
+
+ gen_time_zone ();
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Year& t)
+ {
+ if (default_type (t, xs_ns_name () + L"::gyear"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << ".year ();";
+
+ gen_time_zone ();
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::YearMonth& t)
+ {
+ if (default_type (t, xs_ns_name () + L"::gyear_month"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << endl
+ << " << " << arg_ << ".year () << '-'" << endl
+ << " << " << arg_ << ".month ();";
+
+ gen_time_zone ();
+ }
+ else
+ gen_user_type ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Time& t)
+ {
+ if (default_type (t, xs_ns_name () + L"::time"))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << endl
+ << " << " << arg_ << ".hours () << ':'" << endl
+ << " << " << arg_ << ".minutes () << ':'" << endl
+ << " << " << arg_ << ".seconds ();";
+
+ gen_time_zone ();
+ }
+ else
+ gen_user_type ();
+ }
+
+ private:
+ bool
+ default_type (SemanticGraph::Type& t, String const& def_type)
+ {
+ return ret_type (t) == def_type;
+ }
+
+ void
+ gen_user_type ()
+ {
+ os << "// TODO" << endl
+ << "//" << endl;
+ }
+
+ void
+ gen_string (SemanticGraph::Type& t)
+ {
+ if ((char_type == L"char" && default_type (t, "::std::string")) ||
+ (char_type == L"wchar_t" && default_type (t, "::std::wstring")))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << " <<
+ arg_ << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ void
+ gen_sequence (SemanticGraph::Type& t)
+ {
+ String type (xs_ns_name () + L"::string_sequence");
+
+ if (default_type (t, type))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << ";"
+ << endl;
+
+ os << "for (" << type << "::const_iterator i (" << arg_ <<
+ ".begin ()), e (" << arg_ << ".end ());" << endl
+ << "i != e;)"
+ << "{"
+ << cout_inst << " << *i++;"
+ << "if (i != e)" << endl
+ << cout_inst << " << ' ';"
+ << "}"
+ << cout_inst << " << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ void
+ gen_buffer (SemanticGraph::Type& t)
+ {
+ String type (L"::std::auto_ptr< " + xs_ns_name () + L"::buffer >");
+
+ if (default_type (t, type))
+ {
+ os << cout_inst << " << " << L << strlit (tag_ + L": ") << " << "
+ << arg_ << "->size () << " << L << "\" bytes\" << std::endl;";
+ }
+ else
+ gen_user_type ();
+ }
+
+ void
+ gen_time_zone ()
+ {
+ os << endl
+ << "if (" << arg_ << ".zone_present ())"
+ << "{"
+ << "if (" << arg_ << ".zone_hours () < 0)" << endl
+ << cout_inst << " << " << arg_ << ".zone_hours () << ':' << -" <<
+ arg_ << ".zone_minutes ();"
+ << "else" << endl
+ << cout_inst << " << '+' << " << arg_ << ".zone_hours () << " <<
+ "':' << " << arg_ << ".zone_minutes ();";
+
+ os << "}"
+ << cout_inst << " << std::endl;";
+ }
+
+ private:
+ String tag_;
+ String arg_;
+ };
+ }
+}
+
+#endif // CXX_PARSER_PRINT_IMPL_COMMON_HXX
diff --git a/xsd/cxx/parser/state-processor.cxx b/xsd/cxx/parser/state-processor.cxx
new file mode 100644
index 0000000..141ab05
--- /dev/null
+++ b/xsd/cxx/parser/state-processor.cxx
@@ -0,0 +1,318 @@
+// file : xsd/cxx/parser/state-processor.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/parser/state-processor.hxx>
+
+#include <cxx/parser/elements.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cult/containers/vector.hxx>
+
+#include <iostream>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace
+ {
+ typedef Cult::Containers::Vector<SemanticGraph::Particle*> Particles;
+
+ void
+ print (Particles const& p)
+ {
+ using std::wcerr;
+ using std::endl;
+
+ wcerr << "prefixes: " << endl;
+
+ for (Particles::ConstIterator i (p.begin ()); i != p.end (); ++i)
+ {
+ if (SemanticGraph::Element* e =
+ dynamic_cast<SemanticGraph::Element*> (*i))
+ {
+ wcerr << e->name () << endl;
+ }
+ else
+ {
+ wcerr << "<any>" << endl;
+ }
+ }
+
+ wcerr << endl;
+ }
+
+ //
+ //
+ struct Particle: Traversal::All,
+ Traversal::Choice,
+ Traversal::Sequence
+ {
+ Particle (UnsignedLong& all,
+ UnsignedLong& choice,
+ UnsignedLong& sequence,
+ UnsignedLong& depth)
+ : all_ (all),
+ choice_ (choice),
+ sequence_ (sequence),
+ depth_ (depth)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::All& a)
+ {
+ using SemanticGraph::Compositor;
+
+ // Go over particles, collecting "prefix" particles in prefixes_,
+ // assigning state numbers and calculating effective minOccurs.
+ // If all prefixes of this compositor have minOccurs = 0, then
+ // the compositor itself effectively has minOccurs = 0 regardless
+ // of the actual value specified in the schema.
+ //
+ // Note that we don't need to care about depth since the 'all'
+ // compositor cannot contain any nested compositors.
+ //
+
+ UnsignedLong state (0);
+ UnsignedLong min (0);
+
+ for (Compositor::ContainsIterator ci (a.contains_begin ());
+ ci != a.contains_end (); ++ci)
+ {
+ SemanticGraph::Particle& p (ci->particle ());
+
+ // The 'all' compositor can only include elements.
+ //
+ prefixes_.push_back (&p);
+
+ if (min == 0 && ci->min () != 0)
+ min = 1;
+
+ p.context ().set ("prefix", true);
+ p.context ().set ("state", state++);
+ }
+
+ if (!prefixes_.empty ())
+ {
+ a.context ().set ("comp-number", choice_++);
+ a.context ().set ("prefixes", prefixes_);
+ a.context ().set ("state-count", UnsignedLong (prefixes_.size ()));
+
+ // effective-min = min * actual-min
+ //
+ if (min == 1)
+ min = a.min ();
+
+ a.context ().set ("effective-min", min);
+
+ // print (prefixes_);
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Choice& c)
+ {
+ using SemanticGraph::Compositor;
+
+ // Go over particles, collecting "prefix" particles in prefixes_,
+ // assigning state numbers and calculating effective minOccurs.
+ // If any prefix of this compositor have minOccurs = 0, then the
+ // compositor itself effectively has minOccurs = 0 regardless of
+ // the actual value specified in the schema.
+ //
+
+ UnsignedLong state (0);
+ UnsignedLong min (1);
+
+ for (Compositor::ContainsIterator ci (c.contains_begin ());
+ ci != c.contains_end (); ++ci)
+ {
+ SemanticGraph::Particle& p (ci->particle ());
+
+ if (p.is_a<SemanticGraph::Element> () ||
+ p.is_a<SemanticGraph::Any> ())
+ {
+ prefixes_.push_back (&p);
+
+ if (min == 1 && ci->min () == 0)
+ min = 0;
+ }
+ else
+ {
+ UnsignedLong depth (0);
+ Particle t (all_, choice_, sequence_, depth);
+ t.dispatch (p);
+
+ if (t.prefixes_.empty ())
+ continue; // Skip empty compositors.
+
+ if (++depth > depth_) // One for this compositor.
+ depth_ = depth;
+
+ prefixes_.insert (prefixes_.end (),
+ t.prefixes_.begin ().base (),
+ t.prefixes_.end ().base ());
+
+ if (min == 1 &&
+ p.context ().get<UnsignedLong> ("effective-min") == 0)
+ min = 0;
+ }
+
+ p.context ().set ("prefix", true);
+ p.context ().set ("state", state++);
+ }
+
+ if (!prefixes_.empty ())
+ {
+ c.context ().set ("comp-number", choice_++);
+ c.context ().set ("prefixes", prefixes_);
+
+ // effective-min = min * actual-min
+ //
+ if (min == 1)
+ min = c.min ();
+
+ c.context ().set ("effective-min", min);
+
+ // print (prefixes_);
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Sequence& s)
+ {
+ using SemanticGraph::Compositor;
+
+ // Go over particles, collecting "prefix" particles in prefixes_,
+ // assigning state numbers and calculating effective minOccurs.
+ // If all prefixes of this compositor have minOccurs = 0, then
+ // the compositor itself effectively has minOccurs = 0 regardless
+ // of the actual value specified in the schema.
+ //
+
+ Boolean prefix (true);
+ UnsignedLong state (0);
+ UnsignedLong min (0);
+
+ for (Compositor::ContainsIterator ci (s.contains_begin ());
+ ci != s.contains_end (); ++ci)
+ {
+ SemanticGraph::Particle& p (ci->particle ());
+
+ if (p.is_a<SemanticGraph::Element> () ||
+ p.is_a<SemanticGraph::Any> ())
+ {
+ if (prefix)
+ {
+ prefixes_.push_back (&p);
+
+ if (ci->min () != 0)
+ min = 1;
+ }
+ }
+ else
+ {
+ UnsignedLong depth (0);
+ Particle t (all_, choice_, sequence_, depth);
+ t.dispatch (p);
+
+ if (t.prefixes_.empty ())
+ continue; // Skip empty compositors.
+
+ if (++depth > depth_) // One for this compositor.
+ depth_ = depth;
+
+ if (prefix)
+ {
+ prefixes_.insert (prefixes_.end (),
+ t.prefixes_.begin ().base (),
+ t.prefixes_.end ().base ());
+
+ if (p.context ().get<UnsignedLong> ("effective-min") != 0)
+ min = 1;
+ }
+ }
+
+ p.context ().set ("state", state++);
+
+ if (prefix)
+ p.context ().set ("prefix", true);
+
+ if (prefix && min != 0)
+ prefix = false;
+ }
+
+ if (!prefixes_.empty ())
+ {
+ s.context ().set ("comp-number", sequence_++);
+ s.context ().set ("prefixes", prefixes_);
+
+ // effective-min = min * actual-min
+ //
+ if (min == 1)
+ min = s.min ();
+
+ s.context ().set ("effective-min", min);
+
+ // print (prefixes_);
+ }
+ }
+
+ private:
+ Particles prefixes_;
+
+ UnsignedLong& all_;
+ UnsignedLong& choice_;
+ UnsignedLong& sequence_;
+
+ UnsignedLong& depth_;
+ };
+
+
+ //
+ //
+ struct Complex: Traversal::Complex
+ {
+ virtual Void
+ traverse (Type& c)
+ {
+ if (c.contains_compositor_p ())
+ {
+ UnsignedLong all (0), choice (0), sequence (0), depth (0);
+ Particle t (all, choice, sequence, depth);
+ t.dispatch (c.contains_compositor ().compositor ());
+
+ // Set the maximum stack depth for this type. Used to
+ // allocate fixed-size state stack.
+ //
+ c.context ().set ("depth", depth + 1);
+ }
+ }
+ };
+ }
+
+ Void StateProcessor::
+ process (SemanticGraph::Schema& tu, SemanticGraph::Path const&)
+ {
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+
+ schema >> sources >> schema;
+ schema >> schema_names >> ns >> ns_names;
+
+ Complex complex_type;
+
+ ns_names >> complex_type;
+
+ schema.dispatch (tu);
+ }
+ }
+}
diff --git a/xsd/cxx/parser/state-processor.hxx b/xsd/cxx/parser/state-processor.hxx
new file mode 100644
index 0000000..681959c
--- /dev/null
+++ b/xsd/cxx/parser/state-processor.hxx
@@ -0,0 +1,28 @@
+// file : xsd/cxx/parser/state-processor.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_STATE_PROCESSOR_HXX
+#define CXX_PARSER_STATE_PROCESSOR_HXX
+
+#include <cult/types.hxx>
+#include <xsd-frontend/semantic-graph.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ using namespace Cult::Types;
+
+ class StateProcessor
+ {
+ public:
+ Void
+ process (XSDFrontend::SemanticGraph::Schema&,
+ XSDFrontend::SemanticGraph::Path const& file);
+ };
+ }
+}
+
+#endif // CXX_PARSER_STATE_PROCESSOR_HXX
diff --git a/xsd/cxx/parser/type-processor.cxx b/xsd/cxx/parser/type-processor.cxx
new file mode 100644
index 0000000..3d24208
--- /dev/null
+++ b/xsd/cxx/parser/type-processor.cxx
@@ -0,0 +1,352 @@
+// file : xsd/cxx/parser/type-processor.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cult/containers/set.hxx>
+
+#include <cxx/parser/elements.hxx>
+#include <cxx/parser/type-processor.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ TypeProcessor::
+ TypeProcessor ()
+ {
+ // Dummy ctor, helps with long symbols on HP-UX.
+ }
+
+ namespace
+ {
+ //
+ //
+ struct Type: Traversal::Type
+ {
+ Type (SemanticGraph::Schema& schema,
+ TypeMap::Namespaces& type_map,
+ Boolean add_includes)
+ : schema_ (schema),
+ type_map_ (type_map),
+ add_includes_ (add_includes)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type& type)
+ {
+ using TypeMap::Namespace;
+ using TypeMap::Namespaces;
+
+ SemanticGraph::Context& tc (type.context ());
+
+ // There are two situations where we may try to process the
+ // same type more than once. The first is when the type is
+ // used in several element declarations in the same schema.
+ // The second situation only occurs when we are in the file-
+ // per-type mode. In this case the type was processed as part
+ // of another root schema. In the second case, while the ret
+ // and arg types are assumed to be the same, we need to re-
+ // match the type in order to add include directives to the
+ // new root schema.
+ //
+ Boolean set (true);
+
+ if (tc.count ("ret-type"))
+ {
+ SemanticGraph::Schema* s (
+ tc.get<SemanticGraph::Schema*> ("root-schema"));
+
+ if (&schema_ == s)
+ return;
+
+ set = false;
+ }
+
+ SemanticGraph::Namespace& ns (
+ dynamic_cast<SemanticGraph::Namespace&> (type.scope ()));
+
+ String ns_name (ns.name ());
+ String t_name (type.name ());
+
+ // std::wcerr << "traversing: " << ns_name << "#" << t_name << endl;
+
+ for (Namespaces::ConstIterator n (type_map_.begin ());
+ n != type_map_.end (); ++n)
+ {
+ // Check if the namespace matches.
+ //
+ Boolean ns_match;
+
+ if (!n->xsd_name ().empty ())
+ {
+ ns_match = n->xsd_name ().match (ns_name);
+ }
+ else
+ ns_match = ns_name.empty ();
+
+ // std::wcerr << "considering ns expr: " << n->xsd_name () << endl;
+
+ if (ns_match)
+ {
+ // Namespace matched. See if there is a type that matches.
+ //
+ for (Namespace::TypesIterator t (n->types_begin ());
+ t != n->types_end (); ++t)
+ {
+ if (t->xsd_name ().match (t_name))
+ {
+ if (set)
+ {
+ // Got a match. See if the namespace has the C++
+ // namespace mapping.
+ //
+ String cxx_ns;
+
+ if (n->has_cxx_name ())
+ {
+ if (!n->xsd_name ().empty ())
+ {
+ cxx_ns = n->xsd_name ().merge (
+ n->cxx_name (), ns_name, true);
+ }
+ else
+ cxx_ns = n->cxx_name ();
+
+ cxx_ns += L"::";
+ }
+
+ // Figure out ret and arg type names.
+ //
+ String ret_type (cxx_ns);
+
+ ret_type += t->xsd_name ().merge (
+ t->cxx_ret_name (), t_name, true);
+
+ String arg_type;
+
+ if (t->cxx_arg_name ())
+ {
+ arg_type = cxx_ns;
+ arg_type += t->xsd_name ().merge (
+ t->cxx_arg_name (), t_name, true);
+ }
+ else
+ {
+ if (ret_type == L"void")
+ arg_type = ret_type;
+ else
+ {
+ WideChar last (ret_type[ret_type.size () - 1]);
+
+ // If it is already a pointer or reference then use
+ // it as is.
+ //
+ if (last == L'*' || last == L'&')
+ arg_type = ret_type;
+ else
+ arg_type = L"const " + ret_type + L"&";
+ }
+ }
+
+ tc.set ("ret-type", ret_type);
+ tc.set ("arg-type", arg_type);
+ }
+
+ tc.set ("root-schema", &schema_);
+
+ //std::wcerr << t_name << " -> " << ret_type << endl;
+
+ // See of we need to add any includes to the translations
+ // unit.
+ //
+ if (add_includes_)
+ {
+ if (n->includes_begin () != n->includes_end ())
+ {
+ typedef Cult::Containers::Set<String> Includes;
+
+ if (!schema_.context ().count ("includes"))
+ schema_.context ().set ("includes", Includes ());
+
+ Includes& is (
+ schema_.context ().get<Includes> ("includes"));
+
+ for (Namespace::IncludesIterator i (n->includes_begin ());
+ i != n->includes_end (); ++i)
+ {
+ is.insert (*i);
+ }
+ }
+ }
+
+ return;
+ }
+ }
+ }
+ }
+ }
+
+ private:
+ SemanticGraph::Schema& schema_;
+ TypeMap::Namespaces& type_map_;
+ Boolean add_includes_;
+ };
+
+
+ //
+ //
+ struct GlobalType: Traversal::Type,
+ Traversal::List,
+ Traversal::Complex,
+ Traversal::Enumeration
+ {
+ GlobalType (SemanticGraph::Schema& schema,
+ TypeMap::Namespaces& type_map,
+ Boolean add_includes)
+ : type_ (schema, type_map, add_includes)
+ {
+ inherits_ >> type_;
+ names_ >> instance_ >> belongs_ >> type_;
+ argumented_ >> type_;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type& t)
+ {
+ type_.traverse (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::List& l)
+ {
+ type_.traverse (l);
+ Traversal::List::argumented (l, argumented_);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ type_.traverse (c);
+ Complex::inherits (c, inherits_);
+ Complex::names (c, names_);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Enumeration& e)
+ {
+ type_.traverse (e);
+ Complex::inherits (e, inherits_);
+ }
+
+ private:
+ Parser::Type type_;
+ Traversal::Names names_;
+ Traversal::Instance instance_;
+ Traversal::Inherits inherits_;
+ Traversal::Belongs belongs_;
+ Traversal::Argumented argumented_;
+ };
+
+ Void
+ process_impl (CLI::Options const& options,
+ XSDFrontend::SemanticGraph::Schema& tu,
+ Boolean gen_driver,
+ TypeMap::Namespaces& type_map)
+ {
+ if (tu.names_begin ()->named ().name () ==
+ L"http://www.w3.org/2001/XMLSchema")
+ {
+ // XML Schema namespace.
+ //
+ Traversal::Schema schema;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ GlobalType global_type (tu, type_map, true);
+
+ schema >> schema_names >> ns >> ns_names >> global_type;
+
+ schema.dispatch (tu);
+ }
+ else
+ {
+ // If --extern-xml-schema is specified, then we don't want
+ // includes from the XML Schema type map.
+ //
+ Boolean extern_xml_schema (
+ options.value<CLI::extern_xml_schema> ());
+
+ //
+ //
+ Traversal::Schema schema;
+ Traversal::Schema xs_schema;
+ Traversal::Sources sources;
+ Traversal::Implies implies;
+
+ schema >> sources >> schema;
+ schema >> implies >> xs_schema;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ GlobalType global_type (tu, type_map, true);
+
+ schema >> schema_names >> ns >> ns_names >> global_type;
+
+ Traversal::Names xs_schema_names;
+ Traversal::Namespace xs_ns;
+ Traversal::Names xs_ns_names;
+ GlobalType xs_global_type (tu, type_map, !extern_xml_schema);
+
+ xs_schema >> xs_schema_names >> xs_ns >> xs_ns_names >>
+ xs_global_type;
+
+ schema.dispatch (tu);
+
+ // If we are generating the test driver, make sure the root
+ // element type is processed.
+ //
+ if (gen_driver && options.value<CLI::generate_test_driver> ())
+ {
+ // Figure out the root element. Validator should have made sure
+ // it is unique.
+ //
+ SemanticGraph::Element* root (0);
+ {
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+
+ schema >> sources >> schema;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ RootElement root_element (options, root);
+
+ schema >> schema_names >> ns >> ns_names >> root_element;
+
+ schema.dispatch (tu);
+ }
+
+ global_type.dispatch (root->type ());
+ }
+ }
+ }
+ }
+
+ Void TypeProcessor::
+ process (CLI::Options const& options,
+ XSDFrontend::SemanticGraph::Schema& s,
+ Boolean gen_driver,
+ TypeMap::Namespaces& tm)
+ {
+ process_impl (options, s, gen_driver, tm);
+ }
+ }
+}
diff --git a/xsd/cxx/parser/type-processor.hxx b/xsd/cxx/parser/type-processor.hxx
new file mode 100644
index 0000000..045b331
--- /dev/null
+++ b/xsd/cxx/parser/type-processor.hxx
@@ -0,0 +1,37 @@
+// file : xsd/cxx/parser/type-processor.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_TYPE_PROCESSOR_HXX
+#define CXX_PARSER_TYPE_PROCESSOR_HXX
+
+#include <cult/types.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+
+#include <type-map/type-map.hxx>
+
+#include <cxx/parser/cli.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ using namespace Cult::Types;
+
+ class TypeProcessor
+ {
+ public:
+ TypeProcessor (); // Dummy ctor, helps with long symbols on HP-UX.
+
+ Void
+ process (CLI::Options const& options,
+ XSDFrontend::SemanticGraph::Schema&,
+ Boolean gen_driver,
+ TypeMap::Namespaces&);
+ };
+ }
+}
+
+#endif // CXX_PARSER_TYPE_PROCESSOR_HXX
diff --git a/xsd/cxx/parser/validator.cxx b/xsd/cxx/parser/validator.cxx
new file mode 100644
index 0000000..8d6b968
--- /dev/null
+++ b/xsd/cxx/parser/validator.cxx
@@ -0,0 +1,714 @@
+// file : xsd/cxx/parser/validator.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/parser/validator.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cxx/parser/elements.hxx>
+
+#include <iostream>
+
+using std::wcerr;
+
+namespace CXX
+{
+ namespace Parser
+ {
+ namespace
+ {
+ class ValidationContext: public Context
+ {
+ public:
+ ValidationContext (SemanticGraph::Schema& root,
+ CLI::Options const& options,
+ const WarningSet& disabled_warnings,
+ Boolean& valid_)
+ : Context (std::wcerr, root, options, 0, 0, 0),
+ disabled_warnings_ (disabled_warnings),
+ disabled_warnings_all_ (false),
+ valid (valid_),
+ subst_group_warning_issued (subst_group_warning_issued_),
+ subst_group_warning_issued_ (false)
+ {
+ }
+
+ public:
+ Boolean
+ is_disabled (Char const* w)
+ {
+ return disabled_warnings_all_ ||
+ disabled_warnings_.find (w) != disabled_warnings_.end ();
+ }
+
+ public:
+ String
+ xpath (SemanticGraph::Nameable& n)
+ {
+ if (n.is_a<SemanticGraph::Namespace> ())
+ return L"<namespace-level>"; // There is a bug if you see this.
+
+ assert (n.named ());
+
+ SemanticGraph::Scope& scope (n.scope ());
+
+ if (scope.is_a<SemanticGraph::Namespace> ())
+ return n.name ();
+
+ return xpath (scope) + L"/" + n.name ();
+ }
+
+ protected:
+ ValidationContext (ValidationContext& c)
+ : Context (c),
+ disabled_warnings_ (c.disabled_warnings_),
+ disabled_warnings_all_ (c.disabled_warnings_all_),
+ valid (c.valid),
+ subst_group_warning_issued (c.subst_group_warning_issued)
+ {
+ }
+
+ protected:
+ const WarningSet& disabled_warnings_;
+ Boolean disabled_warnings_all_;
+ Boolean& valid;
+ Boolean& subst_group_warning_issued;
+ Boolean subst_group_warning_issued_;
+ };
+
+ //
+ //
+ struct Any : Traversal::Any, protected virtual ValidationContext
+ {
+ Any (ValidationContext& c)
+ : ValidationContext (c)
+ {
+ }
+
+ struct Element: Traversal::Element,
+ protected virtual ValidationContext
+ {
+ Element (ValidationContext& c, SemanticGraph::Any& any)
+ : ValidationContext (c),
+ any_ (any),
+ ns_ (any.definition_namespace ().name ())
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ if (skip (e)) return;
+
+ using SemanticGraph::Any;
+
+ Boolean q (e.qualified ());
+ String ns (q ? e.namespace_ ().name () : "");
+
+ for (Any::NamespaceIterator i (any_.namespace_begin ());
+ i != any_.namespace_end (); ++i)
+ {
+ Boolean failed (false);
+
+ if (*i == L"##any")
+ {
+ failed = true;
+ }
+ else if (*i == L"##other")
+ {
+ if (ns_)
+ {
+ // Note that here I assume that ##other does not
+ // include names without target namespace. This
+ // is not what the spec says but that seems to be
+ // the consensus.
+ //
+ failed = q && ns != ns_;
+ }
+ else
+ {
+ // No target namespace.
+ //
+ failed = q && ns != L"";
+ }
+ }
+ else if (*i == L"##local")
+ {
+ failed = !q || ns == L"";
+ }
+ else if (*i == L"##targetNamespace")
+ {
+ failed = (q && ns_ == ns) || (!q && ns_ == L"");
+ }
+ else
+ {
+ failed = q && *i == ns;
+ }
+
+ if (failed)
+ {
+ Any& a (any_);
+
+ os << a.file () << ":" << a.line () << ":" << a.column ()
+ << ": warning P001: namespace '" << *i << "' allows for "
+ << "element '" << e.name () << "'" << endl;
+
+ os << a.file () << ":" << a.line () << ":" << a.column ()
+ << ": warning P001: generated code may not associate element '"
+ << e.name () << "' correctly if it appears in place of "
+ << "this wildcard" << endl;
+
+ os << e.file () << ":" << e.line () << ":" << e.column ()
+ << ": info: element '" << e.name () << "' is defined "
+ << "here" << endl;
+
+ os << a.file () << ":" << a.line () << ":" << a.column ()
+ << ": info: turn on validation to ensure correct "
+ << "association" << endl;
+ }
+ }
+ }
+
+ private:
+ SemanticGraph::Any& any_;
+ String ns_;
+ };
+
+ struct Complex: Traversal::Complex
+ {
+ Complex ()
+ : up_ (true), down_ (true)
+ {
+ }
+
+ virtual Void
+ post (Type& c)
+ {
+ // Go down the inheritance hierarchy.
+ //
+ if (down_)
+ {
+ Boolean up = up_;
+ up_ = false;
+
+ if (c.inherits_p ())
+ dispatch (c.inherits ().base ());
+
+ up_ = up;
+ }
+
+ // Go up the inheritance hierarchy.
+ //
+ if (up_)
+ {
+ Boolean down = down_;
+ down_ = false;
+
+ for (Type::BegetsIterator i (c.begets_begin ());
+ i != c.begets_end (); ++i)
+ {
+ dispatch (i->derived ());
+ }
+
+ down_ = down;
+ }
+ }
+
+ private:
+ Boolean up_, down_;
+ };
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ using SemanticGraph::Compositor;
+
+ // Find our complex type.
+ //
+ Compositor* c (&a.contained_particle ().compositor ());
+
+ while(!c->contained_compositor_p ())
+ c = &c->contained_particle ().compositor ();
+
+ SemanticGraph::Complex& type (
+ dynamic_cast<SemanticGraph::Complex&> (
+ c->contained_compositor ().container ()));
+
+ Complex complex;
+ Traversal::Names names;
+ Element element (*this, a);
+
+ complex >> names >> element;
+
+ complex.dispatch (type);
+ }
+ };
+
+
+ //
+ //
+ struct Traverser : Traversal::Schema,
+ Traversal::Complex,
+ Traversal::Type,
+ Traversal::Element,
+ protected virtual ValidationContext
+ {
+ Traverser (ValidationContext& c)
+ : ValidationContext (c),
+ any_ (c)
+ {
+ *this >> sources_ >> *this;
+ *this >> schema_names_ >> ns_ >> names_ >> *this;
+
+ // Any
+ //
+ if (!validation && !is_disabled ("P001"))
+ {
+ *this >> contains_compositor_ >> compositor_ >> contains_particle_;
+ contains_particle_ >> compositor_;
+ contains_particle_ >> any_;
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ using SemanticGraph::Schema;
+
+ traverse (static_cast<SemanticGraph::Type&> (c));
+
+ if (c.inherits_p ())
+ {
+ SemanticGraph::Type& t (c.inherits ().base ());
+
+ if (t.named () &&
+ types_.find (
+ t.scope ().name () + L"#" + t.name ()) == types_.end ())
+ {
+ // Don't worry about types that are in included/imported
+ // schemas.
+ //
+ Schema& s (dynamic_cast<Schema&> (t.scope ().scope ()));
+
+ if (&s == &schema_root || sources_p (schema_root, s))
+ {
+ valid = false;
+
+ wcerr << c.file () << ":" << c.line () << ":" << c.column ()
+ << ": error: type '" << xpath (c) << "' inherits from "
+ << "yet undefined type '" << xpath (t) << "'" << endl;
+
+ wcerr << t.file () << ":" << t.line () << ":" << t.column ()
+ << ": info: '" << xpath (t) << "' is defined here"
+ << endl;
+
+ wcerr << c.file () << ":" << c.line () << ":" << c.column ()
+ << ": info: inheritance from a yet-undefined type is "
+ << "not supported" << endl;
+
+ wcerr << c.file () << ":" << c.line () << ":" << c.column ()
+ << ": info: re-arrange your schema and try again"
+ << endl;
+ }
+ }
+ }
+
+ Complex::traverse (c);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type& t)
+ {
+ if (t.named ())
+ {
+ types_.insert (t.scope ().name () + L"#" + t.name ());
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ if (is_disabled ("P002"))
+ return;
+
+ if (e.substitutes_p () &&
+ !options.value<CLI::generate_polymorphic> () &&
+ !subst_group_warning_issued)
+ {
+ subst_group_warning_issued = true;
+
+ os << e.file () << ":" << e.line () << ":" << e.column ()
+ << ": warning P002: substitution groups are used but "
+ << "--generate-polymorphic was not specified" << endl;
+
+ os << e.file () << ":" << e.line () << ":" << e.column ()
+ << ": info: generated code may not be able to parse "
+ << "some conforming instances" << endl;
+ }
+ }
+
+ // Return true if root sources s.
+ //
+ Boolean
+ sources_p (SemanticGraph::Schema& root, SemanticGraph::Schema& s)
+ {
+ using SemanticGraph::Schema;
+ using SemanticGraph::Sources;
+
+ for (Schema::UsesIterator i (root.uses_begin ());
+ i != root.uses_end (); ++i)
+ {
+ if (i->is_a<Sources> ())
+ {
+ if (&i->schema () == &s || sources_p (i->schema (), s))
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private:
+ Containers::Set<String> types_;
+
+ Traversal::Sources sources_;
+
+ Traversal::Names schema_names_;
+ Traversal::Namespace ns_;
+
+ Traversal::Names names_;
+
+ // Any.
+ //
+ Any any_;
+ Traversal::Compositor compositor_;
+ Traversal::ContainsParticle contains_particle_;
+ Traversal::ContainsCompositor contains_compositor_;
+ };
+
+
+ struct AnonymousType : Traversal::Schema,
+ Traversal::Complex,
+ Traversal::Element,
+ Traversal::Attribute,
+ protected virtual ValidationContext
+ {
+ AnonymousType (ValidationContext& c)
+ : ValidationContext (c),
+ anonymous_error_issued_ (false)
+ {
+ *this >> sources_ >> *this;
+ *this >> schema_names_ >> ns_ >> names_ >> *this;
+ *this >> names_;
+ }
+
+ Boolean
+ traverse_common (SemanticGraph::Member& m)
+ {
+ SemanticGraph::Type& t (m.type ());
+
+ if (!t.named ()
+ && !t.is_a<SemanticGraph::Fundamental::IdRef> ()
+ && !t.is_a<SemanticGraph::Fundamental::IdRefs> ())
+ {
+ if (!anonymous_error_issued_)
+ {
+ valid = false;
+ anonymous_error_issued_ = true;
+
+ wcerr << t.file ()
+ << ": error: anonymous types detected"
+ << endl;
+
+ wcerr << t.file ()
+ << ": info: "
+ << "anonymous types are not supported in this mapping"
+ << endl;
+
+ wcerr << t.file ()
+ << ": info: consider explicitly naming these types or "
+ << "remove the --preserve-anonymous option to "
+ << "automatically name them"
+ << endl;
+
+ if (!options.value<CLI::show_anonymous> ())
+ wcerr << t.file ()
+ << ": info: use --show-anonymous option to see these "
+ << "types" << endl;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ if (skip (e)) return;
+
+ if (traverse_common (e))
+ {
+ if (options.value<CLI::show_anonymous> ())
+ {
+ wcerr << e.file () << ":" << e.line () << ":" << e.column ()
+ << ": error: element '" << xpath (e) << "' "
+ << "is of anonymous type" << endl;
+ }
+ }
+ else
+ Traversal::Element::traverse (e);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Attribute& a)
+ {
+ if (traverse_common (a))
+ {
+ if (options.value<CLI::show_anonymous> ())
+ {
+ wcerr << a.file () << ":" << a.line () << ":" << a.column ()
+ << ": error: attribute '" << xpath (a) << "' "
+ << "is of anonymous type" << endl;
+ }
+ }
+ else
+ Traversal::Attribute::traverse (a);
+ }
+
+ private:
+ Boolean anonymous_error_issued_;
+
+ Containers::Set<String> types_;
+
+ Traversal::Sources sources_;
+
+ Traversal::Names schema_names_;
+ Traversal::Namespace ns_;
+
+ Traversal::Names names_;
+ };
+
+ struct GlobalElement: Traversal::Element, ValidationContext
+ {
+ GlobalElement (ValidationContext& c, SemanticGraph::Element*& element)
+ : ValidationContext (c), element_ (element)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (!valid)
+ return;
+
+ if (options.value<CLI::root_element_first> ())
+ {
+ if (element_ == 0)
+ element_ = &e;
+ }
+ else if (options.value<CLI::root_element_last> ())
+ {
+ element_ = &e;
+ }
+ else if (String name = options.value<CLI::root_element> ())
+ {
+ if (e.name () == name)
+ element_ = &e;
+ }
+ else
+ {
+ if (element_ == 0)
+ element_ = &e;
+ else
+ {
+ wcerr << schema_root.file () << ": error: unable to generate "
+ << "the test driver without a unique document root"
+ << endl;
+
+ wcerr << schema_root.file () << ": info: use --root-element-* "
+ << "options to specify the document root" << endl;
+
+ valid = false;
+ }
+ }
+ }
+
+ private:
+ SemanticGraph::Element*& element_;
+ };
+
+ }
+
+ Validator::
+ Validator ()
+ {
+ // Dummy ctor, helps with long symbols on HP-UX.
+ }
+
+ Boolean Validator::
+ validate (CLI::Options const& options,
+ SemanticGraph::Schema& root,
+ SemanticGraph::Path const&,
+ Boolean gen_driver,
+ const WarningSet& disabled_warnings)
+ {
+ Boolean valid (true);
+ ValidationContext ctx (root, options, disabled_warnings, valid);
+
+ //
+ //
+ if (options.value<CLI::char_type> () != "char" &&
+ options.value<CLI::char_type> () != "wchar_t" &&
+ !ctx.is_disabled ("P003"))
+ {
+ wcerr << "warning P003: unknown base character type '" <<
+ options.value<CLI::char_type> ().c_str () << "'" << endl;
+ }
+
+ //
+ //
+ if (options.value<CLI::xml_parser> () != "xerces" &&
+ options.value<CLI::xml_parser> () != "expat" &&
+ !ctx.is_disabled ("P004"))
+ {
+ wcerr << "warning P004: unknown underlying XML parser '" <<
+ options.value<CLI::xml_parser> ().c_str () << "'" << endl;
+ }
+
+ //
+ //
+ if (options.value<CLI::xml_parser> () == "expat" &&
+ options.value<CLI::char_type> () == "wchar_t")
+ {
+ wcerr << "error: using expat with wchar_t is not yet supported"
+ << endl;
+
+ return false;
+ }
+
+ //
+ //
+ if (options.value<CLI::generate_validation> () &&
+ options.value<CLI::suppress_validation> ())
+ {
+ wcerr << "error: mutually exclusive options specified: "
+ << "--generate-validation and --suppress-validation"
+ << endl;
+
+ return false;
+ }
+
+ //
+ //
+ if (options.value<CLI::generate_noop_impl> () &&
+ options.value<CLI::generate_print_impl> ())
+ {
+ wcerr << "error: mutually exclusive options specified: "
+ << "--generate-noop-impl and --generate-print-impl"
+ << endl;
+
+ return false;
+ }
+
+ //
+ //
+ {
+ Boolean ref (options.value<CLI::root_element_first> ());
+ Boolean rel (options.value<CLI::root_element_last> ());
+ Boolean re (options.value<CLI::root_element> ());
+
+ if ((ref && rel) || (ref && re) || (rel && re))
+ {
+ wcerr << "error: mutually exclusive options specified: "
+ << "--root-element-last, --root-element-first, and "
+ << "--root-element"
+ << endl;
+
+ return false;
+ }
+ }
+
+ //
+ //
+ Boolean import_maps (options.value<CLI::import_maps> ());
+ Boolean export_maps (options.value<CLI::export_maps> ());
+
+ if (import_maps && export_maps)
+ {
+ wcerr << "error: --import-maps and --export-maps are "
+ << "mutually exclusive" << endl;
+
+ return false;
+ }
+
+ if (import_maps && !ctx.polymorphic)
+ {
+ wcerr << "error: --import-maps can only be specified together with "
+ << "--generate-polymorphic" << endl;
+
+ return false;
+ }
+
+ if (export_maps && !ctx.polymorphic)
+ {
+ wcerr << "error: --export-maps can only be specified together with "
+ << "--generate-polymorphic" << endl;
+
+ return false;
+ }
+
+ // Test for anonymout types.
+ //
+ {
+ AnonymousType traverser (ctx);
+ traverser.dispatch (root);
+ }
+
+
+ // Test the rest.
+ //
+ if (valid)
+ {
+ Traverser traverser (ctx);
+ traverser.dispatch (root);
+ }
+
+ // Test that the document root is unique.
+ //
+ if (valid && gen_driver)
+ {
+ SemanticGraph::Element* element (0);
+
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+
+ schema >> sources >> schema;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ GlobalElement global_element (ctx, element);
+
+ schema >> schema_names >> ns >> ns_names >> global_element;
+
+ schema.dispatch (root);
+
+ if (valid && element == 0)
+ {
+ wcerr << root.file () << ": error: unable to generate the "
+ << "test driver without a global element (document root)"
+ << endl;
+
+ valid = false;
+ }
+ }
+
+ return valid;
+ }
+ }
+}
diff --git a/xsd/cxx/parser/validator.hxx b/xsd/cxx/parser/validator.hxx
new file mode 100644
index 0000000..3f10073
--- /dev/null
+++ b/xsd/cxx/parser/validator.hxx
@@ -0,0 +1,35 @@
+// file : xsd/cxx/parser/validator.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_PARSER_VALIDATOR_HXX
+#define CXX_PARSER_VALIDATOR_HXX
+
+#include <cxx/parser/elements.hxx>
+#include <cxx/parser/cli.hxx>
+
+#include <xsd.hxx>
+
+namespace CXX
+{
+ namespace Parser
+ {
+ using namespace Cult::Types;
+
+ class Validator
+ {
+ public:
+ Validator (); // Dummy ctor, helps with long symbols on HP-UX.
+
+ Boolean
+ validate (CLI::Options const& options,
+ SemanticGraph::Schema&,
+ SemanticGraph::Path const& tu,
+ Boolean gen_driver,
+ const WarningSet& disabled_warnings);
+ };
+ }
+}
+
+#endif // CXX_PARSER_VALIDATOR_HXX
diff --git a/xsd/cxx/tree/cli.hxx b/xsd/cxx/tree/cli.hxx
new file mode 100644
index 0000000..9ccf405
--- /dev/null
+++ b/xsd/cxx/tree/cli.hxx
@@ -0,0 +1,220 @@
+// file : xsd/cxx/tree/cli.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_CLI_HXX
+#define CXX_TREE_CLI_HXX
+
+#include <cult/types.hxx>
+
+#include <cult/containers/vector.hxx>
+
+#include <cult/cli/options.hxx>
+#include <cult/cli/options-spec.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace CLI
+ {
+ using namespace Cult::Types;
+
+ typedef Char const Key[];
+
+ extern Key char_type;
+ extern Key output_dir;
+ extern Key generate_polymorphic;
+ extern Key generate_serialization;
+ extern Key generate_inline;
+ extern Key generate_ostream;
+ extern Key generate_doxygen;
+ extern Key generate_comparison;
+ extern Key generate_default_ctor;
+ extern Key generate_from_base_ctor;
+ extern Key generate_wildcard;
+ extern Key generate_insertion;
+ extern Key generate_extraction;
+ extern Key generate_forward;
+ extern Key generate_xml_schema;
+ extern Key extern_xml_schema;
+ extern Key suppress_parsing;
+ extern Key generate_element_type;
+ extern Key generate_element_map;
+ extern Key generate_intellisense;
+ extern Key omit_default_attributes;
+ extern Key namespace_map;
+ extern Key namespace_regex;
+ extern Key namespace_regex_trace;
+ extern Key reserved_name;
+ extern Key type_naming;
+ extern Key function_naming;
+ extern Key type_regex;
+ extern Key accessor_regex;
+ extern Key one_accessor_regex;
+ extern Key opt_accessor_regex;
+ extern Key seq_accessor_regex;
+ extern Key modifier_regex;
+ extern Key one_modifier_regex;
+ extern Key opt_modifier_regex;
+ extern Key seq_modifier_regex;
+ extern Key parser_regex;
+ extern Key serializer_regex;
+ extern Key enumerator_regex;
+ extern Key element_type_regex;
+ extern Key name_regex_trace;
+ extern Key include_with_brackets;
+ extern Key include_prefix;
+ extern Key include_regex;
+ extern Key include_regex_trace;
+ extern Key guard_prefix;
+ extern Key root_element_first;
+ extern Key root_element_last;
+ extern Key root_element_all;
+ extern Key root_element_none;
+ extern Key root_element;
+ extern Key custom_type;
+ extern Key custom_type_regex;
+ extern Key hxx_suffix;
+ extern Key ixx_suffix;
+ extern Key cxx_suffix;
+ extern Key fwd_suffix;
+ extern Key hxx_regex;
+ extern Key ixx_regex;
+ extern Key cxx_regex;
+ extern Key fwd_regex;
+ extern Key hxx_prologue;
+ extern Key ixx_prologue;
+ extern Key cxx_prologue;
+ extern Key fwd_prologue;
+ extern Key prologue;
+ extern Key hxx_epilogue;
+ extern Key ixx_epilogue;
+ extern Key cxx_epilogue;
+ extern Key fwd_epilogue;
+ extern Key epilogue;
+ extern Key hxx_prologue_file;
+ extern Key ixx_prologue_file;
+ extern Key cxx_prologue_file;
+ extern Key fwd_prologue_file;
+ extern Key prologue_file;
+ extern Key hxx_epilogue_file;
+ extern Key ixx_epilogue_file;
+ extern Key cxx_epilogue_file;
+ extern Key fwd_epilogue_file;
+ extern Key epilogue_file;
+ extern Key parts;
+ extern Key parts_suffix;
+ extern Key export_symbol;
+ extern Key export_xml_schema;
+ extern Key export_maps;
+ extern Key import_maps;
+ extern Key show_anonymous;
+ extern Key show_sloc;
+ extern Key proprietary_license;
+ extern Key disable_multi_import; // Undocumented.
+
+
+ typedef Cult::CLI::Options<
+
+ char_type, NarrowString,
+ output_dir, NarrowString,
+ generate_polymorphic, Boolean,
+ generate_serialization, Boolean,
+ generate_inline, Boolean,
+ generate_ostream, Boolean,
+ generate_doxygen, Boolean,
+ generate_comparison, Boolean,
+ generate_default_ctor, Boolean,
+ generate_from_base_ctor, Boolean,
+ generate_wildcard, Boolean,
+ generate_insertion, Cult::Containers::Vector<NarrowString>,
+ generate_extraction, Cult::Containers::Vector<NarrowString>,
+ generate_forward, Boolean,
+ generate_xml_schema, Boolean,
+ extern_xml_schema, NarrowString,
+ suppress_parsing, Boolean,
+ generate_element_type, Boolean,
+ generate_element_map, Boolean,
+ generate_intellisense, Boolean,
+ omit_default_attributes, Boolean,
+ namespace_map, Cult::Containers::Vector<NarrowString>,
+ namespace_regex, Cult::Containers::Vector<NarrowString>,
+ namespace_regex_trace, Boolean,
+ reserved_name, Cult::Containers::Vector<NarrowString>,
+ type_naming, NarrowString,
+ function_naming, NarrowString,
+ type_regex, Cult::Containers::Vector<NarrowString>,
+ accessor_regex, Cult::Containers::Vector<NarrowString>,
+ one_accessor_regex, Cult::Containers::Vector<NarrowString>,
+ opt_accessor_regex, Cult::Containers::Vector<NarrowString>,
+ seq_accessor_regex, Cult::Containers::Vector<NarrowString>,
+ modifier_regex, Cult::Containers::Vector<NarrowString>,
+ one_modifier_regex, Cult::Containers::Vector<NarrowString>,
+ opt_modifier_regex, Cult::Containers::Vector<NarrowString>,
+ seq_modifier_regex, Cult::Containers::Vector<NarrowString>,
+ parser_regex, Cult::Containers::Vector<NarrowString>,
+ serializer_regex, Cult::Containers::Vector<NarrowString>,
+ enumerator_regex, Cult::Containers::Vector<NarrowString>,
+ element_type_regex, Cult::Containers::Vector<NarrowString>,
+ name_regex_trace, Boolean,
+ include_with_brackets, Boolean,
+ include_prefix, NarrowString,
+ include_regex, Cult::Containers::Vector<NarrowString>,
+ include_regex_trace, Boolean,
+ guard_prefix, NarrowString,
+ root_element_first, Boolean,
+ root_element_last, Boolean,
+ root_element_all, Boolean,
+ root_element_none, Boolean,
+ root_element, Cult::Containers::Vector<NarrowString>,
+ custom_type, Cult::Containers::Vector<NarrowString>,
+ custom_type_regex, Cult::Containers::Vector<NarrowString>,
+ hxx_suffix, NarrowString,
+ ixx_suffix, NarrowString,
+ cxx_suffix, NarrowString,
+ fwd_suffix, NarrowString,
+ hxx_regex, NarrowString,
+ ixx_regex, NarrowString,
+ cxx_regex, NarrowString,
+ fwd_regex, NarrowString,
+ hxx_prologue, Cult::Containers::Vector<NarrowString>,
+ ixx_prologue, Cult::Containers::Vector<NarrowString>,
+ cxx_prologue, Cult::Containers::Vector<NarrowString>,
+ fwd_prologue, Cult::Containers::Vector<NarrowString>,
+ prologue, Cult::Containers::Vector<NarrowString>,
+ hxx_epilogue, Cult::Containers::Vector<NarrowString>,
+ ixx_epilogue, Cult::Containers::Vector<NarrowString>,
+ cxx_epilogue, Cult::Containers::Vector<NarrowString>,
+ fwd_epilogue, Cult::Containers::Vector<NarrowString>,
+ epilogue, Cult::Containers::Vector<NarrowString>,
+ hxx_prologue_file, NarrowString,
+ ixx_prologue_file, NarrowString,
+ cxx_prologue_file, NarrowString,
+ fwd_prologue_file, NarrowString,
+ prologue_file, NarrowString,
+ hxx_epilogue_file, NarrowString,
+ ixx_epilogue_file, NarrowString,
+ cxx_epilogue_file, NarrowString,
+ fwd_epilogue_file, NarrowString,
+ epilogue_file, NarrowString,
+ parts, UnsignedLong,
+ parts_suffix, NarrowString,
+ export_symbol, NarrowString,
+ export_xml_schema, Boolean,
+ export_maps, Boolean,
+ import_maps, Boolean,
+ show_anonymous, Boolean,
+ show_sloc, Boolean,
+ proprietary_license, Boolean,
+ disable_multi_import, Boolean
+
+ > Options;
+
+ struct OptionsSpec: Cult::CLI::OptionsSpec<Options> {};
+ }
+ }
+}
+
+#endif // CXX_TREE_CLI_HXX
diff --git a/xsd/cxx/tree/counter.cxx b/xsd/cxx/tree/counter.cxx
new file mode 100644
index 0000000..d8223bb
--- /dev/null
+++ b/xsd/cxx/tree/counter.cxx
@@ -0,0 +1,265 @@
+// file : xsd/cxx/tree/counter.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/counter.hxx>
+
+#include <iostream>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ struct Member: Traversal::Member
+ {
+ Member (UnsignedLong& complexity)
+ : complexity_ (complexity)
+ {
+ }
+
+ virtual Void
+ traverse (Type&)
+ {
+ complexity_++;
+ }
+
+ UnsignedLong& complexity_;
+ };
+
+ struct Any: Traversal::Any, Traversal::AnyAttribute
+ {
+ Any (UnsignedLong& complexity)
+ : complexity_ (complexity)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any&)
+ {
+ complexity_++;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute&)
+ {
+ complexity_++;
+ }
+
+ UnsignedLong& complexity_;
+ };
+
+ struct TypeBase: Traversal::List,
+ Traversal::Union,
+ Traversal::Enumeration,
+ Traversal::Complex,
+ Context
+ {
+ TypeBase (Context& c, UnsignedLong& complexity)
+ : Context (c), complexity_ (complexity)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::List&)
+ {
+ complexity_++;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Union&)
+ {
+ complexity_++;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Enumeration& e)
+ {
+ Boolean string_based (false);
+ {
+ IsStringBasedType t (string_based);
+ t.dispatch (e);
+ }
+
+ complexity_ += (string_based ? 1 : 2);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ complexity_++; // One for the type itself.
+
+ // Plus some for each member.
+ //
+ Any any (complexity_);
+ Member member (complexity_);
+ Traversal::Names names;
+
+ names >> member;
+
+ if (options.value<CLI::generate_wildcard> ())
+ names >> any;
+
+ Complex::names (c, names);
+ }
+
+ private:
+ UnsignedLong& complexity_;
+ };
+
+
+ //
+ //
+ struct GlobalType: Traversal::Type, Context
+
+ {
+ GlobalType (Context& c, Counts& counts)
+ : Context (c), counts_ (counts)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type& t)
+ {
+ counts_.global_types++;
+
+ UnsignedLong complexity (0);
+ TypeBase type (*this, complexity);
+ type.dispatch (t);
+
+ counts_.complexity_total += complexity;
+ counts_.complexity.push_back (complexity);
+ }
+
+ private:
+ Counts& counts_;
+ };
+
+ //
+ //
+ struct GlobalElement: Traversal::Element,
+ GlobalElementBase,
+ Context
+ {
+ GlobalElement (Context& c, Counts& counts)
+ : GlobalElementBase (c),
+ Context (c),
+ counts_ (counts),
+ last_ (0)
+ {
+ }
+
+ ~GlobalElement ()
+ {
+ if (last_ != 0)
+ {
+ last_->context ().set ("last", true);
+ count_last ();
+ }
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ // Check if the previous element we saw needs to be generated.
+ //
+ if (last_ != 0)
+ count_last ();
+
+ last_ = &e;
+
+ if (counts_.global_elements == 0)
+ e.context ().set ("first", true);
+
+ counts_.global_elements++;
+ }
+
+ private:
+ Void
+ count_last ()
+ {
+ if (generate_p (*last_))
+ {
+ counts_.generated_global_elements++;
+
+ UnsignedLong complexity (0);
+
+ if (doc_root_p (*last_))
+ {
+ if (options.value<CLI::generate_element_type> ())
+ {
+ complexity += 1; // For c-tors and d-tor.
+
+ if (!options.value<CLI::suppress_parsing> ())
+ complexity += 1;
+
+ if (options.value<CLI::generate_serialization> ())
+ complexity += 1;
+ }
+ else
+ {
+ if (!options.value<CLI::suppress_parsing> ())
+ complexity += 6; // 13 parsing functions.
+
+ if (options.value<CLI::generate_serialization> ())
+ complexity += 4; // 8 serialization functions.
+ }
+ }
+
+ if (complexity == 0)
+ {
+ // This element must be a substitution group members. For
+ // such elements we are only generating an entry in a map.
+ // We will assign it a complexity of 1 so that we don't
+ // end up with the total complexity that is less than the
+ // number of elements and types.
+ //
+ complexity = 1;
+ }
+
+ counts_.complexity_total += complexity;
+ counts_.complexity.push_back (complexity);
+ }
+ }
+
+ private:
+ Counts& counts_;
+ SemanticGraph::Element* last_;
+ };
+ }
+
+ Counter::
+ Counter ()
+ {
+ }
+
+ Counts Counter::
+ count (CLI::Options const& options, SemanticGraph::Schema& tu)
+ {
+ Counts counts;
+ Context ctx (std::wcerr, tu, options, counts, false, 0, 0, 0);
+
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+
+ schema >> sources >> schema;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ GlobalType global_type (ctx, counts);
+ GlobalElement global_element (ctx, counts);
+
+ schema >> schema_names >> ns >> ns_names;
+
+ ns_names >> global_element;
+ ns_names >> global_type;
+
+ schema.dispatch (tu);
+
+ return counts;
+ }
+ }
+}
diff --git a/xsd/cxx/tree/counter.hxx b/xsd/cxx/tree/counter.hxx
new file mode 100644
index 0000000..f4186ba
--- /dev/null
+++ b/xsd/cxx/tree/counter.hxx
@@ -0,0 +1,28 @@
+// file : xsd/cxx/tree/counter.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_COUNTER_HXX
+#define CXX_TREE_COUNTER_HXX
+
+#include <cxx/tree/elements.hxx>
+#include <cxx/tree/cli.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ class Counter
+ {
+ public:
+ Counter (); // Dummy ctor, helps with long symbols on HP-UX.
+
+ Counts
+ count (CLI::Options const& options,
+ SemanticGraph::Schema&);
+ };
+ }
+}
+
+#endif // CXX_TREE_COUNTER_HXX
diff --git a/xsd/cxx/tree/elements.cxx b/xsd/cxx/tree/elements.cxx
new file mode 100644
index 0000000..5e85087
--- /dev/null
+++ b/xsd/cxx/tree/elements.cxx
@@ -0,0 +1,1327 @@
+// file : xsd/cxx/tree/elements.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ // Context
+ //
+ Void Context::
+ update_ns_scope () // Keeping this function first helps HP-UX
+ { // (long symbols).
+ ns_scope.clear ();
+
+ Boolean first (true);
+
+ for (NamespaceStack::Iterator i (ns_scope_stack.begin ());
+ i != ns_scope_stack.end ();
+ ++i)
+ {
+ // We only qualify names until the namespace level.
+ //
+ if (first)
+ first = false;
+ else
+ ns_scope += L"::";
+
+ ns_scope += *i;
+ }
+ }
+
+ Context::
+ Context (std::wostream& o,
+ SemanticGraph::Schema& root,
+ CLI::Options const& ops,
+ Counts const& counts_,
+ Boolean generate_xml_schema__,
+ Regex const* fe,
+ Regex const* he,
+ Regex const* ie)
+ : CXX::Context (o,
+ root,
+ ops.value<CLI::char_type> (),
+ ops.value<CLI::include_with_brackets> (),
+ ops.value<CLI::include_prefix> (),
+ ops.value<CLI::export_symbol> (),
+ ops.value<CLI::namespace_map> (),
+ ops.value<CLI::namespace_regex> (),
+ ops.value<CLI::namespace_regex_trace> (),
+ ops.value<CLI::include_regex> (),
+ ops.value<CLI::include_regex_trace> (),
+ ops.value<CLI::generate_inline> (),
+ ops.value<CLI::reserved_name> ()),
+ options (ops),
+ counts (counts_),
+ any_type (any_type_),
+ any_simple_type (any_simple_type_),
+ element_type (element_type_),
+ container (container_),
+ flags_type (flags_type_),
+ qname_type (qname_type_),
+ xs_string_type (xs_string_type_),
+ properties_type (properties_type_),
+ error_handler_type (error_handler_type_),
+ list_stream_type (list_stream_type_),
+ namespace_infomap_type (namespace_infomap_type_),
+ parser_type (parser_type_),
+ std_ostream_type (std_ostream_type_),
+ ostream_type (ostream_type_),
+ istream_type (istream_type_),
+ xerces_ns (xerces_ns_),
+ dom_auto_ptr (dom_auto_ptr_),
+ dom_node_key (dom_node_key_),
+ as_double_type (as_double_type_),
+ as_decimal_type (as_decimal_type_),
+ generate_xml_schema (generate_xml_schema_),
+ doxygen (doxygen_),
+ polymorphic (ops.value<CLI::generate_polymorphic> ()),
+ fwd_expr (fe),
+ hxx_expr (he),
+ ixx_expr (ie),
+ ns_scope (ns_scope_),
+ regex_custom_type_map (regex_custom_type_map_),
+ direct_custom_type_map (direct_custom_type_map_),
+ qname_type_ (L"::xsd::cxx::xml::qualified_name< " + char_type + L" >"),
+ parser_type_ (L"::xsd::cxx::xml::dom::parser< " + char_type + L" >"),
+ generate_xml_schema_ (generate_xml_schema__),
+ doxygen_ (ops.value<CLI::generate_doxygen> ()),
+ ns_scope_stack (ns_scope_stack_),
+ cxx_uq_id_expr_ (L"^[a-zA-Z_]\\w*$"),
+ cxx_uq_id_expr (cxx_uq_id_expr_)
+ {
+ SemanticGraph::Namespace& xs (xs_ns ());
+ SemanticGraph::Context& xsc (xs.context ());
+
+ // Cache some often-used names from the XML Schema namespace
+ // if names have already been processed.
+ //
+ if (xsc.count ("container"))
+ {
+ String xs_name (ns_name (xs));
+
+ any_type = fq_name (xs.find ("anyType").first->named ());
+ any_simple_type = fq_name (xs.find ("anySimpleType").first->named ());
+ xs_string_type = fq_name (xs.find ("string").first->named ());
+
+ container = xs_name + L"::" + xsc.get<String> ("container");
+ flags_type = xs_name + L"::" + xsc.get<String> ("flags");
+
+ if (ops.value<CLI::generate_element_type> ())
+ element_type = xs_name + L"::" + xsc.get<String> ("element-type");
+
+ properties_type = xs_name + L"::" + xsc.get<String> ("properties");
+
+ if (!ops.value<CLI::suppress_parsing> () ||
+ ops.value<CLI::generate_serialization> ())
+ {
+ error_handler_type = xs_name + L"::" +
+ xsc.get<String> ("error-handler");
+ }
+
+ dom_auto_ptr_ = xs_name + L"::dom::auto_ptr";
+ dom_node_key_ = xs_name + L"::dom::" +
+ xsc.get<String> ("tree-node-key");
+
+ if (ops.value<CLI::generate_serialization> ())
+ {
+ as_double_type_ = xs_name + L"::" +
+ xsc.get<String> ("as-double");
+
+ as_decimal_type_ = xs_name + L"::" +
+ xsc.get<String> ("as-decimal");
+
+ list_stream_type = xs_name + L"::" +
+ xsc.get<String> ("list-stream");
+
+ namespace_infomap_type = xs_name + L"::" +
+ xsc.get<String> ("namespace-infomap");
+ }
+
+ // istream and ostream are templates and for now use the same
+ // names regardless of the naming convention.
+ //
+ if (!ops.value<CLI::generate_extraction> ().empty ())
+ istream_type = xs_name + L"::istream";
+
+ if (!ops.value<CLI::generate_insertion> ().empty ())
+ ostream_type = xs_name + L"::ostream";
+ }
+
+ // Xerces-C++ namespace. IntelliSense for some reason does not like
+ // it fully-qualified (maybe because it's a namespace alias).
+ //
+ if (ops.value<CLI::generate_intellisense> ())
+ xerces_ns = "xercesc";
+ else
+ xerces_ns = "::xercesc";
+
+ //
+ //
+ if (char_type == L"char")
+ std_ostream_type_ = L"::std::ostream";
+ else if (char_type == L"wchar_t")
+ std_ostream_type_ = L"::std::wostream";
+ else
+ std_ostream_type_ = L"::std::basic_ostream< " + char_type + L" >";
+
+ // Custom type mapping.
+ //
+ typedef Containers::Vector<NarrowString> Vector;
+
+ // Direct custom type mapping.
+ //
+ {
+ Vector const& v (ops.value<CLI::custom_type> ());
+
+ for (Vector::ConstIterator i (v.begin ()), e (v.end ()); i != e; ++i)
+ {
+ String s (*i);
+
+ if (s.empty ())
+ throw InvalidCustomTypeMapping (s, "mapping string is empty");
+
+ // Split the string in two parts at the last '='.
+ //
+ Size pos (s.rfind ('='));
+
+ // If no delimiter found then both type and base are empty.
+ //
+ if (pos == String::npos)
+ {
+ direct_custom_type_map[s].type.clear ();
+ direct_custom_type_map[s].base.clear ();
+ continue;
+ }
+
+ String name (s, 0, pos);
+ String rest (s, pos + 1);
+
+ // See if we've got the base part after '/'.
+ //
+ pos = rest.rfind ('/');
+
+ String type, base;
+
+ if (pos != String::npos)
+ {
+ type.assign (rest, 0, pos);
+ base.assign (rest, pos + 1, String::npos);
+ }
+ else
+ type = rest;
+
+ // type can be a potentially-qualified template-id. base is
+ // an unqualified C++ name.
+ //
+
+ if (!base.empty () && !cxx_uq_id_expr.match (base))
+ throw InvalidCustomTypeMapping (s, "invalid C++ identifier");
+
+ direct_custom_type_map[name].type = type;
+ direct_custom_type_map[name].base = base;
+ }
+ }
+
+ // Regex custom type mapping.
+ //
+ {
+ Vector const& v (ops.value<CLI::custom_type_regex> ());
+
+ for (Vector::ConstIterator i (v.begin ()), e (v.end ()); i != e; ++i)
+ {
+ String s (*i);
+
+ if (s.empty ())
+ throw InvalidCustomTypeMapping (s, "mapping string is empty");
+
+ WideChar delimiter (s[0]);
+
+ // First get pattern.
+ //
+ Size pos (s.find (delimiter, 1));
+
+ if (pos == String::npos)
+ throw InvalidCustomTypeMapping (
+ s, "missing pattern-substitution separator");
+
+ String pat (s, 1, pos - 1);
+ String rest (s, pos + 1);
+
+ String type, base;
+
+ // See if we've got type and base.
+ //
+ if (!rest.empty ())
+ {
+ pos = rest.find (delimiter);
+
+ if (pos == String::npos)
+ throw InvalidCustomTypeMapping (
+ s, "missing pattern-substitution separator");
+
+ type.assign (rest, 0, pos);
+ rest = String (rest, pos + 1);
+
+ if (!rest.empty ())
+ {
+ pos = rest.find (delimiter);
+
+ if (pos == String::npos)
+ throw InvalidCustomTypeMapping (
+ s, "missing pattern-substitution separator");
+
+ base.assign (rest, 0, pos);
+ rest = String (rest, pos + 1);
+
+ if (!rest.empty ())
+ throw InvalidCustomTypeMapping (s, "invalid format");
+ }
+ }
+
+ regex_custom_type_map.push_back (
+ RegexCustomTypeMapInfo (pat, type, base));
+ }
+ }
+ }
+
+ Context::
+ Context (Context& c)
+ : CXX::Context (c),
+ options (c.options),
+ counts (c.counts),
+ any_type (c.any_type),
+ any_simple_type (c.any_simple_type),
+ element_type (c.element_type),
+ container (c.container),
+ flags_type (c.flags_type),
+ qname_type (c.qname_type),
+ xs_string_type (c.xs_string_type),
+ properties_type (c.properties_type),
+ error_handler_type (c.error_handler_type),
+ list_stream_type (c.list_stream_type),
+ namespace_infomap_type (c.namespace_infomap_type),
+ parser_type (c.parser_type),
+ std_ostream_type (c.std_ostream_type),
+ ostream_type (c.ostream_type),
+ istream_type (c.istream_type),
+ xerces_ns (c.xerces_ns),
+ dom_auto_ptr (c.dom_auto_ptr),
+ dom_node_key (c.dom_node_key),
+ as_double_type (c.as_double_type),
+ as_decimal_type (c.as_decimal_type),
+ generate_xml_schema (c.generate_xml_schema),
+ doxygen (c.doxygen),
+ polymorphic (c.polymorphic),
+ fwd_expr (c.fwd_expr),
+ hxx_expr (c.hxx_expr),
+ ixx_expr (c.ixx_expr),
+ ns_scope (c.ns_scope),
+ regex_custom_type_map (c.regex_custom_type_map),
+ direct_custom_type_map (c.direct_custom_type_map),
+ ns_scope_stack (c.ns_scope_stack),
+ cxx_uq_id_expr (c.cxx_uq_id_expr)
+ {
+ }
+
+ Context::
+ Context (Context& c, std::wostream& o)
+ : CXX::Context (c, o),
+ options (c.options),
+ counts (c.counts),
+ any_type (c.any_type),
+ any_simple_type (c.any_simple_type),
+ element_type (c.element_type),
+ container (c.container),
+ flags_type (c.flags_type),
+ qname_type (c.qname_type),
+ xs_string_type (c.xs_string_type),
+ properties_type (c.properties_type),
+ error_handler_type (c.error_handler_type),
+ list_stream_type (c.list_stream_type),
+ namespace_infomap_type (c.namespace_infomap_type),
+ parser_type (c.parser_type),
+ std_ostream_type (c.std_ostream_type),
+ ostream_type (c.ostream_type),
+ istream_type (c.istream_type),
+ xerces_ns (c.xerces_ns),
+ dom_auto_ptr (c.dom_auto_ptr),
+ dom_node_key (c.dom_node_key),
+ as_double_type (c.as_double_type),
+ as_decimal_type (c.as_decimal_type),
+ generate_xml_schema (c.generate_xml_schema),
+ doxygen (c.doxygen),
+ polymorphic (c.polymorphic),
+ fwd_expr (c.fwd_expr),
+ hxx_expr (c.hxx_expr),
+ ixx_expr (c.ixx_expr),
+ ns_scope (c.ns_scope),
+ regex_custom_type_map (c.regex_custom_type_map),
+ direct_custom_type_map (c.direct_custom_type_map),
+ ns_scope_stack (c.ns_scope_stack),
+ cxx_uq_id_expr (c.cxx_uq_id_expr)
+ {
+ }
+
+ Boolean Context::
+ custom_type (SemanticGraph::Type const& t, String& r) const
+ {
+ String const& name (t.name ());
+
+ // First search the direct mapping.
+ //
+ {
+ DirectCustomTypeMap::ConstIterator i (
+ direct_custom_type_map.find (name));
+
+ if (i != direct_custom_type_map.end ())
+ {
+ r = i->second.type;
+ return true;
+ }
+ }
+
+
+ // Second search the regex mapping.
+ //
+ for (RegexCustomTypeMap::ConstIterator
+ i (regex_custom_type_map.begin ()),
+ e (regex_custom_type_map.end ());
+ i != e; ++i)
+ {
+ if (i->pat.match (name))
+ {
+ // Empty type sub tells us to use the original name.
+ //
+ if (i->type_sub.empty ())
+ {
+ r.clear ();
+ return true;
+ }
+
+ r = i->pat.merge (name, i->type_sub);
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ String Context::
+ custom_type (SemanticGraph::Type const& t) const
+ {
+ String r;
+ if (custom_type (t, r))
+ {
+ // Empty type name tells us to use the original name.
+ //
+ if (r.empty ())
+ r = ename (t);
+ }
+
+ return r;
+ }
+
+ Boolean Context::
+ renamed_type (SemanticGraph::Type const& t, String& r) const
+ {
+ String const& name (t.name ());
+
+ // First search the direct mapping.
+ //
+ {
+ DirectCustomTypeMap::ConstIterator i (
+ direct_custom_type_map.find (name));
+
+ if (i != direct_custom_type_map.end ())
+ {
+ r = i->second.base;
+ return true;
+ }
+ }
+
+
+ // Second search the regex mapping.
+ //
+ for (RegexCustomTypeMap::ConstIterator
+ i (regex_custom_type_map.begin ()),
+ e (regex_custom_type_map.end ());
+ i != e; ++i)
+ {
+ if (i->pat.match (name))
+ {
+ if (!i->base_sub.empty ())
+ {
+ r = i->pat.merge (name, i->base_sub);
+ }
+ else
+ r.clear ();
+
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ Boolean Context::
+ is_qname (SemanticGraph::Type& t)
+ {
+ using SemanticGraph::Complex;
+ using SemanticGraph::Fundamental::QName;
+
+ if (t.is_a<QName> ())
+ return true;
+
+ if (Complex* c = dynamic_cast<Complex*> (&t))
+ {
+ if (c->inherits_p () && ultimate_base (*c).is_a<QName> ())
+ return true;
+ }
+
+ return false;
+ }
+
+
+ Void Context::
+ write_annotation (SemanticGraph::Annotation& a)
+ {
+ String const& doc (a.documentation ());
+ WideChar const* s (doc.c_str ());
+ Size size (doc.size ());
+
+ // Remove leading and trailing whitespaces.
+ //
+ while (*s == WideChar (0x20) || *s == WideChar (0x0A) ||
+ *s == WideChar (0x0D) || *s == WideChar (0x09))
+ {
+ s++;
+ size--;
+ }
+
+ if (size != 0)
+ {
+ WideChar const* e (s + size - 1);
+
+ while (e > s &&
+ (*e == WideChar (0x20) || *e == WideChar (0x0A) ||
+ *e == WideChar (0x0D) || *e == WideChar (0x09)))
+ --e;
+
+ size = s <= e ? e - s + 1 : 0;
+ }
+
+ if (size != 0)
+ {
+ os << " * ";
+
+ // Go over the data, forcing newline after 80 chars and adding
+ // ' * ' after each new line.
+ //
+ WideChar const* last_space (0);
+ WideChar const* b (s);
+ WideChar const* e (s);
+ Boolean after_newline (false);
+ Boolean rogue (false);
+
+ for (; e < s + size; ++e)
+ {
+ UnsignedLong u (unicode_char (e)); // May advance e.
+
+ // We are going to treat \v and \f as rogue here even though
+ // they can be present in C++ source code.
+ //
+ if (u > 127 || (u < 32 && u != '\t' && u != '\n'))
+ rogue = true;
+
+ if (u == ' ' || u == '\t')
+ {
+ if (after_newline)
+ {
+ if (e == b)
+ b++; // Skip leading spaces after newline.
+
+ continue;
+ }
+ else
+ last_space = e;
+ }
+ else if (after_newline)
+ {
+ os << " * ";
+ after_newline = false;
+ }
+
+ if (u == '\n')
+ {
+ write_rogue_text (b, e - b + 1, rogue);
+
+ b = e + 1;
+ last_space = 0;
+ after_newline = true;
+ rogue = false;
+ continue;
+ }
+
+ if (e - b >= 70 && last_space != 0)
+ {
+ write_rogue_text (b, last_space - b, rogue);
+ os << endl;
+
+ b = last_space + 1;
+ last_space = 0;
+ after_newline = true;
+ // Cannot reset rogue since we don't output the whole string.
+ }
+ }
+
+ if (e != b)
+ write_rogue_text (b, e - b, rogue);
+
+ if (!after_newline)
+ os << endl;
+ }
+ }
+
+ Void Context::
+ write_rogue_text (WideChar const* s, Size size, Boolean rogue)
+ {
+ if (!rogue)
+ os.write (s, size);
+ else
+ {
+ for (WideChar const* p (s); p < s + size; ++p)
+ {
+ UnsignedLong u (unicode_char (p)); // May advance p.
+
+ // We are going to treat \v and \f as rogue here even though
+ // they can be present in C++ source code.
+ //
+ if (u > 127 || (u < 32 && u != '\t' && u != '\n'))
+ os.put ('?');
+ else
+ os.put (static_cast<WideChar> (u));
+ }
+ }
+ }
+
+ // GenerateDefautCtor
+ //
+ GenerateDefaultCtor::
+ GenerateDefaultCtor (Context& c, Boolean& generate, Boolean no_base)
+ : Context (c), generate_ (generate), no_base_ (no_base)
+ {
+ *this >> inherits_ >> *this;
+ *this >> names_ >> *this;
+ }
+
+ Void GenerateDefaultCtor::
+ traverse (SemanticGraph::Complex& c)
+ {
+ // Make sure we figure out if we have any required members before
+ // we base our decision on the base type.
+ //
+ Complex::names (c, names_);
+
+ if (!generate_)
+ Complex::inherits (c, inherits_);
+ }
+
+ Void GenerateDefaultCtor::
+ traverse (SemanticGraph::Type&)
+ {
+ if (!no_base_)
+ generate_ = true;
+ }
+
+ Void GenerateDefaultCtor::
+ traverse (SemanticGraph::Enumeration&)
+ {
+ if (!no_base_)
+ generate_ = true;
+ }
+
+ Void GenerateDefaultCtor::
+ traverse (SemanticGraph::Element& e)
+ {
+ if (!skip (e) && min (e) == 1 && max (e) == 1)
+ generate_ = true;
+ }
+
+ Void GenerateDefaultCtor::
+ traverse (SemanticGraph::Attribute& a)
+ {
+ if (min (a) == 1 && !(a.fixed () && !is_qname (a.type ())))
+ generate_ = true;
+ }
+
+ Void GenerateDefaultCtor::
+ traverse (SemanticGraph::Any& a)
+ {
+ if (options.value<CLI::generate_wildcard> () &&
+ min (a) == 1 && max (a) == 1)
+ generate_ = true;
+ }
+
+
+ // GenerateFromBaseCtor
+ //
+ GenerateFromBaseCtor::
+ GenerateFromBaseCtor (Context& c, Boolean& generate)
+ : traverser_ (c, generate)
+ {
+ inherits_ >> traverser_;
+ }
+
+ Void GenerateFromBaseCtor::
+ traverse (SemanticGraph::Complex& c)
+ {
+ inherits (c, inherits_);
+ }
+
+ GenerateFromBaseCtor::Traverser::
+ Traverser (Context& c, Boolean& generate)
+ : Context (c), generate_ (generate)
+ {
+ *this >> inherits_ >> *this;
+ *this >> names_ >> *this;
+ }
+
+ Void GenerateFromBaseCtor::Traverser::
+ traverse (SemanticGraph::Complex& c)
+ {
+ names (c, names_);
+
+ if (!generate_)
+ inherits (c, inherits_);
+ }
+
+ Void GenerateFromBaseCtor::Traverser::
+ traverse (SemanticGraph::Element& e)
+ {
+ if (!skip (e) && min (e) == 1 && max (e) == 1)
+ generate_ = true;
+ }
+
+ Void GenerateFromBaseCtor::Traverser::
+ traverse (SemanticGraph::Attribute& a)
+ {
+ if (min (a) == 1 && !(a.fixed () && !is_qname (a.type ())))
+ generate_ = true;
+ }
+
+ Void GenerateFromBaseCtor::Traverser::
+ traverse (SemanticGraph::Any& a)
+ {
+ if (options.value<CLI::generate_wildcard> () &&
+ min (a) == 1 && max (a) == 1)
+ generate_ = true;
+ }
+
+ // HasComplexNonOptArgs
+ //
+ HasComplexNonFundNonOptArgs::
+ HasComplexNonFundNonOptArgs (Context& c,
+ Boolean base,
+ Boolean& complex,
+ Boolean& non_fund,
+ Boolean& clash)
+ : Context (c),
+ complex_ (complex),
+ non_fund_ (non_fund),
+ clash_ (clash)
+ {
+ if (base)
+ *this >> inherits_ >> *this;
+
+ *this >> names_ >> *this;
+ }
+
+ Void HasComplexNonFundNonOptArgs::
+ traverse (SemanticGraph::Complex& c)
+ {
+ // No optimizations: need to check every arg for clashes.
+ //
+ inherits (c, inherits_);
+ names (c, names_);
+ }
+
+ Void HasComplexNonFundNonOptArgs::
+ traverse (SemanticGraph::Element& e)
+ {
+ if (!skip (e) && min (e) == 1 && max (e) == 1)
+ {
+ Boolean fund (false);
+ IsFundamentalType t (fund);
+ t.dispatch (e.type ());
+
+ if (!fund)
+ {
+ non_fund_ = true;
+
+ Boolean simple (true);
+ IsSimpleType t (simple);
+ t.dispatch (e.type ());
+
+ if (!simple)
+ complex_ = true;
+ else
+ clash_ = false;
+ }
+ }
+ }
+
+ // FromBaseCtorArg
+ //
+ FromBaseCtorArg::
+ FromBaseCtorArg (Context& c, ArgType at, Boolean arg)
+ : Context (c), arg_type_ (at), arg_ (arg)
+ {
+ }
+
+ Void FromBaseCtorArg::
+ traverse (SemanticGraph::Any& a)
+ {
+ if (!options.value<CLI::generate_wildcard> ())
+ return;
+
+ if (min (a) == 1 && max (a) == 1)
+ {
+ String const& name (ename (a));
+
+ os << "," << endl
+ << "const " << xerces_ns << "::DOMElement&";
+
+ if (arg_)
+ os << " " << name;
+ }
+ }
+
+ Void FromBaseCtorArg::
+ traverse (SemanticGraph::Element& e)
+ {
+ if (skip (e))
+ return;
+
+ if (min (e) == 1 && max (e) == 1)
+ {
+ String const& name (ename (e));
+
+ os << "," << endl;
+
+ Boolean auto_ptr (false);
+
+ switch (arg_type_)
+ {
+ case arg_complex_auto_ptr:
+ {
+ Boolean simple (true);
+ IsSimpleType t (simple);
+ t.dispatch (e.type ());
+ auto_ptr = !simple;
+ break;
+ }
+ case arg_non_fund_auto_ptr:
+ {
+ Boolean fund (false);
+ IsFundamentalType t (fund);
+ t.dispatch (e.type ());
+ auto_ptr = !fund;
+ break;
+ }
+ case arg_type:
+ break;
+ }
+
+ if (auto_ptr)
+ os << "::std::auto_ptr< " << etype (e) << " >&";
+ else
+ os << "const " << etype (e) << "&";
+
+ if (arg_)
+ os << " " << name;
+ }
+ }
+
+ Void FromBaseCtorArg::
+ traverse (SemanticGraph::Attribute& a)
+ {
+ // Note that we are not going to include attributes with
+ // default or required fixed values here. Instead we are
+ // going to default-initialize them.
+ //
+ if (min (a) == 1 && !(a.fixed () && !is_qname (a.type ())))
+ {
+ String const& name (ename (a));
+
+ os << "," << endl
+ << "const " << etype (a) << "&";
+
+ if (arg_)
+ os << " " << name;
+ }
+ }
+
+ // CtorArgs
+ //
+ CtorArgs::
+ CtorArgs (Context& c, ArgType at)
+ : Context (c),
+ arg_type_ (at),
+ base_arg_ (0),
+ first_ (true),
+ member_name_ (c)
+ {
+ *this >> inherits_ >> *this;
+ *this >> names_ >> *this;
+ }
+
+ CtorArgs::
+ CtorArgs (Context& c, ArgType at, String& base_arg)
+ : Context (c),
+ arg_type_ (at),
+ base_arg_ (&base_arg),
+ first_ (true),
+ member_name_ (c)
+ {
+ *this >> inherits_ >> *this;
+ *this >> names_ >> *this;
+ }
+
+ Void CtorArgs::
+ traverse (SemanticGraph::Type& t)
+ {
+ os << comma () << "const ";
+
+ member_name_.dispatch (t);
+
+ os << "&";
+
+ if (base_arg_ != 0)
+ {
+ *base_arg_ = L"_xsd_" + ename (t) + L"_base";
+
+ os << " " << *base_arg_;
+ }
+ }
+
+ Void CtorArgs::
+ traverse (SemanticGraph::Enumeration& e)
+ {
+ os << comma () << "const ";
+
+ member_name_.traverse (e);
+
+ os << "&";
+
+ if (base_arg_ != 0)
+ {
+ *base_arg_ = L"_xsd_" + ename (e) + L"_base";
+
+ os << " " << *base_arg_;
+ }
+ }
+
+ Void CtorArgs::
+ traverse (SemanticGraph::Any& a)
+ {
+ if (!options.value<CLI::generate_wildcard> ())
+ return;
+
+ if (min (a) == 1 && max (a) == 1)
+ {
+ os << comma () << "const " << xerces_ns << "::DOMElement&";
+
+ if (base_arg_ != 0)
+ os << " " << ename (a);
+ }
+ }
+
+ Void CtorArgs::
+ traverse (SemanticGraph::Element& e)
+ {
+ if (skip (e))
+ return;
+
+ if (min (e) == 1 && max (e) == 1)
+ {
+ Boolean auto_ptr (false);
+
+ switch (arg_type_)
+ {
+ case arg_complex_auto_ptr:
+ {
+ Boolean simple (true);
+ IsSimpleType t (simple);
+ t.dispatch (e.type ());
+ auto_ptr = !simple;
+ break;
+ }
+ case arg_non_fund_auto_ptr:
+ {
+ Boolean fund (false);
+ IsFundamentalType t (fund);
+ t.dispatch (e.type ());
+ auto_ptr = !fund;
+ break;
+ }
+ case arg_type:
+ break;
+ }
+
+ if (auto_ptr)
+ os << comma () << "::std::auto_ptr< " << etype (e) << " >&";
+ else
+ os << comma () << "const " << etype (e) << "&";
+
+ if (base_arg_ != 0)
+ os << " " << ename (e);
+ }
+ }
+
+ Void CtorArgs::
+ traverse (SemanticGraph::Attribute& a)
+ {
+ // Note that we are not going to include attributes with
+ // default or required fixed values here. Instead we are
+ // going to default-initialize them.
+ //
+ if (min (a) == 1 && !(a.fixed () && !is_qname (a.type ())))
+ {
+ os << comma () << "const " << etype (a) << "&";
+
+ if (base_arg_ != 0)
+ os << " " << ename (a);
+ }
+ }
+
+ String CtorArgs::
+ comma ()
+ {
+ Boolean tmp (first_);
+ first_ = false;
+ return tmp ? "" : ",\n";
+ }
+
+
+ // CtorArgsWithoutBase
+ //
+ CtorArgsWithoutBase::
+ CtorArgsWithoutBase (Context& c, ArgType at, Boolean arg, Boolean first)
+ : Context (c), arg_type_ (at), arg_ (arg), first_ (first)
+ {
+ *this >> inherits_ >> *this;
+ *this >> names_ >> *this;
+ }
+
+ Void CtorArgsWithoutBase::
+ traverse (SemanticGraph::Any& a)
+ {
+ if (!options.value<CLI::generate_wildcard> ())
+ return;
+
+ if (min (a) == 1 && max (a) == 1)
+ {
+ os << comma () << "const " << xerces_ns << "::DOMElement&";
+
+ if (arg_)
+ os << " " << ename (a);
+ }
+ }
+
+ Void CtorArgsWithoutBase::
+ traverse (SemanticGraph::Element& e)
+ {
+ if (skip (e))
+ return;
+
+ if (min (e) == 1 && max (e) == 1)
+ {
+ Boolean auto_ptr (false);
+
+ switch (arg_type_)
+ {
+ case arg_complex_auto_ptr:
+ {
+ Boolean simple (true);
+ IsSimpleType t (simple);
+ t.dispatch (e.type ());
+ auto_ptr = !simple;
+ break;
+ }
+ case arg_non_fund_auto_ptr:
+ {
+ Boolean fund (false);
+ IsFundamentalType t (fund);
+ t.dispatch (e.type ());
+ auto_ptr = !fund;
+ break;
+ }
+ case arg_type:
+ break;
+ }
+
+ if (auto_ptr)
+ os << comma () << "::std::auto_ptr< " << etype (e) << " >&";
+ else
+ os << comma () << "const " << etype (e) << "&";
+
+ if (arg_)
+ os << " " << ename (e);
+ }
+ }
+
+ Void CtorArgsWithoutBase::
+ traverse (SemanticGraph::Attribute& a)
+ {
+ // Note that we are not going to include attributes with
+ // default or required fixed values here. Instead we are
+ // going to default-initialize them.
+ //
+ if (min (a) == 1 && !(a.fixed () && !is_qname (a.type ())))
+ {
+ os << comma () << "const " << etype (a) << "&";
+
+ if (arg_)
+ os << " " << ename (a);
+ }
+ }
+
+ String CtorArgsWithoutBase::
+ comma ()
+ {
+ Boolean tmp (first_);
+ first_ = false;
+ return tmp ? "" : ",\n";
+ }
+
+ // GlobalElementBase
+ //
+ Boolean GlobalElementBase::
+ generate_p (SemanticGraph::Element& e)
+ {
+ if (e.substitutes_p () && ctx_.polymorphic)
+ return true;
+
+ if (!doc_root_p (e))
+ return false;
+
+ // If we are not generating element types nor parsing/serialization
+ // code then we won't generate anything from it.
+ //
+ if (!ctx_.options.value<CLI::generate_element_type> () &&
+ ctx_.options.value<CLI::suppress_parsing> () &&
+ !ctx_.options.value<CLI::generate_serialization> ())
+ return false;
+
+ return true;
+ }
+
+ Boolean GlobalElementBase::
+ doc_root_p (SemanticGraph::Element& e)
+ {
+ if (!ctx_.options.value<CLI::root_element_first> () &&
+ !ctx_.options.value<CLI::root_element_last> () &&
+ !ctx_.options.value<CLI::root_element_all> () &&
+ !ctx_.options.value<CLI::root_element_none> () &&
+ ctx_.options.value<CLI::root_element> ().empty ())
+ return true; // By default treat them all.
+
+ if (ctx_.options.value<CLI::root_element_none> ())
+ return false;
+
+ if (ctx_.options.value<CLI::root_element_all> ())
+ return true;
+
+ if (ctx_.options.value<CLI::root_element_first> () &&
+ e.context ().count ("first") != 0)
+ return true;
+
+ if (ctx_.options.value<CLI::root_element_last> () &&
+ e.context ().count ("last") != 0)
+ return true;
+
+ typedef Cult::Containers::Vector<NarrowString> Names;
+ Names const& names (ctx_.options.value<CLI::root_element> ());
+
+ // Hopefully nobody will specify more than a handful of names ;-).
+ //
+ for (Names::ConstIterator i (names.begin ()); i != names.end (); ++i)
+ {
+ String name (*i);
+
+ if (e.name () == name)
+ return true;
+ }
+
+ return false;
+ }
+
+ // Namespace
+ //
+ Namespace::
+ Namespace (Context& c,
+ UnsignedLong first,
+ UnsignedLong last)
+ : CXX::Namespace (c, *this),
+ GlobalElementBase (c),
+ ctx_ (c),
+ first_ (first),
+ last_ (last),
+ count_ (0)
+ {
+ }
+
+ Void Namespace::
+ traverse (Type& ns)
+ {
+ using SemanticGraph::Element;
+
+ if (first_ > last_)
+ CXX::Namespace::traverse (ns);
+ else
+ {
+ Boolean opened (false);
+
+ for (Type::NamesIterator i (ns.names_begin ());
+ i != ns.names_end (); ++i)
+ {
+ SemanticGraph::Nameable& n (i->named ());
+
+ if (n.is_a<SemanticGraph::Type> () ||
+ (n.is_a<Element> () && generate_p (dynamic_cast<Element&> (n))))
+ {
+ if (count_ >= first_ && count_ <= last_)
+ {
+ if (!opened)
+ {
+ opened = true;
+ pre (ns);
+ }
+
+ edge_traverser ().dispatch (*i);
+ }
+
+ ++count_;
+ }
+ }
+
+ if (opened)
+ post (ns);
+ }
+ }
+
+ Void Namespace::
+ enter (Type&, String const& name, Boolean)
+ {
+ ctx_.enter_ns_scope (name);
+ }
+
+ Void Namespace::
+ leave ()
+ {
+ ctx_.leave_ns_scope ();
+ }
+
+ // Includes
+ //
+ Void TypeForward::
+ traverse (SemanticGraph::Type& t)
+ {
+ String const& name (ename (t));
+
+ if (String custom = custom_type (t))
+ {
+ String new_name;
+ renamed_type (t, new_name);
+
+ if (new_name)
+ os << "class " << new_name << ";";
+
+ if (custom == name)
+ os << "class " << name << ";";
+ else
+ os << "typedef " << custom << " " << name << ";";
+ }
+ else
+ os << "class " << name << ";";
+ }
+
+ Void Includes::
+ traverse_ (SemanticGraph::Uses& u)
+ {
+ // Support for weak (forward) inclusion used in the file-per-type
+ // compilation model.
+ //
+ Type t (type_);
+ Boolean weak (u.context ().count ("weak"));
+
+ if (weak && t == header)
+ {
+ // Generate forward declarations.
+ //
+ if (forward_)
+ t = forward;
+ else
+ {
+ schema_.dispatch (u.schema ());
+ return;
+ }
+ }
+
+ if (t == source && !weak)
+ return;
+
+ SemanticGraph::Path path (u.path ());
+
+ // Try to use the portable representation of the path. If that
+ // fails, fall back to the native representation.
+ //
+ NarrowString path_str;
+ try
+ {
+ path_str = path.string ();
+ }
+ catch (SemanticGraph::InvalidPath const&)
+ {
+ path_str = path.native_file_string ();
+ }
+
+ String inc_path;
+
+ switch (t)
+ {
+ case forward:
+ {
+ inc_path = ctx_.fwd_expr->merge (path_str);
+ break;
+ }
+ case header:
+ case source:
+ {
+ inc_path = ctx_.hxx_expr->merge (path_str);
+ break;
+ }
+ case inline_:
+ {
+ if (weak)
+ {
+ inc_path = ctx_.hxx_expr->merge (path_str);
+ ctx_.os << "#include " << ctx_.process_include_path (inc_path)
+ << endl;
+ }
+
+ inc_path = ctx_.ixx_expr->merge (path_str);
+ break;
+ }
+ }
+
+ ctx_.os << "#include " << ctx_.process_include_path (inc_path) << endl
+ << endl;
+ }
+ }
+}
diff --git a/xsd/cxx/tree/elements.hxx b/xsd/cxx/tree/elements.hxx
new file mode 100644
index 0000000..3d70aab
--- /dev/null
+++ b/xsd/cxx/tree/elements.hxx
@@ -0,0 +1,2030 @@
+// file : xsd/cxx/tree/elements.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_ELEMENTS_HXX
+#define CXX_TREE_ELEMENTS_HXX
+
+#include <sstream>
+
+#include <cult/containers/map.hxx>
+#include <cult/containers/deque.hxx>
+#include <cult/containers/vector.hxx>
+
+#include <backend-elements/regex.hxx>
+
+#include <cxx/elements.hxx>
+
+#include <cxx/tree/cli.hxx>
+
+
+namespace CXX
+{
+ namespace Tree
+ {
+ struct Counts
+ {
+ Counts ()
+ : global_types (0),
+ global_elements (0),
+ generated_global_elements (0),
+ complexity_total (0)
+ {
+ }
+
+ UnsignedLong global_types;
+ UnsignedLong global_elements;
+ UnsignedLong generated_global_elements;
+
+ // Complexity value for each global type and generated global
+ // element, in order.
+ //
+ Cult::Containers::Vector<UnsignedLong> complexity;
+ UnsignedLong complexity_total;
+ };
+
+ struct InvalidCustomTypeMapping
+ {
+ InvalidCustomTypeMapping (String const& mapping,
+ String const& reason)
+ : mapping_ (mapping), reason_ (reason)
+ {
+ }
+
+ String const&
+ mapping () const
+ {
+ return mapping_;
+ }
+
+ String const&
+ reason () const
+ {
+ return reason_;
+ }
+
+ private:
+ String mapping_;
+ String reason_;
+ };
+
+ //
+ //
+ class Context: public CXX::Context
+ {
+ public:
+ typedef BackendElements::Regex::Expression<Char> Regex;
+ typedef BackendElements::Regex::Pattern<WideChar> WideRegexPat;
+
+ struct DirectCustomTypeMapInfo
+ {
+ DirectCustomTypeMapInfo (String const& t = L"",
+ String const& b = L"")
+ : type (t), base (b)
+ {
+ }
+
+ String type;
+ String base;
+ };
+
+ struct RegexCustomTypeMapInfo
+ {
+ RegexCustomTypeMapInfo (WideRegexPat const& p,
+ String const& t,
+ String const& b)
+ : pat (p), type_sub (t), base_sub (b)
+ {
+ }
+
+ WideRegexPat pat;
+ String type_sub;
+ String base_sub;
+ };
+
+ typedef
+ Cult::Containers::Vector<RegexCustomTypeMapInfo>
+ RegexCustomTypeMap;
+
+ typedef
+ Cult::Containers::Map<String, DirectCustomTypeMapInfo>
+ DirectCustomTypeMap;
+
+ public:
+ Context (std::wostream& o,
+ SemanticGraph::Schema& root,
+ CLI::Options const& ops,
+ Counts const& counts_,
+ Boolean generate_xml_schema,
+ Regex const* fwd_expr,
+ Regex const* hxx_expr,
+ Regex const* ixx_expr);
+
+ protected:
+ Context (Context& c);
+ Context (Context& c, std::wostream& o);
+
+ // Custom type mapping.
+ //
+ public:
+ // Returns empty string if custom mapping is not required.
+ //
+ String
+ custom_type (SemanticGraph::Type const&) const;
+
+ // Returns true if custom mapping is required. name is
+ // populated with the custom type name or empty if the
+ // original name should be used.
+ //
+ Boolean
+ custom_type (SemanticGraph::Type const&, String& name) const;
+
+ // Returns true if this type has been renamed as part of the
+ // customization process. If the function returns true, the
+ // name string is populated with the new name or empty if
+ // the type should not be generated at all.
+ //
+ Boolean
+ renamed_type (SemanticGraph::Type const&, String& name) const;
+
+ public:
+ // Return true if this type is-a QName.
+ //
+ Boolean
+ is_qname (SemanticGraph::Type&);
+
+ public:
+ // Performs a number of processing steps, including forcing a new
+ // line after 80 characters as well as "commentizing" the text by
+ // adding '* ' after each newline.
+ //
+ Void
+ write_annotation (SemanticGraph::Annotation&);
+
+ // Escaped names.
+ //
+ public:
+ // Accessor name.
+ //
+ static String const&
+ eaname (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<String> ("aname");
+ }
+
+ static String const&
+ eaname (SemanticGraph::Any const& a)
+ {
+ return a.context ().get<String> ("aname");
+ }
+
+ static String const&
+ eaname (SemanticGraph::AnyAttribute const& a)
+ {
+ return a.context ().get<String> ("aname");
+ }
+
+ // Modifier name.
+ //
+ static String const&
+ emname (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<String> ("mname");
+ }
+
+ static String const&
+ emname (SemanticGraph::Any const& a)
+ {
+ return a.context ().get<String> ("mname");
+ }
+
+ static String const&
+ emname (SemanticGraph::AnyAttribute const& a)
+ {
+ return a.context ().get<String> ("mname");
+ }
+
+ //
+ //
+ static String const&
+ etype (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<String> ("type");
+ }
+
+ static String const&
+ etraits (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<String> ("traits");
+ }
+
+ static String const&
+ econtainer (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<String> ("container");
+ }
+
+ static String const&
+ econtainer (SemanticGraph::Any const& a)
+ {
+ return a.context ().get<String> ("container");
+ }
+
+ static String const&
+ econtainer (SemanticGraph::AnyAttribute const& a)
+ {
+ return a.context ().get<String> ("container");
+ }
+
+ static String const&
+ eiterator (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<String> ("iterator");
+ }
+
+ static String const&
+ eiterator (SemanticGraph::Any const& a)
+ {
+ return a.context ().get<String> ("iterator");
+ }
+
+ static String const&
+ eiterator (SemanticGraph::AnyAttribute const& a)
+ {
+ return a.context ().get<String> ("iterator");
+ }
+
+ static String const&
+ econst_iterator (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<String> ("const-iterator");
+ }
+
+ static String const&
+ econst_iterator (SemanticGraph::Any const& a)
+ {
+ return a.context ().get<String> ("const-iterator");
+ }
+
+ static String const&
+ econst_iterator (SemanticGraph::AnyAttribute const& a)
+ {
+ return a.context ().get<String> ("const-iterator");
+ }
+
+ static String const&
+ emember (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<String> ("member");
+ }
+
+ static String const&
+ emember (SemanticGraph::Any const& a)
+ {
+ return a.context ().get<String> ("member");
+ }
+
+ static String const&
+ emember (SemanticGraph::AnyAttribute const& a)
+ {
+ return a.context ().get<String> ("member");
+ }
+
+ static String const&
+ edefault_value (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<String> ("default-value");
+ }
+
+ static String const&
+ edefault_value_member (SemanticGraph::Member const& m)
+ {
+ return m.context ().get<String> ("default-value-member");
+ }
+
+ // Underlying enum value type.
+ //
+ static String const&
+ evalue (SemanticGraph::Enumeration const& e)
+ {
+ return e.context ().get<String> ("value");
+ }
+
+ // dom_document
+ //
+ static Boolean
+ edom_document_p (SemanticGraph::Complex const& c)
+ {
+ return c.context ().count ("dom-document");
+ }
+
+ static String const&
+ edom_document (SemanticGraph::Complex const& c)
+ {
+ return c.context ().get<String> ("dom-document");
+ }
+
+ static Boolean
+ edom_document_member_p (SemanticGraph::Complex const& c)
+ {
+ return c.context ().count ("dom-document-member");
+ }
+
+ static String const&
+ edom_document_member (SemanticGraph::Complex const& c)
+ {
+ return c.context ().get<String> ("dom-document-member");
+ }
+
+ // Parsing and serialization function names.
+ //
+ static String const&
+ eparser (SemanticGraph::Element const& e)
+ {
+ return e.context ().get<String> ("parser");
+ }
+
+ static String const&
+ eserializer (SemanticGraph::Element const& e)
+ {
+ return e.context ().get<String> ("serializer");
+ }
+
+ public:
+ Void
+ enter_ns_scope (String const& name)
+ {
+ ns_scope_stack.push_back (name);
+ update_ns_scope ();
+ }
+
+ Void
+ leave_ns_scope ()
+ {
+ ns_scope_stack.pop_back ();
+ update_ns_scope ();
+ }
+
+ private:
+ Void
+ update_ns_scope ();
+
+ private:
+ // Write text that may contain characters that we will have
+ // to escape (indicated by the rogue flag).
+ //
+ Void
+ write_rogue_text (WideChar const* s, Size size, Boolean rogue);
+
+ public:
+ CLI::Options const& options;
+ Counts const& counts;
+ String& any_type;
+ String& any_simple_type;
+ String& element_type;
+ String& container;
+ String& flags_type;
+ String& qname_type;
+ String& xs_string_type;
+ String& properties_type;
+ String& error_handler_type;
+ String& list_stream_type;
+ String& namespace_infomap_type;
+ String& parser_type;
+ String& std_ostream_type;
+ String& ostream_type;
+ String& istream_type;
+ String& xerces_ns;
+ String& dom_auto_ptr;
+ String& dom_node_key;
+ String& as_double_type;
+ String& as_decimal_type;
+
+ Boolean& generate_xml_schema;
+ Boolean& doxygen;
+ Boolean polymorphic;
+
+ Regex const* fwd_expr;
+ Regex const* hxx_expr;
+ Regex const* ixx_expr;
+
+ String& ns_scope;
+
+ RegexCustomTypeMap& regex_custom_type_map;
+ DirectCustomTypeMap& direct_custom_type_map;
+
+ private:
+ String any_type_;
+ String any_simple_type_;
+ String element_type_;
+ String container_;
+ String flags_type_;
+ String qname_type_;
+ String xs_string_type_;
+ String properties_type_;
+ String error_handler_type_;
+ String list_stream_type_;
+ String namespace_infomap_type_;
+ String parser_type_;
+ String std_ostream_type_;
+ String ostream_type_;
+ String istream_type_;
+ String xerces_ns_;
+ String dom_auto_ptr_;
+ String dom_node_key_;
+ String as_double_type_;
+ String as_decimal_type_;
+
+ Boolean generate_xml_schema_;
+ Boolean doxygen_;
+
+ typedef
+ Cult::Containers::Deque<String>
+ NamespaceStack;
+
+ typedef
+ Cult::Containers::Deque<String>
+ ScopeStack;
+
+ String ns_scope_;
+
+ NamespaceStack& ns_scope_stack;
+ NamespaceStack ns_scope_stack_;
+
+ RegexCustomTypeMap regex_custom_type_map_;
+ DirectCustomTypeMap direct_custom_type_map_;
+
+ private:
+ WideRegexPat const cxx_uq_id_expr_;
+ WideRegexPat const& cxx_uq_id_expr;
+ };
+
+ // Check whether this Schema type maps to a fundamental C++ type.
+ //
+ struct IsFundamentalType : Traversal::Fundamental::Byte,
+ Traversal::Fundamental::UnsignedByte,
+ Traversal::Fundamental::Short,
+ Traversal::Fundamental::UnsignedShort,
+ Traversal::Fundamental::Int,
+ Traversal::Fundamental::UnsignedInt,
+ Traversal::Fundamental::Long,
+ Traversal::Fundamental::UnsignedLong,
+ Traversal::Fundamental::Integer,
+ Traversal::Fundamental::NonPositiveInteger,
+ Traversal::Fundamental::NonNegativeInteger,
+ Traversal::Fundamental::PositiveInteger,
+ Traversal::Fundamental::NegativeInteger,
+
+ Traversal::Fundamental::Boolean,
+
+ Traversal::Fundamental::Float,
+ Traversal::Fundamental::Double,
+ Traversal::Fundamental::Decimal
+
+ {
+ IsFundamentalType (Boolean& r)
+ : r_ (r)
+ {
+ }
+
+ // Integral types.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Byte&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedByte&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Short&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedShort&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Int&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedInt&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Long&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedLong&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Integer&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::PositiveInteger&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NegativeInteger&)
+ {
+ r_ = true;
+ }
+
+ // Boolean.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Boolean&)
+ {
+ r_ = true;
+ }
+
+ // Floats.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Float&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Double&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Decimal&)
+ {
+ r_ = true;
+ }
+
+ private:
+ Boolean& r_;
+ };
+
+ // Check whether this is a string-based type.
+ //
+ struct IsStringBasedType : Traversal::Complex,
+ Traversal::Union,
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Language
+ {
+ IsStringBasedType (Boolean& r)
+ : r_ (r)
+ {
+ *this >> inherits_ >> *this;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ inherits (c, inherits_);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Union&)
+ {
+ // Current mapping of union is string-based.
+ //
+ r_ = true;
+ }
+
+ // Strings.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName&)
+ {
+ r_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Language&)
+ {
+ r_ = true;
+ }
+
+ private:
+ Boolean& r_;
+ Traversal::Inherits inherits_;
+ };
+
+
+ // Check whether this is a enumeration-based type.
+ //
+ struct IsEnumBasedType : Traversal::Complex
+ {
+ IsEnumBasedType (SemanticGraph::Enumeration*& e)
+ : enum_ (e)
+ {
+ *this >> inherits_;
+
+ inherits_ >> *this;
+ inherits_ >> enum_;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ inherits (c, inherits_);
+ }
+
+ private:
+ struct Enumeration: Traversal::Enumeration
+ {
+ Enumeration (SemanticGraph::Enumeration*& e)
+ : e_ (e)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (e_ == 0)
+ e_ = &e;
+ }
+
+ private:
+ SemanticGraph::Enumeration*& e_;
+ };
+
+
+ private:
+ Enumeration enum_;
+ Traversal::Inherits inherits_;
+ };
+
+
+ //
+ //
+ struct MemberTypeName : protected Context,
+ Traversal::Type,
+ Traversal::List,
+ Traversal::Union,
+ Traversal::Complex,
+
+ Traversal::AnyType,
+ Traversal::AnySimpleType,
+
+ Traversal::Fundamental::Byte,
+ Traversal::Fundamental::UnsignedByte,
+ Traversal::Fundamental::Short,
+ Traversal::Fundamental::UnsignedShort,
+ Traversal::Fundamental::Int,
+ Traversal::Fundamental::UnsignedInt,
+ Traversal::Fundamental::Long,
+ Traversal::Fundamental::UnsignedLong,
+ Traversal::Fundamental::Integer,
+ Traversal::Fundamental::NonPositiveInteger,
+ Traversal::Fundamental::NonNegativeInteger,
+ Traversal::Fundamental::PositiveInteger,
+ Traversal::Fundamental::NegativeInteger,
+
+ Traversal::Fundamental::Boolean,
+
+ Traversal::Fundamental::Float,
+ Traversal::Fundamental::Double,
+ Traversal::Fundamental::Decimal,
+
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NameTokens,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Language,
+
+ Traversal::Fundamental::QName,
+
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef,
+ Traversal::Fundamental::IdRefs,
+
+ Traversal::Fundamental::AnyURI,
+
+ Traversal::Fundamental::Base64Binary,
+ Traversal::Fundamental::HexBinary,
+
+ Traversal::Fundamental::Date,
+ Traversal::Fundamental::DateTime,
+ Traversal::Fundamental::Duration,
+ Traversal::Fundamental::Day,
+ Traversal::Fundamental::Month,
+ Traversal::Fundamental::MonthDay,
+ Traversal::Fundamental::Year,
+ Traversal::Fundamental::YearMonth,
+ Traversal::Fundamental::Time,
+
+ Traversal::Fundamental::Entity,
+ Traversal::Fundamental::Entities
+
+ {
+ MemberTypeName (Context& c)
+ : Context (c)
+ {
+ }
+
+ MemberTypeName (Context& c, std::wostream& o)
+ : Context (c, o)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type&)
+ {
+ abort ();
+ }
+
+ virtual Void
+ traverse (SemanticGraph::List& l)
+ {
+ os << fq_name (l);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Union& u)
+ {
+ os << fq_name (u);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ os << fq_name (c);
+ }
+
+ // anyType & anySimpleType.
+ //
+ virtual Void
+ traverse (SemanticGraph::AnyType& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnySimpleType& t)
+ {
+ os << fq_name (t);
+ }
+
+ // Integral types.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Byte& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedByte& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Short& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedShort& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Int& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedInt& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Long& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedLong& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Integer& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::PositiveInteger& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NegativeInteger& t)
+ {
+ os << fq_name (t);
+ }
+
+ // Boolean.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Boolean& t)
+ {
+ os << fq_name (t);
+ }
+
+ // Floats.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Float& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Double& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Decimal& t)
+ {
+ os << fq_name (t);
+ }
+
+ // Strings.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameTokens& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Language& t)
+ {
+ os << fq_name (t);
+ }
+
+
+ // Qualified name.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::QName& t)
+ {
+ os << fq_name (t);
+ }
+
+
+ // ID/IDREF.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef& t)
+ {
+ if (t.named ())
+ {
+ // IDREF<anyType>
+ //
+ os << fq_name (t);
+ }
+ else
+ {
+ SemanticGraph::Nameable& ncname (
+ xs_ns ().find ("NCName").first->named ());
+
+ os << "::xsd::cxx::tree::idref< " <<
+ type_name (t.argumented ().type ()) << ", " <<
+ char_type << ", " << fq_name (ncname) << " >";
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRefs& t)
+ {
+ if (t.named ())
+ {
+ // IDREFS<anyType>
+ //
+ os << fq_name (t);
+ }
+ else
+ {
+ SemanticGraph::Nameable& ncname (
+ xs_ns ().find ("NCName").first->named ());
+
+ os << "::xsd::cxx::tree::idrefs< " << char_type << ", " <<
+ any_simple_type << ", ::xsd::cxx::tree::idref< " <<
+ type_name (t.argumented ().type ()) << ", " << char_type <<
+ ", " << fq_name (ncname) << " > >";
+ }
+ }
+
+ // URI.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::AnyURI& t)
+ {
+ os << fq_name (t);
+ }
+
+ // Binary.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Base64Binary& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::HexBinary& t)
+ {
+ os << fq_name (t);
+ }
+
+
+ // Date/time.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Date& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::DateTime& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Duration& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Day& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Month& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::MonthDay& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Year& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::YearMonth& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Time& t)
+ {
+ os << fq_name (t);
+ }
+
+ // Entity.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entity& t)
+ {
+ os << fq_name (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entities& t)
+ {
+ os << fq_name (t);
+ }
+
+ private:
+ // For idref/idrefs
+ //
+ String
+ type_name (SemanticGraph::Type& t)
+ {
+ // This type is always named.
+ //
+ std::wostringstream o;
+
+ MemberTypeName type (*this, o);
+ type.dispatch (t);
+
+ return o.str ();
+ }
+ };
+
+
+ //
+ //
+ struct BaseTypeName : MemberTypeName
+ {
+ BaseTypeName (Context& c)
+ : MemberTypeName (c)
+ {
+ }
+
+ BaseTypeName (Context& c, std::wostream& o)
+ : MemberTypeName (c, o)
+ {
+ }
+
+ virtual Void
+ fundamental_base (SemanticGraph::Type& t)
+ {
+ os << "::xsd::cxx::tree::fundamental_base< " <<
+ fq_name (t) << ", " << char_type << ", " <<
+ any_simple_type << " >";
+ }
+
+ // Integrals.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Byte& t)
+ {
+ fundamental_base (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedByte& t)
+ {
+ fundamental_base (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Short& t)
+ {
+ fundamental_base (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedShort& t)
+ {
+ fundamental_base (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Int& t)
+ {
+ fundamental_base (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedInt& t)
+ {
+ fundamental_base (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Long& t)
+ {
+ fundamental_base (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedLong& t)
+ {
+ fundamental_base (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Integer& t)
+ {
+ fundamental_base (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger& t)
+ {
+ fundamental_base (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger& t)
+ {
+ fundamental_base (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::PositiveInteger& t)
+ {
+ fundamental_base (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NegativeInteger& t)
+ {
+ fundamental_base (t);
+ }
+
+ // Boolean.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Boolean& t)
+ {
+ fundamental_base (t);
+ }
+
+ // Floats.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Float& t)
+ {
+ fundamental_base (t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Double& t)
+ {
+ os << "::xsd::cxx::tree::fundamental_base< " <<
+ fq_name (t) << ", " << char_type << ", " <<
+ any_simple_type << ", " <<
+ "::xsd::cxx::tree::schema_type::double_ >";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Decimal& t)
+ {
+ os << "::xsd::cxx::tree::fundamental_base< " <<
+ fq_name (t) << ", " << char_type << ", " <<
+ any_simple_type << ", " <<
+ "::xsd::cxx::tree::schema_type::decimal >";
+ }
+ };
+
+ // Initial value should be true.
+ //
+ struct IsSimpleType : Traversal::Complex,
+ Traversal::Member,
+ Traversal::Any,
+ Traversal::AnyAttribute
+ {
+ IsSimpleType (Boolean& v)
+ : v_ (v)
+ {
+ *this >> names_ >> *this;
+ *this >> inherits_ >> *this;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ names (c, names_);
+
+ if (v_)
+ inherits (c, inherits_);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Member&)
+ {
+ v_ = false;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any&)
+ {
+ v_ = false;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute&)
+ {
+ v_ = false;
+ }
+
+ private:
+ Boolean& v_;
+ Traversal::Names names_;
+ Traversal::Inherits inherits_;
+ };
+
+ // Test whether we need to generate default c-tor. Note that we are not
+ // interested in anyAttribute since it is always mapped to a sequence.
+ //
+ struct GenerateDefaultCtor: Traversal::Complex,
+ Traversal::Enumeration,
+ Traversal::Type,
+ Traversal::Element,
+ Traversal::Attribute,
+ Traversal::Any,
+ protected virtual Context
+ {
+ // generate should initially be false.
+ //
+ GenerateDefaultCtor (Context&, Boolean& generate, Boolean no_base);
+
+ virtual Void
+ traverse (SemanticGraph::Complex&);
+
+ virtual Void
+ traverse (SemanticGraph::Type&);
+
+ virtual Void
+ traverse (SemanticGraph::Enumeration&);
+
+ virtual Void
+ traverse (SemanticGraph::Element&);
+
+ virtual Void
+ traverse (SemanticGraph::Attribute&);
+
+ virtual Void
+ traverse (SemanticGraph::Any&);
+
+ private:
+ Boolean& generate_;
+ Boolean no_base_;
+
+ private:
+ Traversal::Inherits inherits_;
+ Traversal::Names names_;
+ };
+
+ // Test whether we need to generate from-base c-tor.
+ //
+ struct GenerateFromBaseCtor: Traversal::Complex
+ {
+ // generate should initially be false.
+ //
+ GenerateFromBaseCtor (Context& c, Boolean& generate);
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c);
+
+ private:
+ // Note that we are not interested in anyAttribute since it is always
+ // mapped to a sequence.
+ //
+ struct Traverser: Traversal::Complex,
+ Traversal::Element,
+ Traversal::Attribute,
+ Traversal::Any,
+ protected virtual Context
+ {
+ Traverser (Context& c, Boolean& generate);
+
+ virtual Void
+ traverse (SemanticGraph::Complex&);
+
+ virtual Void
+ traverse (SemanticGraph::Attribute&);
+
+ virtual Void
+ traverse (SemanticGraph::Element&);
+
+ virtual Void
+ traverse (SemanticGraph::Any&);
+
+ private:
+ Boolean& generate_;
+
+ private:
+ Traversal::Inherits inherits_;
+ Traversal::Names names_;
+ } traverser_;
+
+ Traversal::Inherits inherits_;
+ };
+
+ // Test whether the type has any non-optional element of complex
+ // (has attributes/elements) and non-fundamental types.
+ //
+ struct HasComplexNonFundNonOptArgs: Traversal::Complex,
+ Traversal::Element,
+ protected virtual Context
+ {
+ // complex and non_fund should initially be false. clash
+ // should initially be true.
+ //
+ HasComplexNonFundNonOptArgs (Context& c,
+ Boolean including_base,
+ Boolean& complex,
+ Boolean& non_fund,
+ Boolean& clash);
+
+ virtual Void
+ traverse (SemanticGraph::Complex&);
+
+ virtual Void
+ traverse (SemanticGraph::Element&);
+
+ private:
+ Boolean& complex_;
+ Boolean& non_fund_;
+ Boolean& clash_;
+
+ Traversal::Inherits inherits_;
+ Traversal::Names names_;
+ };
+
+ // Immediate non-optional member. Note that AnyAttribute is always
+ // mapped to a sequence.
+ //
+ struct FromBaseCtorArg : Traversal::Any,
+ Traversal::Element,
+ Traversal::Attribute,
+ protected virtual Context
+ {
+ enum ArgType
+ {
+ arg_type,
+ arg_complex_auto_ptr,
+ arg_non_fund_auto_ptr
+ };
+
+ FromBaseCtorArg (Context& c, ArgType, Boolean arg);
+
+ virtual Void
+ traverse (SemanticGraph::Any&);
+
+ virtual Void
+ traverse (SemanticGraph::Attribute&);
+
+ virtual Void
+ traverse (SemanticGraph::Element&);
+
+ private:
+ ArgType arg_type_;
+ Boolean arg_;
+ };
+
+ // List of all non-optional members and a simple base. Note that
+ // AnyAttribute is always mapped to a sequence.
+ //
+ struct CtorArgs : Traversal::Complex,
+ Traversal::Enumeration,
+ Traversal::Type,
+ Traversal::Any,
+ Traversal::Element,
+ Traversal::Attribute,
+ protected virtual Context
+ {
+ enum ArgType
+ {
+ arg_type,
+ arg_complex_auto_ptr,
+ arg_non_fund_auto_ptr
+ };
+
+ // The second version outputs the argument name and stores
+ // in in the base_arg string.
+ //
+ CtorArgs (Context&, ArgType);
+ CtorArgs (Context&, ArgType, String& base_arg);
+
+ virtual Void
+ traverse (SemanticGraph::Type&);
+
+ virtual Void
+ traverse (SemanticGraph::Enumeration&);
+
+ virtual Void
+ traverse (SemanticGraph::Any&);
+
+ virtual Void
+ traverse (SemanticGraph::Attribute&);
+
+ virtual Void
+ traverse (SemanticGraph::Element&);
+
+ private:
+ String
+ comma ();
+
+ private:
+ ArgType arg_type_;
+ String base_;
+ String* base_arg_;
+ Boolean first_;
+
+ private:
+ Traversal::Inherits inherits_;
+ Traversal::Names names_;
+
+ MemberTypeName member_name_;
+ };
+
+
+ // Check whether we need to generate c-tor without the base argument.
+ //
+ struct GenerateWithoutBaseCtor: Traversal::List,
+ Traversal::Union,
+ Traversal::Complex,
+ Traversal::Enumeration,
+
+ Traversal::AnyType,
+ Traversal::AnySimpleType,
+
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+
+ Traversal::Fundamental::NameTokens,
+ Traversal::Fundamental::IdRefs,
+
+ Traversal::Fundamental::Base64Binary,
+ Traversal::Fundamental::HexBinary
+ {
+ // generate should initially be false.
+ //
+ GenerateWithoutBaseCtor (Boolean& generate)
+ : generate_ (generate)
+ {
+ *this >> inherits_ >> *this;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::List&)
+ {
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Union&)
+ {
+ // No default initialization.
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ Complex::inherits (c);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Enumeration&)
+ {
+ // No default initialization.
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyType&)
+ {
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnySimpleType&)
+ {
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String&)
+ {
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString&)
+ {
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token&)
+ {
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameTokens&)
+ {
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRefs&)
+ {
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Base64Binary&)
+ {
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::HexBinary&)
+ {
+ generate_ = true;
+ }
+
+ private:
+ Boolean& generate_;
+ Traversal::Inherits inherits_;
+ };
+
+
+ // List of all non-optional members sans simple base. Note that
+ // AnyAttribute is always mapped to a sequence.
+ //
+ struct CtorArgsWithoutBase: Traversal::Complex,
+ Traversal::Any,
+ Traversal::Element,
+ Traversal::Attribute,
+ protected virtual Context
+ {
+ enum ArgType
+ {
+ arg_type,
+ arg_complex_auto_ptr,
+ arg_non_fund_auto_ptr
+ };
+
+ CtorArgsWithoutBase (Context& c, ArgType, Boolean arg, Boolean first);
+
+ virtual Void
+ traverse (SemanticGraph::Any&);
+
+ virtual Void
+ traverse (SemanticGraph::Element&);
+
+ virtual Void
+ traverse (SemanticGraph::Attribute&);
+
+ private:
+ String
+ comma ();
+
+ private:
+ ArgType arg_type_;
+ Boolean arg_;
+ Boolean first_;
+
+ private:
+ Traversal::Inherits inherits_;
+ Traversal::Names names_;
+ };
+
+ //
+ //
+ struct GlobalElementBase
+ {
+ GlobalElementBase (Context& c)
+ : ctx_ (c)
+ {
+ }
+
+ Boolean
+ generate_p (SemanticGraph::Element&);
+
+ Boolean
+ doc_root_p (SemanticGraph::Element&);
+
+ private:
+ Context& ctx_;
+ };
+
+
+ //
+ //
+ struct Namespace: CXX::Namespace,
+ GlobalElementBase,
+ CXX::Namespace::ScopeTracker
+ {
+ Namespace (Context&,
+ UnsignedLong first = 1,
+ UnsignedLong last = 0);
+
+ virtual Void
+ traverse (Type&);
+
+ protected:
+ virtual Void
+ enter (Type&, String const& name, Boolean last);
+
+ virtual Void
+ leave ();
+
+ protected:
+ Context& ctx_;
+
+ private:
+ UnsignedLong first_;
+ UnsignedLong last_;
+ UnsignedLong count_;
+ };
+
+ //
+ //
+ struct DocumentedNamespace: Namespace
+ {
+ DocumentedNamespace (Context& c)
+ : Namespace (c)
+ {
+ }
+
+ virtual Void
+ enter (Type& ns, String const& name, Boolean last)
+ {
+ Namespace::enter (ns, name, last);
+
+ // Only add documentation to the innermost namespace.
+ //
+ if (ctx_.doxygen && name && last)
+ {
+ ctx_.os << "/**" << endl
+ << " * @brief C++ namespace for the %" <<
+ ctx_.comment (ns.name ()) << endl
+ << " * schema namespace." << endl
+ << " */" << endl;
+ }
+ }
+ };
+
+ //
+ //
+ struct TypeForward: Traversal::Type, Context
+ {
+ TypeForward (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type& t);
+ };
+
+ struct Includes : Traversal::Imports,
+ Traversal::Includes
+ {
+ enum Type
+ {
+ forward,
+ header,
+ inline_,
+ source
+ };
+
+ Includes (Context& c, Type type)
+ : ctx_ (c),
+ type_ (type),
+ forward_ (c.options.value<CLI::generate_forward> ()),
+ namespace_ (c),
+ type_forward_ (c)
+ {
+ schema_ >> schema_names_ >> namespace_ >> names_ >> type_forward_;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Imports& i)
+ {
+ traverse_ (i);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Includes& i)
+ {
+ traverse_ (i);
+ }
+
+ private:
+ Void
+ traverse_ (SemanticGraph::Uses&);
+
+ private:
+ Context& ctx_;
+ Type type_;
+ Boolean forward_;
+
+ Traversal::Schema schema_;
+ Traversal::Names schema_names_;
+ Namespace namespace_;
+ Traversal::Names names_;
+ TypeForward type_forward_;
+ };
+
+ //
+ //
+ struct FundIncludes : Traversal::Fundamental::Byte,
+ Traversal::Fundamental::UnsignedByte,
+ Traversal::Fundamental::Short,
+ Traversal::Fundamental::UnsignedShort,
+ Traversal::Fundamental::Int,
+ Traversal::Fundamental::UnsignedInt,
+ Traversal::Fundamental::Long,
+ Traversal::Fundamental::UnsignedLong,
+ Traversal::Fundamental::Integer,
+ Traversal::Fundamental::NonPositiveInteger,
+ Traversal::Fundamental::NonNegativeInteger,
+ Traversal::Fundamental::PositiveInteger,
+ Traversal::Fundamental::NegativeInteger,
+
+ Traversal::Fundamental::Boolean,
+
+ Traversal::Fundamental::Float,
+ Traversal::Fundamental::Double,
+ Traversal::Fundamental::Decimal,
+ Context
+
+ {
+ FundIncludes (Context& c, String const& prefix)
+ : Context (c), prefix_ (prefix),
+ long_ (false), unsigned_long_ (false)
+ {
+ }
+
+ // Integral types.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Byte& t)
+ {
+ gen_include (t, "byte.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedByte& t)
+ {
+ gen_include (t, "unsigned-byte.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Short& t)
+ {
+ gen_include (t, "short.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedShort& t)
+ {
+ gen_include (t, "unsigned-short.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Int& t)
+ {
+ gen_include (t, "int.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedInt& t)
+ {
+ gen_include (t, "unsigned-int.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Long& t)
+ {
+ if (!long_)
+ long_ = gen_include (t, "long.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedLong& t)
+ {
+ if (!unsigned_long_)
+ unsigned_long_ = gen_include (t, "unsigned-long.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Integer& t)
+ {
+ if (!long_)
+ long_ = gen_include (t, "long.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger& t)
+ {
+ if (!long_)
+ long_ = gen_include (t, "long.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger& t)
+ {
+ if (!unsigned_long_)
+ unsigned_long_ = gen_include (t, "unsigned-long.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::PositiveInteger& t)
+ {
+ if (!unsigned_long_)
+ unsigned_long_ = gen_include (t, "unsigned-long.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NegativeInteger& t)
+ {
+ if (!long_)
+ long_ = gen_include (t, "long.hxx");
+ }
+
+ // Boolean.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Boolean& t)
+ {
+ gen_include (t, "boolean.hxx");
+ }
+
+ // Floats.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Float& t)
+ {
+ gen_include (t, "float.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Double& t)
+ {
+ gen_include (t, "double.hxx");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Decimal& t)
+ {
+ gen_include (t, "decimal.hxx");
+ }
+
+ private:
+ Boolean
+ gen_include (SemanticGraph::Type& t, String const& file)
+ {
+ String custom;
+
+ // XML Schema built-in type customization is only possible when
+ // we are generating separate header.
+ //
+ if (generate_xml_schema && custom_type (t, custom))
+ {
+ String new_name;
+ renamed_type (t, new_name);
+
+ if (!new_name)
+ return false;
+ }
+
+ os << "#include <xsd/cxx/tree/" << prefix_ << "/" << file << ">"
+ << endl;
+
+ return true;
+ }
+
+ private:
+ String prefix_;
+ Boolean long_;
+ Boolean unsigned_long_;
+ };
+ }
+}
+
+#endif // CXX_TREE_ELEMENTS_HXX
diff --git a/xsd/cxx/tree/fundamental-header.hxx b/xsd/cxx/tree/fundamental-header.hxx
new file mode 100644
index 0000000..5ea3596
--- /dev/null
+++ b/xsd/cxx/tree/fundamental-header.hxx
@@ -0,0 +1,1186 @@
+// file : xsd/cxx/tree/fundamental-header.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_FUNDAMENTAL_HEADER_HXX
+#define CXX_TREE_FUNDAMENTAL_HEADER_HXX
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ struct FundamentalNamespace : DocumentedNamespace,
+
+ Traversal::AnyType,
+ Traversal::AnySimpleType,
+
+ Traversal::Fundamental::Byte,
+ Traversal::Fundamental::UnsignedByte,
+ Traversal::Fundamental::Short,
+ Traversal::Fundamental::UnsignedShort,
+ Traversal::Fundamental::Int,
+ Traversal::Fundamental::UnsignedInt,
+ Traversal::Fundamental::Long,
+ Traversal::Fundamental::UnsignedLong,
+ Traversal::Fundamental::Integer,
+ Traversal::Fundamental::NonPositiveInteger,
+ Traversal::Fundamental::NonNegativeInteger,
+ Traversal::Fundamental::PositiveInteger,
+ Traversal::Fundamental::NegativeInteger,
+
+ Traversal::Fundamental::Boolean,
+
+ Traversal::Fundamental::Float,
+ Traversal::Fundamental::Double,
+ Traversal::Fundamental::Decimal,
+
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NameTokens,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Language,
+
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef,
+ Traversal::Fundamental::IdRefs,
+
+ Traversal::Fundamental::AnyURI,
+
+ Traversal::Fundamental::QName,
+
+ Traversal::Fundamental::Base64Binary,
+ Traversal::Fundamental::HexBinary,
+
+ Traversal::Fundamental::Date,
+ Traversal::Fundamental::DateTime,
+ Traversal::Fundamental::Duration,
+ Traversal::Fundamental::Day,
+ Traversal::Fundamental::Month,
+ Traversal::Fundamental::MonthDay,
+ Traversal::Fundamental::Year,
+ Traversal::Fundamental::YearMonth,
+ Traversal::Fundamental::Time,
+
+ Traversal::Fundamental::Entity,
+ Traversal::Fundamental::Entities,
+ protected virtual Context
+ {
+ FundamentalNamespace (Context& c)
+ : Context (c),
+ DocumentedNamespace (c),
+ export_ (c.options.value<CLI::export_xml_schema> () && type_exp)
+ {
+ *this >> names_ >> *this;
+ }
+
+ Void
+ gen_typedef (String const& type, String const& name)
+ {
+ os << "typedef " << type << " " << name << ";";
+
+ if (export_ && type.find (L'<') != String::npos)
+ os << "template class " << type_exp << type << ";";
+ }
+
+ String
+ built_in_type (SemanticGraph::Type& t, String const& type)
+ {
+ String custom;
+
+ String name (ename (t));
+
+ // XML Schema built-in type customization is only possible when
+ // we are generating separate header.
+ //
+ if (generate_xml_schema && custom_type (t, custom))
+ {
+ if (custom.empty ())
+ custom = name;
+
+ String new_name;
+ renamed_type (t, new_name);
+
+ if (new_name)
+ {
+ gen_typedef (type, new_name);
+
+ if (doxygen)
+ os << endl;
+ }
+
+ if (doxygen)
+ os << "/**" << endl
+ << " * @brief C++ type corresponding to the " <<
+ comment (t.name ()) << " XML Schema" << endl
+ << " * built-in type." << endl
+ << " */" << endl;
+
+ if (custom == name)
+ os << "class " << name << ";";
+ else
+ os << "typedef " << custom << " " << name << ";";
+
+ if (doxygen)
+ os << endl;
+ }
+ else
+ {
+ // Otherwise generate simple typedef.
+ //
+
+ if (doxygen)
+ os << "/**" << endl
+ << " * @brief C++ type corresponding to the " <<
+ comment (t.name ()) << " XML Schema" << endl
+ << " * built-in type." << endl
+ << " */" << endl;
+
+ gen_typedef (type, name);
+
+ if (doxygen)
+ os << endl;
+ }
+
+ return name;
+ }
+
+ // anyType and anySimpleType
+ //
+ virtual Void
+ traverse (SemanticGraph::AnyType& t)
+ {
+ os << "// anyType and anySimpleType." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl;
+
+ type_ = built_in_type (t, "::xsd::cxx::tree::type");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnySimpleType& t)
+ {
+ simple_type_ = built_in_type (
+ t, L"::xsd::cxx::tree::simple_type< " + type_ + L" >");
+
+ if (doxygen)
+ os << "/**" << endl
+ << " * @brief Alias for the anyType type." << endl
+ << " */" << endl;
+
+ gen_typedef ("::xsd::cxx::tree::type",
+ xs_ns ().context().get<String> ("container"));
+
+ os << endl;
+
+ if (doxygen)
+ os << endl;
+ }
+
+ // Integrals.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Byte& t)
+ {
+ os << "// 8-bit" << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl;
+
+ built_in_type (t, "signed char");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedByte& t)
+ {
+ built_in_type (t, "unsigned char");
+ os << endl;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Short& t)
+ {
+ os << "// 16-bit" << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl;
+
+ built_in_type (t, "short");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedShort& t)
+ {
+ built_in_type (t, "unsigned short");
+ os << endl;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Int& t)
+ {
+ os << "// 32-bit" << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl;
+
+ built_in_type (t, "int");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedInt& t)
+ {
+ built_in_type (t, "unsigned int");
+ os << endl;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Long& t)
+ {
+ os << "// 64-bit" << endl
+ << "//" <<endl;
+
+ if (doxygen)
+ os << endl;
+
+ built_in_type (t, "long long");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedLong& t)
+ {
+ built_in_type (t, "unsigned long long");
+ os << endl;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Integer& t)
+ {
+ os << "// Supposed to be arbitrary-length integral types." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl;
+
+ built_in_type (t, "long long");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger& t)
+ {
+ built_in_type (t, "long long");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger& t)
+ {
+ built_in_type (t, "unsigned long long");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::PositiveInteger& t)
+ {
+ built_in_type (t, "unsigned long long");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NegativeInteger& t)
+ {
+ built_in_type (t, "long long");
+ os << endl;
+ }
+
+ // Boolean.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Boolean& t)
+ {
+ os << "// Boolean." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl;
+
+ built_in_type (t, "bool");
+
+ os << endl;
+ }
+
+ // Floats.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Float& t)
+ {
+ os << "// Floating-point types." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl;
+
+ built_in_type (t, "float");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Double& t)
+ {
+ double_ = built_in_type (t, "double");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Decimal& t)
+ {
+ decimal_ = built_in_type (t, "double");
+ os << endl;
+ }
+
+
+ // Strings.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String& t)
+ {
+ os << "// String types." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl;
+
+ string_ = built_in_type (
+ t,
+ L"::xsd::cxx::tree::string< " + char_type + L", " +
+ simple_type_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString& t)
+ {
+ norm_string_ = built_in_type (
+ t,
+ L"::xsd::cxx::tree::normalized_string< " + char_type +
+ L", " + string_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token& t)
+ {
+ token_ = built_in_type (
+ t,
+ L"::xsd::cxx::tree::token< " + char_type + L", " +
+ norm_string_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken& t)
+ {
+ nmtoken_ = built_in_type (
+ t,
+ L"::xsd::cxx::tree::nmtoken< " + char_type + L", " +
+ token_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameTokens& t)
+ {
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::nmtokens< " + char_type +
+ L", " + simple_type_ + L", " + nmtoken_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name& t)
+ {
+ name_ = built_in_type (
+ t,
+ L"::xsd::cxx::tree::name< " + char_type + L", " + token_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName& t)
+ {
+ ncname_ = built_in_type (
+ t,
+ L"::xsd::cxx::tree::ncname< " + char_type + L", " + name_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Language& t)
+ {
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::language< " + char_type + L", " +
+ token_ + L" >");
+
+ os << endl;
+ }
+
+ // ID/IDREF.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id& t)
+ {
+ os << "// ID/IDREF." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl;
+
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::id< " + char_type + L", " + ncname_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef& t)
+ {
+ idref_ = built_in_type (
+ t,
+ L"::xsd::cxx::tree::idref< " + type_ + L", " + char_type + L", " +
+ ncname_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRefs& t)
+ {
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::idrefs< " + char_type +
+ L", " + simple_type_ + L", " + idref_ + L" >");
+
+ os << endl;
+ }
+
+
+ // URI.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::AnyURI& t)
+ {
+ os << "// URI." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl;
+
+ uri_ = built_in_type (
+ t,
+ L"::xsd::cxx::tree::uri< " + char_type + L", " +
+ simple_type_ + L" >");
+
+ os << endl;
+ }
+
+ // Qualified name.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::QName& t)
+ {
+ os << "// Qualified name." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl;
+
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::qname< " + char_type +
+ L", " + simple_type_ + L", " + uri_ + L", " + ncname_ + L" >");
+
+ os << endl;
+ }
+
+ // Binary.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Base64Binary& t)
+ {
+ os << "// Binary." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Binary buffer type." << endl
+ << " */" << endl;
+
+ gen_typedef (L"::xsd::cxx::tree::buffer< " + char_type + L" >",
+ xs_ns ().context().get<String> ("buffer"));
+
+ if (doxygen)
+ os << endl;
+
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::base64_binary< " + char_type +
+ L", " + simple_type_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::HexBinary& t)
+ {
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::hex_binary< " + char_type +
+ L", " + simple_type_ + L" >");
+
+ os << endl;
+ }
+
+
+ // Date/time.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Date& t)
+ {
+ os << "// Date/time." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Time zone type." << endl
+ << " */" << endl;
+
+ gen_typedef ("::xsd::cxx::tree::time_zone",
+ xs_ns ().context().get<String> ("time-zone"));
+
+ if (doxygen)
+ os << endl;
+
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::date< " + char_type + L", " +
+ simple_type_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::DateTime& t)
+ {
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::date_time< " + char_type + L", " +
+ simple_type_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Duration& t)
+ {
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::duration< " + char_type + L", " +
+ simple_type_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Day& t)
+ {
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::gday< " + char_type + L", " +
+ simple_type_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Month& t)
+ {
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::gmonth< " + char_type + L", " +
+ simple_type_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::MonthDay& t)
+ {
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::gmonth_day< " + char_type + L", " +
+ simple_type_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Year& t)
+ {
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::gyear< " + char_type + L", " +
+ simple_type_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::YearMonth& t)
+ {
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::gyear_month< " + char_type + L", " +
+ simple_type_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Time& t)
+ {
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::time< " + char_type + L", " +
+ simple_type_ + L" >");
+
+ os << endl;
+ }
+
+ // Entity.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entity& t)
+ {
+ os << "// Entity." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl;
+
+ entity_ = built_in_type (
+ t,
+ L"::xsd::cxx::tree::entity< " + char_type + L", " +
+ ncname_ + L" >");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entities& t)
+ {
+ built_in_type (
+ t,
+ L"::xsd::cxx::tree::entities< " + char_type +
+ L", " + simple_type_ + L", " + entity_ + L" >");
+
+ os << endl;
+ }
+
+ virtual Void
+ post (SemanticGraph::Namespace& n)
+ {
+ SemanticGraph::Context& c (xs_ns ().context());
+
+ Boolean parsing (!options.value<CLI::suppress_parsing> ());
+ Boolean serialization (options.value<CLI::generate_serialization> ());
+ Boolean element_map (options.value<CLI::generate_element_map> ());
+
+ if (options.value<CLI::generate_element_type> ())
+ {
+ if (doxygen)
+ os << "/**" << endl
+ << " * @brief Base class for element types." << endl
+ << " */" << endl;
+ else
+ os << "// Base class for element types." << endl
+ << "//" << endl;
+
+ gen_typedef (L"::xsd::cxx::tree::element_type < " +
+ char_type + L", " + type_ + L" >",
+ c.get<String> ("element-type"));
+ os << endl;
+ }
+
+ if (element_map)
+ {
+ if (doxygen)
+ os << "/**" << endl
+ << " * @brief Root element map." << endl
+ << " */" << endl;
+ else
+ os << "// Root element map." << endl
+ << "//" << endl;
+
+ gen_typedef (L"::xsd::cxx::tree::element_map < " +
+ char_type + L", " + type_ + L" >",
+ c.get<String> ("element-map"));
+ os << endl;
+ }
+
+ if (serialization)
+ {
+ os << "// Namespace information and list stream. Used in" << endl
+ << "// serialization functions." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << "/**" << endl
+ << " * @brief Namespace serialization information." << endl
+ << " */" << endl;
+
+ gen_typedef (
+ L"::xsd::cxx::xml::dom::namespace_info < " + char_type + L" >",
+ c.get<String> ("namespace-info"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Namespace serialization information map." << endl
+ << " */" << endl;
+
+ gen_typedef (L"::xsd::cxx::xml::dom::namespace_infomap < " +
+ char_type + L" >",
+ c.get<String> ("namespace-infomap"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief List serialization stream." << endl
+ << " */" << endl;
+
+ gen_typedef (
+ L"::xsd::cxx::tree::list_stream < " + char_type + L" >",
+ c.get<String> ("list-stream"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Serialization wrapper for the %double type." << endl
+ << " */" << endl;
+
+ gen_typedef (L"::xsd::cxx::tree::as_double < " + double_ + L" >",
+ c.get<String> ("as-double"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Serialization wrapper for the %decimal type." << endl
+ << " */" << endl;
+
+ gen_typedef (L"::xsd::cxx::tree::as_decimal < " + decimal_ + L" >",
+ c.get<String> ("as-decimal"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Simple type facet." << endl
+ << " */" << endl;
+
+ gen_typedef ("::xsd::cxx::tree::facet", c.get<String> ("facet"));
+
+ os << endl;
+ }
+
+ //@@ Can't change names of ostream/istream since they are
+ // templates.
+ //
+ if (!options.value<CLI::generate_insertion> ().empty ())
+ {
+ if (doxygen)
+ os << "/**" << endl
+ << " * @brief Data representation output stream template." << endl
+ << " */" << endl;
+ else
+ os << "// Data representation output stream template." << endl
+ << "//" << endl;
+
+ os << "using ::xsd::cxx::tree::ostream;"
+ << endl;
+ }
+
+ if (!options.value<CLI::generate_extraction> ().empty ())
+ {
+ if (doxygen)
+ os << "/**" << endl
+ << " * @brief Data representation input stream template." << endl
+ << " */" << endl;
+ else
+ os << "// Data representation input stream template." << endl
+ << "//" << endl;
+
+ os << "using ::xsd::cxx::tree::istream;"
+ << endl;
+ }
+
+ os << "// Flags and properties." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Parsing and serialization flags." << endl
+ << " */" << endl;
+
+ gen_typedef ("::xsd::cxx::tree::flags", c.get<String> ("flags"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Parsing properties." << endl
+ << " */" << endl;
+
+ gen_typedef (L"::xsd::cxx::tree::properties< " + char_type + L" >",
+ c.get<String> ("properties"));
+ os << endl;
+
+
+ //
+ //
+ os << "// Exceptions." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Root of the C++/Tree %exception hierarchy." << endl
+ << " */" << endl;
+
+ gen_typedef (L"::xsd::cxx::tree::exception< " + char_type + L" >",
+ c.get<String> ("exception"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Exception indicating that the size argument exceeds" <<
+ endl
+ << " * the capacity argument." << endl
+ << " */" << endl;
+
+ gen_typedef (L"::xsd::cxx::tree::bounds< " + char_type + L" >",
+ c.get<String> ("bounds"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Exception indicating that a duplicate ID value" <<
+ endl
+ << " * was encountered in the object model." << endl
+ << " */" << endl;
+
+ gen_typedef (L"::xsd::cxx::tree::duplicate_id< " + char_type + L" >",
+ c.get<String> ("duplicate-id"));
+
+ if (parsing)
+ {
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Exception indicating a parsing failure." << endl
+ << " */" << endl;
+
+ gen_typedef (L"::xsd::cxx::tree::parsing< " + char_type + L" >",
+ c.get<String> ("parsing"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Exception indicating that an expected element" <<
+ endl
+ << " * was not encountered." << endl
+ << " */" << endl;
+
+ gen_typedef (
+ L"::xsd::cxx::tree::expected_element< " + char_type + L" >",
+ c.get<String> ("expected-element"));
+ }
+
+ if (parsing || serialization)
+ {
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Exception indicating that an unexpected " <<
+ "element" << endl
+ << " * was encountered." << endl
+ << " */" << endl;
+
+ gen_typedef (
+ L"::xsd::cxx::tree::unexpected_element< " + char_type + L" >",
+ c.get<String> ("unexpected-element"));
+ }
+
+ if (parsing)
+ {
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Exception indicating that an expected " <<
+ "attribute" << endl
+ << " * was not encountered." << endl
+ << " */" << endl;
+
+ gen_typedef (
+ L"::xsd::cxx::tree::expected_attribute< " + char_type + L" >",
+ c.get<String> ("expected-attribute"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Exception indicating that an unexpected " <<
+ "enumerator" << endl
+ << " * was encountered." << endl
+ << " */" << endl;
+
+ gen_typedef (
+ L"::xsd::cxx::tree::unexpected_enumerator< " + char_type + L" >",
+ c.get<String> ("unexpected-enumerator"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Exception indicating that the text content " <<
+ "was" << endl
+ << " * expected for an element." << endl
+ << " */" << endl;
+
+ gen_typedef (
+ L"::xsd::cxx::tree::expected_text_content< " + char_type + L" >",
+ c.get<String> ("expected-text-content"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Exception indicating that a prefix-namespace" <<
+ endl
+ << " * mapping was not provided." << endl
+ << " */" << endl;
+
+ gen_typedef (
+ L"::xsd::cxx::tree::no_prefix_mapping< " + char_type + L" >",
+ c.get<String> ("no-prefix-mapping"));
+ }
+
+ if (options.value<CLI::generate_polymorphic> ())
+ {
+ if (parsing || serialization)
+ {
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Exception indicating that the type " <<
+ "information" << endl
+ << " * is not available for a type." << endl
+ << " */" << endl;
+
+ gen_typedef (
+ L"::xsd::cxx::tree::no_type_info< " + char_type + L" >",
+ c.get<String> ("no-type-info"));
+ }
+
+ if (parsing)
+ {
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Exception indicating that the types are not" <<
+ endl
+ << " * related by inheritance." << endl
+ << " */" << endl;
+
+ gen_typedef (
+ L"::xsd::cxx::tree::not_derived< " + char_type + L" >",
+ c.get<String> ("not-derived"));
+ }
+ }
+
+ if (element_map)
+ {
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Exception indicating that parsing or " <<
+ "serialization" << endl
+ << " * information is not available for an element." << endl
+ << " */" << endl;
+
+ gen_typedef (
+ L"::xsd::cxx::tree::no_element_info< " + char_type + L" >",
+ c.get<String> ("no-element-info"));
+ }
+
+ if (serialization)
+ {
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Exception indicating a serialization " <<
+ "failure." << endl
+ << " */" << endl;
+
+ gen_typedef (
+ L"::xsd::cxx::tree::serialization< " + char_type + L" >",
+ c.get<String> ("serialization"));
+ }
+
+ os << endl;
+
+ //
+ //
+ if (parsing || serialization)
+ {
+ os << "// Parsing/serialization diagnostics." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Error severity." << endl
+ << " */" << endl;
+
+ gen_typedef ("::xsd::cxx::tree::severity",
+ c.get<String> ("severity"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief Error condition." << endl
+ << " */" << endl;
+
+ gen_typedef (L"::xsd::cxx::tree::error< " + char_type + L" >",
+ c.get<String> ("error"));
+
+ if (doxygen)
+ os << endl
+ << "/**" << endl
+ << " * @brief List of %error conditions." << endl
+ << " */" << endl;
+
+ gen_typedef (L"::xsd::cxx::tree::diagnostics< " + char_type + L" >",
+ c.get<String> ("diagnostics"));
+ os << endl;
+ }
+
+ if (parsing || serialization)
+ {
+ if (doxygen)
+ os << "/**" << endl
+ << " * @brief Error handler callback interface." << endl
+ << " */" << endl;
+ else
+ os << "// Error handler callback interface." << endl
+ << "//" << endl;
+
+ gen_typedef (
+ L"::xsd::cxx::xml::error_handler< " + char_type + L" >",
+ c.get<String> ("error-handler"));
+
+ os << endl;
+ }
+
+ if (parsing || serialization)
+ {
+ if (doxygen)
+ os << "/**" << endl
+ << " * @brief DOM interaction." << endl
+ << " */" << endl;
+ else
+ os << "// DOM interaction." << endl
+ << "//" << endl;
+
+ os << "namespace dom"
+ << "{";
+
+ // @@ Disregarding current naming convention by using the
+ // fixed name (no template typedef).
+ //
+ if (doxygen)
+ os << "/**" << endl
+ << " * @brief Automatic pointer for DOMDocument." << endl
+ << " */" << endl;
+ else
+ os << "// Automatic pointer for DOMDocument." << endl
+ << "//" << endl;
+
+ os << "using ::xsd::cxx::xml::dom::auto_ptr;"
+ << endl;
+
+ if (parsing)
+ {
+ if (!generate_xml_schema)
+ {
+ String g (L"XSD_CXX_TREE_TREE_NODE_KEY" + ns_name (n));
+
+ std::transform (g.begin (), g.end(), g.begin (), upcase);
+ g = escape (g); // Make it a C++ id.
+
+ os << "#ifndef " << g << endl
+ << "#define " << g << endl;
+ }
+
+ if (doxygen)
+ os << "/**" << endl
+ << " * @brief DOM user data key for back pointers to " <<
+ "tree nodes." << endl
+ << " */" << endl;
+ else
+ os << "// DOM user data key for back pointers to tree nodes." << endl
+ << "//" << endl;
+
+ os << "const XMLCh* const " << c.get<String> ("tree-node-key") <<
+ " = ::xsd::cxx::tree::user_data_keys::node;";
+
+ if (!generate_xml_schema)
+ os << "#endif" << endl;
+ }
+
+ os << "}"; // namespace dom
+ }
+
+ if (element_map)
+ {
+ if (doxygen)
+ os << "//@cond" << endl
+ << endl;
+
+ if (!generate_xml_schema)
+ {
+ String g (L"XSD_CXX_TREE_ELEMENT_MAP_INIT" + ns_name (n));
+
+ std::transform (g.begin (), g.end(), g.begin (), upcase);
+ g = escape (g); // Make it a C++ id.
+
+ os << "#ifndef " << g << endl
+ << "#define " << g << endl;
+ }
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::element_map_init < " <<
+ char_type << ", " << type_ << " >" << endl
+ << "_xsd_element_map_init;";
+
+ if (!generate_xml_schema)
+ os << "#endif" << endl;
+
+ if (doxygen)
+ os << endl
+ << "//@endcond" << endl;
+ }
+
+ Namespace::post (n);
+ }
+
+ private:
+ Boolean export_;
+
+ Traversal::Names names_;
+
+ String type_;
+ String simple_type_;
+ String string_;
+ String norm_string_;
+ String token_;
+ String nmtoken_;
+ String name_;
+ String ncname_;
+ String idref_;
+ String uri_;
+ String entity_;
+
+ String double_;
+ String decimal_;
+ };
+ }
+}
+
+#endif // CXX_TREE_FUNDAMENTAL_HEADER_HXX
diff --git a/xsd/cxx/tree/generator.cxx b/xsd/cxx/tree/generator.cxx
new file mode 100644
index 0000000..f9b055e
--- /dev/null
+++ b/xsd/cxx/tree/generator.cxx
@@ -0,0 +1,1689 @@
+// file : xsd/cxx/tree/generator.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/generator.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+#include <cxx/tree/counter.hxx>
+#include <cxx/tree/validator.hxx>
+#include <cxx/tree/name-processor.hxx>
+
+#include <cxx/tree/tree-forward.hxx>
+#include <cxx/tree/tree-header.hxx>
+#include <cxx/tree/tree-inline.hxx>
+#include <cxx/tree/tree-source.hxx>
+
+#include <cxx/tree/parser-header.hxx>
+#include <cxx/tree/parser-source.hxx>
+
+#include <cxx/tree/stream-header.hxx>
+#include <cxx/tree/stream-source.hxx>
+
+#include <cxx/tree/serialization-header.hxx>
+#include <cxx/tree/serialization-source.hxx>
+
+#include <cxx/tree/stream-insertion-header.hxx>
+#include <cxx/tree/stream-insertion-source.hxx>
+#include <cxx/tree/stream-extraction-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+
+#include <backend-elements/regex.hxx>
+#include <backend-elements/indentation/cxx.hxx>
+#include <backend-elements/indentation/sloc.hxx>
+#include <backend-elements/indentation/clip.hxx>
+
+#include <cult/containers/set.hxx>
+#include <cult/containers/vector.hxx>
+
+#include <boost/filesystem/fstream.hpp>
+
+#include <iostream>
+
+#include <usage.hxx>
+
+#include "../../../libxsd/xsd/cxx/version.hxx"
+
+using std::endl;
+using std::wcerr;
+
+using namespace XSDFrontend::SemanticGraph;
+
+//
+//
+typedef
+boost::filesystem::wifstream
+WideInputFileStream;
+
+typedef
+boost::filesystem::wofstream
+WideOutputFileStream;
+
+namespace CXX
+{
+ namespace
+ {
+ Char const copyright_gpl[] =
+ "// Copyright (C) 2005-2009 Code Synthesis Tools CC\n"
+ "//\n"
+ "// This program was generated by CodeSynthesis XSD, an XML Schema to\n"
+ "// C++ data binding compiler.\n"
+ "//\n"
+ "// This program is free software; you can redistribute it and/or modify\n"
+ "// it under the terms of the GNU General Public License version 2 as\n"
+ "// published by the Free Software Foundation.\n"
+ "//\n"
+ "// This program is distributed in the hope that it will be useful,\n"
+ "// but WITHOUT ANY WARRANTY; without even the implied warranty of\n"
+ "// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n"
+ "// GNU General Public License for more details.\n"
+ "//\n"
+ "// You should have received a copy of the GNU General Public License\n"
+ "// along with this program; if not, write to the Free Software\n"
+ "// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA\n"
+ "//\n"
+ "// In addition, as a special exception, Code Synthesis Tools CC gives\n"
+ "// permission to link this program with the Xerces-C++ library (or with\n"
+ "// modified versions of Xerces-C++ that use the same license as Xerces-C++),\n"
+ "// and distribute linked combinations including the two. You must obey\n"
+ "// the GNU General Public License version 2 in all respects for all of\n"
+ "// the code used other than Xerces-C++. If you modify this copy of the\n"
+ "// program, you may extend this exception to your version of the program,\n"
+ "// but you are not obligated to do so. If you do not wish to do so, delete\n"
+ "// this exception statement from your version.\n"
+ "//\n"
+ "// Furthermore, Code Synthesis Tools CC makes a special exception for\n"
+ "// the Free/Libre and Open Source Software (FLOSS) which is described\n"
+ "// in the accompanying FLOSSE file.\n"
+ "//\n\n";
+
+ Char const copyright_proprietary[] =
+ "// Copyright (C) 2005-2009 Code Synthesis Tools CC\n"
+ "//\n"
+ "// This program was generated by CodeSynthesis XSD, an XML Schema\n"
+ "// to C++ data binding compiler, in the Proprietary License mode.\n"
+ "// You should have received a proprietary license from Code Synthesis\n"
+ "// Tools CC prior to generating this code. See the license text for\n"
+ "// conditions.\n"
+ "//\n\n";
+ }
+
+ namespace Tree
+ {
+ namespace CLI
+ {
+ extern Key char_type = "char-type";
+ extern Key output_dir = "output-dir";
+ extern Key generate_polymorphic = "generate-polymorphic";
+ extern Key generate_serialization = "generate-serialization";
+ extern Key generate_inline = "generate-inline";
+ extern Key generate_ostream = "generate-ostream";
+ extern Key generate_doxygen = "generate-doxygen";
+ extern Key generate_comparison = "generate-comparison";
+ extern Key generate_default_ctor = "generate-default-ctor";
+ extern Key generate_from_base_ctor = "generate-from-base-ctor";
+ extern Key generate_wildcard = "generate-wildcard";
+ extern Key generate_insertion = "generate-insertion";
+ extern Key generate_extraction = "generate-extraction";
+ extern Key generate_forward = "generate-forward";
+ extern Key generate_xml_schema = "generate-xml-schema";
+ extern Key extern_xml_schema = "extern-xml-schema";
+ extern Key suppress_parsing = "suppress-parsing";
+ extern Key generate_element_type = "generate-element-type";
+ extern Key generate_element_map = "generate-element-map";
+ extern Key generate_intellisense = "generate-intellisense";
+ extern Key omit_default_attributes = "omit-default-attributes";
+ extern Key namespace_map = "namespace-map";
+ extern Key namespace_regex = "namespace-regex";
+ extern Key namespace_regex_trace = "namespace-regex-trace";
+ extern Key reserved_name = "reserved-name";
+ extern Key type_naming = "type-naming";
+ extern Key function_naming = "function-naming";
+ extern Key type_regex = "type-regex";
+ extern Key accessor_regex = "accessor-regex";
+ extern Key one_accessor_regex = "one-accessor-regex";
+ extern Key opt_accessor_regex = "opt-accessor-regex";
+ extern Key seq_accessor_regex = "seq-accessor-regex";
+ extern Key modifier_regex = "modifier-regex";
+ extern Key one_modifier_regex = "one-modifier-regex";
+ extern Key opt_modifier_regex = "opt-modifier-regex";
+ extern Key seq_modifier_regex = "seq-modifier-regex";
+ extern Key parser_regex = "parser-regex";
+ extern Key serializer_regex = "serializer-regex";
+ extern Key enumerator_regex = "enumerator-regex";
+ extern Key element_type_regex = "element-type-regex";
+ extern Key name_regex_trace = "name-regex-trace";
+ extern Key include_with_brackets = "include-with-brackets";
+ extern Key include_prefix = "include-prefix";
+ extern Key include_regex = "include-regex";
+ extern Key include_regex_trace = "include-regex-trace";
+ extern Key guard_prefix = "guard-prefix";
+ extern Key root_element_first = "root-element-first";
+ extern Key root_element_last = "root-element-last";
+ extern Key root_element_all = "root-element-all";
+ extern Key root_element_none = "root-element-none";
+ extern Key root_element = "root-element";
+ extern Key custom_type = "custom-type";
+ extern Key custom_type_regex = "custom-type-regex";
+ extern Key hxx_suffix = "hxx-suffix";
+ extern Key ixx_suffix = "ixx-suffix";
+ extern Key cxx_suffix = "cxx-suffix";
+ extern Key fwd_suffix = "fwd-suffix";
+ extern Key hxx_regex = "hxx-regex";
+ extern Key ixx_regex = "ixx-regex";
+ extern Key cxx_regex = "cxx-regex";
+ extern Key fwd_regex = "fwd-regex";
+ extern Key hxx_prologue = "hxx-prologue";
+ extern Key ixx_prologue = "ixx-prologue";
+ extern Key cxx_prologue = "cxx-prologue";
+ extern Key fwd_prologue = "fwd-prologue";
+ extern Key prologue = "prologue";
+ extern Key hxx_epilogue = "hxx-epilogue";
+ extern Key ixx_epilogue = "ixx-epilogue";
+ extern Key cxx_epilogue = "cxx-epilogue";
+ extern Key fwd_epilogue = "fwd-epilogue";
+ extern Key epilogue = "epilogue";
+ extern Key hxx_prologue_file = "hxx-prologue-file";
+ extern Key ixx_prologue_file = "ixx-prologue-file";
+ extern Key cxx_prologue_file = "cxx-prologue-file";
+ extern Key fwd_prologue_file = "fwd-prologue-file";
+ extern Key prologue_file = "prologue-file";
+ extern Key hxx_epilogue_file = "hxx-epilogue-file";
+ extern Key ixx_epilogue_file = "ixx-epilogue-file";
+ extern Key cxx_epilogue_file = "cxx-epilogue-file";
+ extern Key fwd_epilogue_file = "fwd-epilogue-file";
+ extern Key epilogue_file = "epilogue-file";
+ extern Key parts = "parts";
+ extern Key parts_suffix = "parts-suffix";
+ extern Key export_symbol = "export-symbol";
+ extern Key export_xml_schema = "export-xml-schema";
+ extern Key export_maps = "export-maps";
+ extern Key import_maps = "import-maps";
+ extern Key show_anonymous = "show-anonymous";
+ extern Key show_sloc = "show-sloc";
+ extern Key proprietary_license = "proprietary-license";
+ extern Key disable_multi_import = "disable-multi-import";
+ }
+ }
+
+ Void Tree::Generator::
+ usage ()
+ {
+ std::wostream& e (wcerr);
+ ::CLI::Indent::Clip< ::CLI::OptionsUsage, WideChar> clip (e);
+
+ e << "--char-type <type>" << endl
+ << " Use <type> as the base character type. Valid\n"
+ << " values are 'char' (default) and 'wchar_t'."
+ << endl;
+
+ e << "--output-dir <dir>" << endl
+ << " Write generated files to <dir> instead of current\n"
+ << " directory."
+ << endl;
+
+
+ e << "--generate-polymorphic" << endl
+ << " Generate polymorphism-aware code. Specify this\n"
+ << " option if you use substitution groups or xsi:type."
+ << endl;
+
+ e << "--generate-serialization" << endl
+ << " Generate serialization functions. They convert an\n"
+ << " in-memory representation back to XML."
+ << endl;
+
+ e << "--generate-inline" << endl
+ << " Generate certain functions inline."
+ << endl;
+
+ e << "--generate-ostream" << endl
+ << " Generate ostream insertion operators."
+ << endl;
+
+ e << "--generate-doxygen" << endl
+ << " Generate documentation comments in the Doxygen\n"
+ << " format."
+ << endl;
+
+ e << "--generate-comparison" << endl
+ << " Generate comparison operators."
+ << endl;
+
+ e << "--generate-default-ctor" << endl
+ << " Generate default constructors even for types that\n"
+ << " have required members."
+ << endl;
+
+ e << "--generate-from-base-ctor" << endl
+ << " Generate from-base constructors."
+ << endl;
+
+ e << "--generate-wildcard" << endl
+ << " Generate accessors/modifiers as well as parsing\n"
+ << " and serialization code for XML Schema wildcards."
+ << endl;
+
+ e << "--generate-insertion <os>" << endl
+ << " Generate data representation stream insertion\n"
+ << " operators for the <os> output stream type."
+ << endl;
+
+ e << "--generate-extraction <is>" << endl
+ << " Generate data representation stream extraction\n"
+ << " constructors for the <is> input stream type."
+ << endl;
+
+ e << "--generate-forward" << endl
+ << " Generate forward declaration file."
+ << endl;
+
+ e << "--generate-xml-schema" << endl
+ << " Generate a C++ header file as if the schema being\n"
+ << " compiled defines the XML Schema namespace."
+ << endl;
+
+ e << "--extern-xml-schema <file>" << endl
+ << " Generate code as if the XML Schema namespace was\n"
+ << " defined in <file> and xsd:included in the schema\n"
+ << " being compiled."
+ << endl;
+
+ e << "--suppress-parsing" << endl
+ << " Suppress the generation of parsing functions."
+ << endl;
+
+ e << "--generate-element-type" << endl
+ << " Generate types instead of parsing/serialization\n"
+ << " functions for root elements."
+ << endl;
+
+ e << "--generate-element-map" << endl
+ << " Generate a root element map that allows uniform\n"
+ << " parsing/serialization of multiple root elements.\n"
+ << endl;
+
+ e << "--generate-intellisense" << endl
+ << " Generate workarounds for IntelliSense bugs in\n"
+ << " Visual Studio 2005 (8.0)."
+ << endl;
+
+ e << "--omit-default-attributes" << endl
+ << " Omit attributes with default and fixed values\n"
+ << " from serialized XML documents."
+ << endl;
+
+ e << "--namespace-map <xns>=<cns>" << endl
+ << " Map XML Schema namespace <xns> to C++ namespace\n"
+ << " <cns>. Repeat this option to specify mapping for\n"
+ << " more than one XML Schema namespace."
+ << endl;
+
+ e << "--namespace-regex <regex>" << endl
+ << " Add <regex> to the list of regular expressions\n"
+ << " used to translate XML Schema namespace names to\n"
+ << " C++ namespace names."
+ << endl;
+
+ e << "--namespace-regex-trace" << endl
+ << " Trace the process of applying regular expressions\n"
+ << " specified with the --namespace-regex option."
+ << endl;
+
+ e << "--reserved-name <name>" << endl
+ << " Add <name> to the list of names that should not\n"
+ << " be used as identifiers. The name can optionally\n"
+ << " be followed by '=' and the replacement name that\n"
+ << " should be used instead."
+ << endl;
+
+ e << "--type-naming <style>" << endl
+ << " Specify the type naming convention that should be\n"
+ << " used in the generated code. Valid styles are 'knr'\n"
+ << " (default), 'ucc', and 'java'."
+ << endl;
+
+ e << "--function-naming <style>" << endl
+ << " Specify the function naming convention that should\n"
+ << " be used in the generated code. Valid styles are\n"
+ << " 'knr' (default), 'lcc', and 'java'."
+ << endl;
+
+ e << "--type-regex <expr>" << endl
+ << " Add <expr> to the list of regular expressions\n"
+ << " used to translate XML Schema type names to C++\n"
+ << " type names."
+ << endl;
+
+ e << "--accessor-regex <expr>" << endl
+ << " Add <expr> to the list of regular expressions\n"
+ << " used to translate XML Schema names of elements and\n"
+ << " attributes to C++ accessor function names."
+ << endl;
+
+ e << "--one-accessor-regex <expr>" << endl
+ << " Add <expr> to the list of regular expressions\n"
+ << " used to translate XML Schema names of elements\n"
+ << " and attributes with cardinality one to C++\n"
+ << " accessor function names."
+ << endl;
+
+ e << "--opt-accessor-regex <expr>" << endl
+ << " Add <expr> to the list of regular expressions\n"
+ << " used to translate XML Schema names of elements\n"
+ << " and attributes with cardinality optional to C++\n"
+ << " accessor function names."
+ << endl;
+
+ e << "--seq-accessor-regex <expr>" << endl
+ << " Add <expr> to the list of regular expressions\n"
+ << " used to translate XML Schema names of elements\n"
+ << " and attributes with cardinality sequence to C++\n"
+ << " accessor function names."
+ << endl;
+
+ e << "--modifier-regex <expr>" << endl
+ << " Add <expr> to the list of regular expressions\n"
+ << " used to translate XML Schema names of elements and\n"
+ << " attributes to C++ modifier function names."
+ << endl;
+
+ e << "--one-modifier-regex <expr>" << endl
+ << " Add <expr> to the list of regular expressions\n"
+ << " used to translate XML Schema names of elements\n"
+ << " and attributes with cardinality one to C++\n"
+ << " modifier function names."
+ << endl;
+
+ e << "--opt-modifier-regex <expr>" << endl
+ << " Add <expr> to the list of regular expressions\n"
+ << " used to translate XML Schema names of elements\n"
+ << " and attributes with cardinality optional to C++\n"
+ << " modifier function names."
+ << endl;
+
+ e << "--seq-modifier-regex <expr>" << endl
+ << " Add <expr> to the list of regular expressions\n"
+ << " used to translate XML Schema names of elements\n"
+ << " and attributes with cardinality sequence to C++\n"
+ << " modifier function names."
+ << endl;
+
+ e << "--parser-regex <expr>" << endl
+ << " Add <expr> to the list of regular expressions\n"
+ << " used to translate XML Schema element names to\n"
+ << " C++ parsing function names."
+ << endl;
+
+ e << "--serializer-regex <expr>" << endl
+ << " Add <expr> to the list of regular expressions\n"
+ << " used to translate XML Schema element names to\n"
+ << " C++ serialization function names."
+ << endl;
+
+ e << "--enumerator-regex <expr>" << endl
+ << " Add <expr> to the list of regular expressions\n"
+ << " used to translate XML Schema enumeration values\n"
+ << " to C++ enumerator names."
+ << endl;
+
+ e << "--element-type-regex <expr>" << endl
+ << " Add <expr> to the list of regular expressions\n"
+ << " used to translate XML Schema element names to\n"
+ << " C++ element type names."
+ << endl;
+
+ e << "--name-regex-trace" << endl
+ << " Trace the process of applying regular expressions\n"
+ << " specified with the name transformation options."
+ << endl;
+
+ e << "--include-with-brackets" << endl
+ << " Use angle brackets (<>) instead of quotes (\"\") in\n"
+ << " generated #include directives."
+ << endl;
+
+ e << "--include-prefix <prefix>" << endl
+ << " Add <prefix> to generated #include directive\n"
+ << " paths."
+ << endl;
+
+ e << "--include-regex <regex>" << endl
+ << " Add <regex> to the list of regular expressions\n"
+ << " used to transform #include directive paths."
+ << endl;
+
+ e << "--include-regex-trace" << endl
+ << " Trace the process of applying regular expressions\n"
+ << " specified with the --include-regex option."
+ << endl;
+
+ e << "--guard-prefix <prefix>" << endl
+ << " Add <prefix> to generated header inclusion guards."
+ << endl;
+
+ e << "--root-element-first" << endl
+ << " Treat only the first global element as a document\n"
+ << " root."
+ << endl;
+
+ e << "--root-element-last" << endl
+ << " Treat only the last global element as a document\n"
+ << " root."
+ << endl;
+
+ e << "--root-element-all" << endl
+ << " Treat all global elements as document roots."
+ << endl;
+
+ e << "--root-element-none" << endl
+ << " Don't treat any global elements as document roots."
+ << endl;
+
+ e << "--root-element <element>" << endl
+ << " Treat only <element> as a document root. Repeat\n"
+ << " this option to specify more than one root element."
+ << endl;
+
+ e << "--custom-type <map>" << endl
+ << " Use a custom C++ type instead of the generated\n"
+ << " class. The <map> argument is in the form\n"
+ << " name[=type[/base]], where <name> is a type name as\n"
+ << " defined in XML Schema, <type> is a C++ type name\n"
+ << " that should be used instead, and optional <base>\n"
+ << " is a C++ name that should be given to the C++\n"
+ << " class generated from the XML Schema definition\n"
+ << " which is normally used as a base for the custom\n"
+ << " type."
+ << endl;
+
+ e << "--custom-type-regex <regex>" << endl
+ << " Use custom C++ types instead of the generated\n"
+ << " classes. The <regex> argument is in the form\n"
+ << " /name/[type/[base/]], where <name> is a regex\n"
+ << " pattern that will be matched against type names\n"
+ << " as defined in XML Schema, <type> is a C++ type\n"
+ << " name that should be used instead, and optional\n"
+ << " <base> is a C++ name that should be given to\n"
+ << " the C++ class generated from the XML Schema\n"
+ << " definition."
+ << endl;
+
+ e << "--hxx-suffix <suffix>" << endl
+ << " Use <suffix> instead of the default '.hxx' to\n"
+ << " construct the name of the header file."
+ << endl;
+
+ e << "--ixx-suffix <suffix>" << endl
+ << " Use <suffix> instead of the default '.ixx' to\n"
+ << " construct the name of the inline file."
+ << endl;
+
+ e << "--cxx-suffix <suffix>" << endl
+ << " Use <suffix> instead of the default '.cxx' to\n"
+ << " construct the name of the source file."
+ << endl;
+
+ e << "--fwd-suffix <suffix>" << endl
+ << " Use <suffix> instead of the default '-fwd.hxx'\n"
+ << " to construct the name of the forward declaration\n"
+ << " file."
+ << endl;
+
+ e << "--hxx-regex <regex>" << endl
+ << " Use <regex> to construct the name of the header\n"
+ << " file."
+ << endl;
+
+ e << "--ixx-regex <regex>" << endl
+ << " Use <regex> to construct the name of the inline\n"
+ << " file."
+ << endl;
+
+ e << "--cxx-regex <regex>" << endl
+ << " Use <regex> to construct the name of the source\n"
+ << " file."
+ << endl;
+
+ e << "--fwd-regex <regex>" << endl
+ << " Use <regex> to construct the name of the forward\n"
+ << " declaration file."
+ << endl;
+
+ // Prologues.
+ //
+ e << "--hxx-prologue <text>" << endl
+ << " Insert <text> at the beginning of the header file."
+ << endl;
+
+ e << "--ixx-prologue <text>" << endl
+ << " Insert <text> at the beginning of the inline file."
+ << endl;
+
+ e << "--cxx-prologue <text>" << endl
+ << " Insert <text> at the beginning of the source file."
+ << endl;
+
+ e << "--fwd-prologue <text>" << endl
+ << " Insert <text> at the beginning of the forward\n"
+ << " declaration file."
+ << endl;
+
+ e << "--prologue <text>" << endl
+ << " Insert <text> at the beginning of each generated\n"
+ << " file for which there is no file-specific prologue."
+ << endl;
+
+
+ // Epilogues.
+ //
+ e << "--hxx-epilogue <text>" << endl
+ << " Insert <text> at the end of the header file."
+ << endl;
+
+ e << "--ixx-epilogue <text>" << endl
+ << " Insert <text> at the end of the inline file."
+ << endl;
+
+ e << "--cxx-epilogue <text>" << endl
+ << " Insert <text> at the end of the source file."
+ << endl;
+
+ e << "--fwd-epilogue <text>" << endl
+ << " Insert <text> at the end of the forward\n"
+ << " declaration file."
+ << endl;
+
+ e << "--epilogue <text>" << endl
+ << " Insert <text> at the end of each generated file\n"
+ << " for which there is no file-specific epilogue."
+ << endl;
+
+
+ // Prologue files.
+ //
+ e << "--hxx-prologue-file <file>" << endl
+ << " Insert the content of the <file> at the beginning\n"
+ << " of the header file."
+ << endl;
+
+ e << "--ixx-prologue-file <file>" << endl
+ << " Insert the content of the <file> at the beginning\n"
+ << " of the inline file."
+ << endl;
+
+ e << "--cxx-prologue-file <file>" << endl
+ << " Insert the content of the <file> at the beginning\n"
+ << " of the source file."
+ << endl;
+
+ e << "--fwd-prologue-file <file>" << endl
+ << " Insert the content of the <file> at the beginning\n"
+ << " of the forward declaration file."
+ << endl;
+
+ e << "--prologue-file <file>" << endl
+ << " Insert the content of the <file> at the beginning\n"
+ << " of each generated file for which there is no file-\n"
+ << " specific prologue file."
+ << endl;
+
+ // Epilogue files.
+ //
+ e << "--hxx-epilogue-file <file>" << endl
+ << " Insert the content of the <file> at the end of\n"
+ << " the header file."
+ << endl;
+
+ e << "--ixx-epilogue-file <file>" << endl
+ << " Insert the content of the <file> at the end of\n"
+ << " the inline file."
+ << endl;
+
+ e << "--cxx-epilogue-file <file>" << endl
+ << " Insert the content of the <file> at the end of\n"
+ << " the source file."
+ << endl;
+
+ e << "--fwd-epilogue-file <file>" << endl
+ << " Insert the content of the <file> at the end of\n"
+ << " the forward declaration file."
+ << endl;
+
+ e << "--epilogue-file <file>" << endl
+ << " Insert the content of the <file> at the end of\n"
+ << " each generated file for which there is no file-\n"
+ << " specific epilogue file."
+ << endl;
+
+ // Misc.
+ //
+ e << "--parts <num>" << endl
+ << " Split generated source code into <num> parts."
+ << endl;
+
+ e << "--parts-suffix <suffix>" << endl
+ << " Use <suffix> instead of the default '-' to\n"
+ << " separate the file name from the part number."
+ << endl;
+
+ e << "--export-symbol <symbol>" << endl
+ << " Export symbol for Win32 DLL export/import control."
+ << endl;
+
+ e << "--export-xml-schema" << endl
+ << " Export/import types in the XML Schema namespace."
+ << endl;
+
+ e << "--export-maps" << endl
+ << " Export polymorphism support maps from Win32 DLL."
+ << endl;
+
+ e << "--import-maps" << endl
+ << " Import polymorphism support maps from Win32 DLL."
+ << endl;
+
+ e << "--show-anonymous" << endl
+ << " Show elements and attributes that are of anonymous\n"
+ << " types."
+ << endl;
+
+ e << "--show-sloc" << endl
+ << " Show the number of generated physical source lines\n"
+ << " of code (SLOC)."
+ << endl;
+
+ e << "--sloc-limit <num>" << endl
+ << " Check that the number of generated physical source\n"
+ << " lines of code (SLOC) does not exceed <num>."
+ << endl;
+
+ e << "--options-file <file>" << endl
+ << " Read additional options from <file>. Each option\n"
+ << " should appear on a separate line optionally\n"
+ << " followed by space and an argument."
+ << endl;
+
+ e << "--proprietary-license" << endl
+ << " Indicate that the generated code is licensed under\n"
+ << " a proprietary license instead of the GPL."
+ << endl;
+ }
+
+ Tree::CLI::OptionsSpec Tree::Generator::
+ options_spec ()
+ {
+ CLI::OptionsSpec spec;
+
+ spec.option<CLI::char_type> ().default_value ("char");
+
+ spec.option<CLI::hxx_suffix> ().default_value (".hxx");
+ spec.option<CLI::ixx_suffix> ().default_value (".ixx");
+ spec.option<CLI::cxx_suffix> ().default_value (".cxx");
+ spec.option<CLI::fwd_suffix> ().default_value ("-fwd.hxx");
+
+ spec.option<CLI::type_naming> ().default_value ("knr");
+ spec.option<CLI::function_naming> ().default_value ("knr");
+
+ spec.option<CLI::parts> ().default_value (1);
+ spec.option<CLI::parts_suffix> ().default_value ("-");
+
+ return spec;
+ }
+
+
+ namespace
+ {
+ Void
+ open (WideInputFileStream& ifs, NarrowString const& path)
+ {
+ try
+ {
+ Path fs_path (path, boost::filesystem::native);
+ ifs.open (fs_path, std::ios_base::in | std::ios_base::binary);
+
+ if (!ifs.is_open ())
+ {
+ wcerr << path.c_str () << ": error: unable to open in read mode"
+ << endl;
+
+ throw Tree::Generator::Failed ();
+ }
+ }
+ catch (InvalidPath const&)
+ {
+ wcerr << "error: '" << path.c_str () << "' is not a valid "
+ << "filesystem path" << endl;
+
+ throw Tree::Generator::Failed ();
+ }
+ }
+
+ Void
+ append (WideOutputFileStream& os,
+ NarrowString const& path,
+ WideInputFileStream& default_is)
+ {
+ using std::ios_base;
+
+ if (path)
+ {
+ WideInputFileStream is;
+ open (is, path);
+ os << is.rdbuf ();
+ }
+ else if (default_is.is_open ())
+ {
+ os << default_is.rdbuf ();
+ default_is.seekg (0, ios_base::beg);
+ }
+ }
+
+ Void
+ append (WideOutputFileStream& os,
+ Cult::Containers::Vector<NarrowString> const& primary,
+ Cult::Containers::Vector<NarrowString> const& def)
+ {
+ Cult::Containers::Vector<NarrowString> const& v (
+ primary.empty () ? def : primary);
+
+ for (Containers::Vector<NarrowString>::ConstIterator
+ i (v.begin ()), e (v.end ()); i != e; ++i)
+ {
+ os << i->c_str () << endl;
+ }
+ }
+ }
+
+
+ UnsignedLong Tree::Generator::
+ generate (Tree::CLI::Options const& ops,
+ Schema& schema,
+ Path const& file_path,
+ const WarningSet& disabled_warnings,
+ FileList& file_list,
+ AutoUnlinks& unlinks)
+ {
+ using std::ios_base;
+ namespace Indentation = BackendElements::Indentation;
+
+ typedef BackendElements::Regex::Expression<Char> Regex;
+
+ using Cult::Containers::Vector;
+
+ typedef Vector<Path> Paths;
+ typedef Vector<Evptr<WideOutputFileStream> > WideOutputFileStreams;
+
+ try
+ {
+ // Do option validation.
+ //
+ if (ops.value<CLI::parts> () < 1)
+ {
+ wcerr << "error: invalid value for option --parts: " <<
+ ops.value<CLI::parts> () << endl;
+ throw Failed ();
+ }
+
+ // Get counts.
+ //
+ Counts counts;
+ {
+ Counter counter;
+ counts = counter.count (ops, schema);
+
+ /*
+ wcerr << "global type count: " << counts.global_types << endl;
+ wcerr << "global element count: " << counts.global_elements << endl;
+ wcerr << "generated global element count: " <<
+ counts.generated_global_elements << endl;
+
+ wcerr << "total complexity: " << counts.complexity_total << endl;
+ wcerr << "complexity vector size: " << counts.complexity.size ()
+ << endl;
+ */
+ }
+
+ // Evaluate the graph for possibility of generating something useful.
+ //
+ {
+ Validator validator;
+ if (!validator.validate (
+ ops, schema, file_path, disabled_warnings, counts))
+ throw Failed ();
+ }
+
+ // Process names.
+ //
+ {
+ NameProcessor proc;
+ if (!proc.process (ops, schema, file_path))
+ throw Failed ();
+ }
+
+ // Parts.
+ //
+ UnsignedLong parts (ops.value<CLI::parts> ());
+ UnsignedLong units (
+ counts.global_types + counts.generated_global_elements);
+
+ UnsignedLong units_per_part (units / parts);
+
+ if (parts != 1 && units_per_part < 1)
+ {
+ wcerr << "error: too many parts specified: " << parts << endl;
+ throw Failed ();
+ }
+
+ UnsignedLong complexity_per_part (counts.complexity_total / parts);
+
+
+ NarrowString parts_suffix (ops.value<CLI::parts_suffix> ());
+
+ //
+ //
+ Boolean generate_xml_schema (ops.value<CLI::generate_xml_schema> ());
+
+ // We could be compiling several schemas at once in which case
+ // handling of the --generate-xml-schema option gets tricky: we
+ // will need to rely on the presence of the --extern-xml-schema
+ // to tell us which (fake) schema file corresponds to XML Schema.
+ //
+ if (generate_xml_schema)
+ {
+ if (NarrowString name = ops.value<CLI::extern_xml_schema> ())
+ {
+ if (file_path.native_file_string () != name)
+ generate_xml_schema = false;
+ }
+ }
+
+ Boolean inline_ (ops.value<CLI::generate_inline> () &&
+ !generate_xml_schema);
+
+ Boolean forward (ops.value<CLI::generate_forward> () &&
+ !generate_xml_schema);
+
+ Boolean source (!generate_xml_schema);
+
+ // Generate code.
+ //
+ NarrowString name (file_path.leaf ());
+
+ NarrowString hxx_suffix (ops.value <CLI::hxx_suffix> ());
+ NarrowString ixx_suffix (ops.value <CLI::ixx_suffix> ());
+ NarrowString cxx_suffix (ops.value <CLI::cxx_suffix> ());
+ NarrowString fwd_suffix (ops.value <CLI::fwd_suffix> ());
+
+ Regex hxx_expr (ops.value <CLI::hxx_regex> ().empty ()
+ ? "#^(.+?)(\\.[^./\\\\]+)?$#$1" + hxx_suffix + "#"
+ : ops.value <CLI::hxx_regex> ());
+
+ Regex ixx_expr (ops.value <CLI::ixx_regex> ().empty ()
+ ? "#^(.+?)(\\.[^./\\\\]+)?$#$1" + ixx_suffix + "#"
+ : ops.value <CLI::ixx_regex> ());
+
+ Regex cxx_expr (ops.value <CLI::cxx_regex> ().empty ()
+ ? "#^(.+?)(\\.[^./\\\\]+)?$#$1" + cxx_suffix + "#"
+ : ops.value <CLI::cxx_regex> ());
+
+ Regex fwd_expr (ops.value <CLI::fwd_regex> ().empty ()
+ ? "#^(.+?)(\\.[^./\\\\]+)?$#$1" + fwd_suffix + "#"
+ : ops.value <CLI::fwd_regex> ());
+
+ if (!hxx_expr.match (name))
+ {
+ wcerr << "error: header expression '" <<
+ hxx_expr.pattern () << "' does not match '" <<
+ name.c_str () << "'" << endl;
+ throw Failed ();
+ }
+
+ if (inline_ && !ixx_expr.match (name))
+ {
+ wcerr << "error: inline expression '" <<
+ ixx_expr.pattern () << "' does not match '" <<
+ name.c_str () << "'" << endl;
+ throw Failed ();
+ }
+
+ if (source && parts == 1 && !cxx_expr.match (name))
+ {
+ wcerr << "error: source expression '" <<
+ cxx_expr.pattern () << "' does not match '" <<
+ name.c_str () << "'" << endl;
+ throw Failed ();
+ }
+
+ if (forward && !fwd_expr.match (name))
+ {
+ wcerr << "error: forward expression '" <<
+ fwd_expr.pattern () << "' does not match '" <<
+ name.c_str () << "'" << endl;
+ throw Failed ();
+ }
+
+ NarrowString hxx_name (hxx_expr.merge (name));
+ NarrowString ixx_name (inline_ ? ixx_expr.merge (name) : NarrowString ());
+ NarrowString fwd_name (forward ? fwd_expr.merge (name) : NarrowString ());
+
+ Path hxx_path (hxx_name, boost::filesystem::native);
+ Path ixx_path (ixx_name, boost::filesystem::native);
+ Path fwd_path (fwd_name, boost::filesystem::native);
+ Paths cxx_paths;
+
+ if (source)
+ {
+ if (parts > 1)
+ {
+ for (UnsignedLong i (0); i < parts; ++i)
+ {
+ std::ostringstream os;
+ os << i;
+
+ Regex expr (
+ "#^(.+?)(\\.[^./\\\\]+)?$#$1" + parts_suffix + os.str () + "$2#");
+
+ NarrowString part_name (expr.merge (name));
+
+ if (!cxx_expr.match (part_name))
+ {
+ wcerr << "error: source expression '" <<
+ cxx_expr.pattern () << "' does not match '" <<
+ part_name.c_str () << "'" << endl;
+ throw Failed ();
+ }
+
+ cxx_paths.push_back (
+ Path (cxx_expr.merge (part_name), boost::filesystem::native));
+ }
+ }
+ else
+ cxx_paths.push_back (
+ Path (cxx_expr.merge (name), boost::filesystem::native));
+ }
+
+ if (NarrowString dir = ops.value<CLI::output_dir> ())
+ {
+ try
+ {
+ Path path (dir, boost::filesystem::native);
+
+ hxx_path = path / hxx_path;
+ ixx_path = path / ixx_path;
+ fwd_path = path / fwd_path;
+
+ for (Paths::Iterator i (cxx_paths.begin ());
+ i != cxx_paths.end (); ++i)
+ *i = path / *i;
+ }
+ catch (InvalidPath const&)
+ {
+ wcerr << dir.c_str () << ": error: invalid path" << endl;
+ throw Failed ();
+ }
+ }
+
+ //
+ //
+ WideOutputFileStream hxx (hxx_path, ios_base::out);
+ WideOutputFileStream ixx;
+ WideOutputFileStream fwd;
+ WideOutputFileStreams cxx;
+
+
+ // FWD
+ //
+ if (forward)
+ {
+ fwd.open (fwd_path, ios_base::out);
+
+ if (!fwd.is_open ())
+ {
+ wcerr << fwd_path << ": error: unable to open in write mode" << endl;
+ throw Failed ();
+ }
+
+ unlinks.add (fwd_path);
+ file_list.push_back (fwd_path.native_file_string ());
+ }
+
+
+ // HXX
+ //
+ if (!hxx.is_open ())
+ {
+ wcerr << hxx_path << ": error: unable to open in write mode" << endl;
+ throw Failed ();
+ }
+
+ unlinks.add (hxx_path);
+ file_list.push_back (hxx_path.native_file_string ());
+
+
+ // IXX
+ //
+ if (inline_)
+ {
+ ixx.open (ixx_path, ios_base::out);
+
+ if (!ixx.is_open ())
+ {
+ wcerr << ixx_path << ": error: unable to open in write mode" << endl;
+ throw Failed ();
+ }
+
+ unlinks.add (ixx_path);
+ file_list.push_back (ixx_path.native_file_string ());
+ }
+
+
+ // CXX
+ //
+ if (source)
+ {
+ for (Paths::Iterator i (cxx_paths.begin ());
+ i != cxx_paths.end (); ++i)
+ {
+ Evptr<WideOutputFileStream> s (
+ new WideOutputFileStream (*i, ios_base::out));
+
+ if (!s->is_open ())
+ {
+ wcerr << *i << ": error: unable to open in write mode" << endl;
+ throw Failed ();
+ }
+
+ unlinks.add (*i);
+ file_list.push_back (i->native_file_string ());
+ cxx.push_back (s);
+ }
+ }
+
+
+ // Print copyright and license.
+ //
+ Char const* copyright (
+ ops.value<CLI::proprietary_license> ()
+ ? copyright_proprietary
+ : copyright_gpl);
+
+ if (forward)
+ fwd << copyright;
+
+ hxx << copyright;
+
+ if (ops.value<CLI::generate_doxygen> ())
+ {
+ // Use native path format.
+ //
+ hxx << "/**" << endl
+ << " * @file" << endl
+ << " * @brief Generated from " << name.c_str () << "." << endl
+ << " */" << endl
+ << endl;
+
+ }
+
+ if (inline_)
+ ixx << copyright;
+
+ if (source)
+ {
+ for (WideOutputFileStreams::Iterator i (cxx.begin ());
+ i != cxx.end (); ++i)
+ **i << copyright;
+ }
+
+
+ // Prologue.
+ //
+ WideInputFileStream prologue;
+ {
+ NarrowString name (ops.value<CLI::prologue_file> ());
+
+ if (name)
+ open (prologue, name);
+ }
+
+ // Epilogue.
+ //
+ WideInputFileStream epilogue;
+ {
+ NarrowString name (ops.value<CLI::epilogue_file> ());
+
+ if (name)
+ open (epilogue, name);
+ }
+
+ // SLOC counter.
+ //
+ UnsignedLong sloc (0);
+ Boolean show_sloc (ops.value<CLI::show_sloc> ());
+
+ //
+ //
+ Regex guard_expr ("/([a-z])([A-Z])/$1_$2/"); // Split words.
+ NarrowString guard_prefix (ops.value<CLI::guard_prefix> ());
+
+ if (!guard_prefix)
+ guard_prefix = file_path.branch_path ().native_directory_string ();
+
+ if (guard_prefix)
+ guard_prefix += '_';
+
+ // FWD
+ //
+ if (forward)
+ {
+ Context ctx (fwd, schema, ops, counts, generate_xml_schema,
+ &fwd_expr, &hxx_expr, &ixx_expr);
+
+ Indentation::Clip<Indentation::SLOC, WideChar> fwd_sloc (fwd);
+
+ // Guard
+ //
+ String guard (guard_expr.merge (guard_prefix + fwd_name));
+ guard = ctx.escape (guard); // make a c++ id
+ std::transform (guard.begin (), guard.end(), guard.begin (), upcase);
+
+ fwd << "#ifndef " << guard << endl
+ << "#define " << guard << endl
+ << endl;
+
+ // Copy prologue.
+ //
+ fwd << "// Begin prologue." << endl
+ << "//" << endl;
+
+ append (fwd,
+ ops.value<CLI::fwd_prologue> (),
+ ops.value<CLI::prologue> ());
+ append (fwd, ops.value<CLI::fwd_prologue_file> (), prologue);
+
+ fwd << "//" << endl
+ << "// End prologue." << endl
+ << endl;
+
+ // Version check.
+ //
+ fwd << "#include <xsd/cxx/version.hxx>" << endl
+ << endl
+ << "#if (XSD_INT_VERSION != " << XSD_INT_VERSION << "L)" << endl
+ << "#error XSD runtime version mismatch" << endl
+ << "#endif" << endl
+
+ << endl;
+ {
+ fwd << "#include <xsd/cxx/pre.hxx>" << endl
+ << endl;
+
+ if (ctx.char_type == L"char")
+ {
+ fwd << "#ifndef XSD_USE_CHAR" << endl
+ << "#define XSD_USE_CHAR" << endl
+ << "#endif" << endl
+ << endl;
+
+ fwd << "#ifndef XSD_CXX_TREE_USE_CHAR" << endl
+ << "#define XSD_CXX_TREE_USE_CHAR" << endl
+ << "#endif" << endl
+ << endl;
+ }
+ else if (ctx.char_type == L"wchar_t")
+ {
+ fwd << "#ifndef XSD_USE_WCHAR" << endl
+ << "#define XSD_USE_WCHAR" << endl
+ << "#endif" << endl
+ << endl;
+
+ fwd << "#ifndef XSD_CXX_TREE_USE_WCHAR" << endl
+ << "#define XSD_CXX_TREE_USE_WCHAR" << endl
+ << "#endif" << endl
+ << endl;
+ }
+
+ // Set auto-indentation.
+ //
+ Indentation::Clip<Indentation::CXX, WideChar> fwd_clip (fwd);
+
+
+ // Generate.
+ //
+ generate_forward (ctx);
+
+ fwd << "#include <xsd/cxx/post.hxx>" << endl
+ << endl;
+ }
+
+ // Copy epilogue.
+ //
+ fwd << "// Begin epilogue." << endl
+ << "//" << endl;
+
+ append (fwd, ops.value<CLI::fwd_epilogue_file> (), epilogue);
+ append (fwd,
+ ops.value<CLI::fwd_epilogue> (),
+ ops.value<CLI::epilogue> ());
+
+ fwd << "//" << endl
+ << "// End epilogue." << endl
+ << endl;
+
+ fwd << "#endif // " << guard << endl;
+
+ if (show_sloc)
+ {
+ wcerr << fwd_path << ": "
+ << fwd_sloc.buffer ().count () << endl;
+
+ sloc += fwd_sloc.buffer ().count ();
+ }
+ }
+
+ // HXX
+ //
+ {
+ Context ctx (hxx, schema, ops, counts, generate_xml_schema,
+ &fwd_expr, &hxx_expr, &ixx_expr);
+
+ Indentation::Clip<Indentation::SLOC, WideChar> hxx_sloc (hxx);
+
+ // Guard
+ //
+ String guard (guard_expr.merge (guard_prefix + hxx_name));
+ guard = ctx.escape (guard); // make a c++ id
+ std::transform (guard.begin (), guard.end(), guard.begin (), upcase);
+
+ hxx << "#ifndef " << guard << endl
+ << "#define " << guard << endl
+ << endl;
+
+ // Copy prologue.
+ //
+ hxx << "// Begin prologue." << endl
+ << "//" << endl;
+
+ append (
+ hxx, ops.value<CLI::hxx_prologue> (), ops.value<CLI::prologue> ());
+ append (hxx, ops.value<CLI::hxx_prologue_file> (), prologue);
+
+ hxx << "//" << endl
+ << "// End prologue." << endl
+ << endl;
+
+ // Version check.
+ //
+ hxx << "#include <xsd/cxx/config.hxx>" << endl
+ << endl
+ << "#if (XSD_INT_VERSION != " << XSD_INT_VERSION << "L)" << endl
+ << "#error XSD runtime version mismatch" << endl
+ << "#endif" << endl
+ << endl;
+
+ {
+ hxx << "#include <xsd/cxx/pre.hxx>" << endl
+ << endl;
+
+ // Generate character selection defines.
+ //
+ if (!forward)
+ {
+ if (ctx.char_type == L"char")
+ {
+ hxx << "#ifndef XSD_USE_CHAR" << endl
+ << "#define XSD_USE_CHAR" << endl
+ << "#endif" << endl
+ << endl;
+
+ hxx << "#ifndef XSD_CXX_TREE_USE_CHAR" << endl
+ << "#define XSD_CXX_TREE_USE_CHAR" << endl
+ << "#endif" << endl
+ << endl;
+ }
+ else if (ctx.char_type == L"wchar_t")
+ {
+ hxx << "#ifndef XSD_USE_WCHAR" << endl
+ << "#define XSD_USE_WCHAR" << endl
+ << "#endif" << endl
+ << endl;
+
+ hxx << "#ifndef XSD_CXX_TREE_USE_WCHAR" << endl
+ << "#define XSD_CXX_TREE_USE_WCHAR" << endl
+ << "#endif" << endl
+ << endl;
+ }
+ }
+
+ // Set auto-indentation.
+ //
+ Indentation::Clip<Indentation::CXX, WideChar> hxx_clip (hxx);
+
+
+ // Generate.
+ //
+ if (!generate_xml_schema)
+ {
+ if (forward)
+ hxx << "#include " << ctx.process_include_path (fwd_name)
+ << endl << endl;
+ else
+ generate_forward (ctx);
+ }
+
+ generate_tree_header (ctx);
+
+ if (!generate_xml_schema)
+ {
+
+ if (ops.value<CLI::generate_ostream> ())
+ generate_stream_header (ctx);
+
+ if (!ops.value<CLI::generate_element_type> () &&
+ !ops.value<CLI::suppress_parsing> ())
+ generate_parser_header (ctx);
+
+ if (ops.value<CLI::generate_serialization> ())
+ generate_serialization_header (ctx);
+
+ if (!ops.value<CLI::generate_insertion> ().empty ())
+ generate_stream_insertion_header (ctx);
+ }
+
+ if (inline_)
+ {
+ hxx << "#ifndef XSD_DONT_INCLUDE_INLINE" << endl
+ << "#include " << ctx.process_include_path (ixx_name) << endl
+ << "#endif // XSD_DONT_INCLUDE_INLINE" << endl
+ << endl;
+ }
+
+ hxx << "#include <xsd/cxx/post.hxx>" << endl
+ << endl;
+ }
+
+ // Copy epilogue.
+ //
+ hxx << "// Begin epilogue." << endl
+ << "//" << endl;
+
+ append (hxx, ops.value<CLI::hxx_epilogue_file> (), epilogue);
+ append (
+ hxx, ops.value<CLI::hxx_epilogue> (), ops.value<CLI::epilogue> ());
+
+ hxx << "//" << endl
+ << "// End epilogue." << endl
+ << endl;
+
+ hxx << "#endif // " << guard << endl;
+
+ if (show_sloc)
+ {
+ wcerr << hxx_path << ": "
+ << hxx_sloc.buffer ().count () << endl;
+
+ sloc += hxx_sloc.buffer ().count ();
+ }
+ }
+
+
+ // IXX
+ //
+ if (inline_)
+ {
+ Context ctx (ixx, schema, ops, counts, generate_xml_schema,
+ &fwd_expr, &hxx_expr, &ixx_expr);
+
+ Indentation::Clip<Indentation::SLOC, WideChar> ixx_sloc (ixx);
+
+ // Guard
+ //
+ String guard (guard_expr.merge (guard_prefix + ixx_name));
+ guard = ctx.escape (guard); // make a c++ id
+ std::transform (guard.begin (), guard.end(), guard.begin (), upcase);
+
+ ixx << "#ifndef " << guard.c_str () << endl
+ << "#define " << guard.c_str () << endl
+ << endl;
+
+ // Copy prologue.
+ //
+ ixx << "// Begin prologue." << endl
+ << "//" << endl;
+
+ append (
+ ixx, ops.value<CLI::ixx_prologue> (), ops.value<CLI::prologue> ());
+ append (ixx, ops.value<CLI::ixx_prologue_file> (), prologue);
+
+ ixx << "//" << endl
+ << "// End prologue." << endl
+ << endl;
+
+ {
+ // Set auto-indentation.
+ //
+ Indentation::Clip<Indentation::CXX, WideChar> ixx_clip (ixx);
+
+
+ // Generate.
+ //
+ generate_tree_inline (ctx, 1, 0);
+ }
+
+ // Copy epilogue.
+ //
+ ixx << "// Begin epilogue." << endl
+ << "//" << endl;
+
+ append (ixx, ops.value<CLI::ixx_epilogue_file> (), epilogue);
+ append (
+ ixx, ops.value<CLI::ixx_epilogue> (), ops.value<CLI::epilogue> ());
+
+ ixx << "//" << endl
+ << "// End epilogue." << endl
+ << endl;
+
+ ixx << "#endif // " << guard.c_str () << endl;
+
+ if (show_sloc)
+ {
+ wcerr << ixx_path << ": "
+ << ixx_sloc.buffer ().count () << endl;
+
+ sloc += ixx_sloc.buffer ().count ();
+ }
+ }
+
+
+ // CXX
+ //
+
+ if (source)
+ {
+ UnsignedLong first_unit (0); // First unit in the current part.
+
+ for (UnsignedLong part (0); part < parts; ++part)
+ {
+ // Figure out the range of units for this part.
+ //
+ UnsignedLong last_unit (first_unit);
+
+ if (units != 0)
+ {
+ UnsignedLong complexity (counts.complexity[last_unit]);
+
+ while (complexity < complexity_per_part)
+ {
+ // Make sure there will be at least one unit for each part left.
+ //
+ if ((last_unit + 1) >= units ||
+ (units - (last_unit + 1) - 1) < (parts - part - 1))
+ break;
+
+ // Check if the increase in complexity should be kept in this
+ // part or moved to the next.
+ //
+ UnsignedLong new_complexity (
+ complexity + counts.complexity[last_unit + 1]);
+
+ if (new_complexity > complexity_per_part)
+ {
+ if ((new_complexity - complexity_per_part) >
+ (counts.complexity[last_unit + 1] / 2))
+ break;
+ }
+
+ last_unit++;
+ complexity = new_complexity;
+ }
+
+ if (part + 1 == parts)
+ {
+ // Last part.
+ //
+ last_unit = units - 1;
+ }
+ }
+
+ //
+ //
+ UnsignedLong first (first_unit);
+ UnsignedLong last (last_unit);
+
+ first_unit = last_unit + 1;
+
+ //wcerr << "[" << first << ", " << last << "]: " << complexity
+ // << endl;
+
+ WideOutputFileStream& os (*cxx[part]);
+
+ Context ctx (os, schema, ops, counts, generate_xml_schema,
+ &fwd_expr, &hxx_expr, &ixx_expr);
+
+ Indentation::Clip<Indentation::SLOC, WideChar> cxx_sloc (os);
+
+ // Copy prologue.
+ //
+ os << "// Begin prologue." << endl
+ << "//" << endl;
+
+ append (os,
+ ops.value<CLI::cxx_prologue> (),
+ ops.value<CLI::prologue> ());
+ append (os, ops.value<CLI::cxx_prologue_file> (), prologue);
+
+ os << "//" << endl
+ << "// End prologue." << endl
+ << endl;
+
+ {
+ os << "#include <xsd/cxx/pre.hxx>" << endl
+ << endl;
+
+ // Set auto-indentation.
+ //
+ Indentation::Clip<Indentation::CXX, WideChar> cxx_clip (os);
+
+
+ // Generate.
+ //
+ os << "#include " << ctx.process_include_path (hxx_name) << endl
+ << endl;
+
+ if (!inline_)
+ generate_tree_inline (ctx, first, last);
+
+ generate_tree_source (ctx, first, last);
+
+ if (ops.value<CLI::generate_ostream> ())
+ generate_stream_source (ctx, first, last);
+
+ if (!ops.value<CLI::generate_element_type> () &&
+ !ops.value<CLI::suppress_parsing> ())
+ generate_parser_source (ctx, first, last);
+
+ if (ops.value<CLI::generate_serialization> ())
+ generate_serialization_source (ctx, first, last);
+
+ if (!ops.value<CLI::generate_extraction> ().empty ())
+ generate_stream_extraction_source (ctx);
+
+ if (!ops.value<CLI::generate_insertion> ().empty ())
+ generate_stream_insertion_source (ctx);
+
+ os << "#include <xsd/cxx/post.hxx>" << endl
+ << endl;
+ }
+
+ // Copy epilogue.
+ //
+ os << "// Begin epilogue." << endl
+ << "//" << endl;
+
+ append (os, ops.value<CLI::cxx_epilogue_file> (), epilogue);
+ append (os,
+ ops.value<CLI::cxx_epilogue> (),
+ ops.value<CLI::epilogue> ());
+
+ os << "//" << endl
+ << "// End epilogue." << endl
+ << endl;
+
+ if (show_sloc)
+ {
+ wcerr << cxx_paths[part] << ": "
+ << cxx_sloc.buffer ().count () << endl;
+
+ sloc += cxx_sloc.buffer ().count ();
+ }
+ }
+ }
+
+ return sloc;
+ }
+ catch (NoNamespaceMapping const& e)
+ {
+ wcerr << e.file () << ":" << e.line () << ":" << e.column ()
+ << ": error: unable to map XML Schema namespace '" << e.ns ()
+ << "' to C++ namespace" << endl;
+
+ wcerr << e.file () << ":" << e.line () << ":" << e.column ()
+ << ": info: use the --namespace-map or --namespace-regex option "
+ << "to provide custom mapping" << endl;
+
+ throw Failed ();
+ }
+ catch (InvalidNamespaceMapping const& e)
+ {
+ wcerr << "error: invalid XML to C++ namespace mapping specified: "
+ << "'" << e.mapping () << "': " << e.reason () << endl;
+
+ throw Failed ();
+ }
+ catch (InvalidCustomTypeMapping const& e)
+ {
+ wcerr << "error: invalid custom type mapping specified: "
+ << "'" << e.mapping () << "': " << e.reason () << endl;
+
+ throw Failed ();
+ }
+ catch (BackendElements::Regex::Format<Char> const& e)
+ {
+ wcerr << "error: invalid regex: '" <<
+ e.expression ().c_str () << "': " <<
+ e.description ().c_str () << endl;
+
+ throw Failed ();
+ }
+ catch (BackendElements::Regex::Format<WideChar> const& e)
+ {
+ wcerr << "error: invalid regex: '" <<
+ e.expression () << "': " << e.description () << endl;
+
+ throw Failed ();
+ }
+ }
+}
diff --git a/xsd/cxx/tree/generator.hxx b/xsd/cxx/tree/generator.hxx
new file mode 100644
index 0000000..1aa3c60
--- /dev/null
+++ b/xsd/cxx/tree/generator.hxx
@@ -0,0 +1,49 @@
+// file : xsd/cxx/tree/generator.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_GENERATOR_HXX
+#define CXX_TREE_GENERATOR_HXX
+
+#include <cult/types.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx> // Path
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <xsd.hxx>
+
+#include <cxx/tree/cli.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ using namespace Cult::Types;
+
+ class Generator
+ {
+ public:
+ static Void
+ usage ();
+
+ static CLI::OptionsSpec
+ options_spec ();
+
+ struct Failed {};
+
+ static UnsignedLong
+ generate (CLI::Options const& options,
+ XSDFrontend::SemanticGraph::Schema&,
+ XSDFrontend::SemanticGraph::Path const& file,
+ const WarningSet& disabled_warnings,
+ FileList& file_list,
+ AutoUnlinks& unlinks);
+
+ private:
+ Generator ();
+ };
+ }
+}
+
+#endif // CXX_TREE_GENERATOR_HXX
diff --git a/xsd/cxx/tree/name-processor.cxx b/xsd/cxx/tree/name-processor.cxx
new file mode 100644
index 0000000..456095f
--- /dev/null
+++ b/xsd/cxx/tree/name-processor.cxx
@@ -0,0 +1,2100 @@
+// file : xsd/cxx/tree/name-processor.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/name-processor.hxx>
+#include <cxx/tree/elements.hxx>
+
+#include <backend-elements/regex.hxx>
+
+#include <cult/containers/set.hxx>
+#include <cult/containers/map.hxx>
+#include <cult/containers/vector.hxx>
+
+#include <sstream>
+#include <iostream>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ NameProcessor::
+ NameProcessor ()
+ {
+ // Dummy ctor, helps with long symbols on HP-UX.
+ }
+
+ namespace
+ {
+ //
+ //
+ typedef Cult::Containers::Set<String> NameSet;
+
+
+
+
+ class Context: public Tree::Context
+ {
+ public:
+ struct Failed {};
+
+ Context (CLI::Options const& options,
+ Counts const& counts,
+ Boolean generate_xml_schema,
+ SemanticGraph::Schema& root,
+ SemanticGraph::Path const& file)
+ : Tree::Context (std::wcerr,
+ root,
+ options,
+ counts,
+ generate_xml_schema,
+ 0,
+ 0,
+ 0),
+ schema_path_ (file),
+ schema_path (schema_path_),
+ global_type_names (global_type_names_),
+ global_element_names (global_element_names_),
+ type_regex (type_regex_),
+ accessor_regex (accessor_regex_),
+ one_accessor_regex (one_accessor_regex_),
+ opt_accessor_regex (opt_accessor_regex_),
+ seq_accessor_regex (seq_accessor_regex_),
+ modifier_regex (modifier_regex_),
+ one_modifier_regex (one_modifier_regex_),
+ opt_modifier_regex (opt_modifier_regex_),
+ seq_modifier_regex (seq_modifier_regex_),
+ parser_regex (parser_regex_),
+ serializer_regex (serializer_regex_),
+ enumerator_regex (enumerator_regex_),
+ element_type_regex (element_type_regex_)
+ {
+ typedef Containers::Vector<NarrowString> Vector;
+
+ NarrowString tn (options.value<CLI::type_naming> ());
+ NarrowString fn (options.value<CLI::function_naming> ());
+
+
+ // Type name regex.
+ //
+ {
+ // Predefined rules. The most frequently used come last: global
+ // names, two components (<name>,type), three components
+ // (<name>,const,iterator), and one component (value in enum).
+ //
+ if (tn == "knr")
+ {
+ type_regex.push_back ("/(?:[^ ]* )?([^,]+),([^,]+),([^,]+),([^,]+)/$1_$2_$3_$4/");
+ type_regex.push_back ("/(?:[^ ]* )?([^,]+),([^,]+),([^,]+)/$1_$2_$3/");
+ type_regex.push_back ("/(?:[^ ]* )?([^,]+),([^,]+)/$1_$2/");
+ type_regex.push_back ("/(?:[^ ]* )?([^,]+)/$1/");
+
+ /*
+ type_regex.push_back ("/([^,]+)/$1/");
+ type_regex.push_back ("/([^,]+),([^,]+),([^,]+),([^,]+)/$1_$2_$3_$4/");
+ type_regex.push_back ("/([^,]+),([^,]+),([^,]+)/$1_$2_$3/");
+ type_regex.push_back ("/([^,]+),([^,]+)/$1_$2/");
+ type_regex.push_back ("/[^ ]* (.+)/$1/");
+ */
+ }
+ else
+ {
+ // Upper camel case or Java.
+ //
+ type_regex.push_back ("/(?:[^ ]* )?([^,]+),([^,]+),([^,]+),([^,]+)/\\u$1\\u$2\\u$3\\u$4/");
+ type_regex.push_back ("/(?:[^ ]* )?([^,]+),([^,]+),([^,]+)/\\u$1\\u$2\\u$3/");
+ type_regex.push_back ("/(?:[^ ]* )?([^,]+),([^,]+)/\\u$1\\u$2/");
+ type_regex.push_back ("/(?:[^ ]* )?([^,]+)/\\u$1/");
+
+ /*
+ type_regex.push_back ("/([^,]+)/\\u$1/");
+ type_regex.push_back ("/([^,]+),([^,]+),([^,]+),([^,]+)/\\u$1\\u$2\\u$3\\u$4/");
+ type_regex.push_back ("/([^,]+),([^,]+),([^,]+)/\\u$1\\u$2\\u$3/");
+ type_regex.push_back ("/([^,]+),([^,]+)/\\u$1\\u$2/");
+ type_regex.push_back ("/[^ ]* (.+)/\\u$1/");
+ */
+
+ }
+
+ compile_regex (options.value<CLI::type_regex> (),
+ type_regex,
+ "type");
+ }
+
+ // Accessor name regex.
+ //
+ {
+ // Predefined rules. The most frequently used come last: one
+ // component, three components (<name>,default,value) and two
+ // component (dom,document).
+ //
+ if (fn == "knr")
+ {
+ accessor_regex.push_back ("/([^,]+),([^,]+)/$1_$2/");
+ accessor_regex.push_back ("/([^,]+),([^,]+),([^,]+)/$1_$2_$3/");
+ accessor_regex.push_back ("/([^,]+)/$1/");
+ }
+ else if (fn == "lcc")
+ {
+ accessor_regex.push_back ("/([^,]+),([^,]+)/\\l$1\\u$2/");
+ accessor_regex.push_back ("/([^,]+),([^,]+),([^,]+)/\\l$1\\u$2\\u$3/");
+ accessor_regex.push_back ("/([^,]+)/\\l$1/");
+ }
+ else
+ {
+ // Java: add get.
+ //
+ accessor_regex.push_back ("/([^,]+),([^,]+)/get\\u$1\\u$2/");
+ accessor_regex.push_back ("/([^,]+),([^,]+),([^,]+)/get\\u$1\\u$2\\u$3/");
+ accessor_regex.push_back ("/([^,]+)/get\\u$1/");
+ }
+
+ compile_regex (options.value<CLI::accessor_regex> (),
+ accessor_regex,
+ "accessor");
+
+ compile_regex (options.value<CLI::one_accessor_regex> (),
+ one_accessor_regex,
+ "one accessor");
+
+ compile_regex (options.value<CLI::opt_accessor_regex> (),
+ opt_accessor_regex,
+ "optional accessor");
+
+ compile_regex (options.value<CLI::seq_accessor_regex> (),
+ seq_accessor_regex,
+ "sequence accessor");
+ }
+
+
+ // Modifier name regex.
+ //
+ {
+ if (fn == "knr")
+ {
+ // any,attribute
+ //
+ modifier_regex.push_back ("/([^,]+),([^,]+)/$1_$2/");
+ }
+ else if (fn == "lcc")
+ {
+ modifier_regex.push_back ("/([^,]+),([^,]+)/\\l$1\\u$2/");
+ modifier_regex.push_back ("/([^,]+)/\\l$1/");
+ }
+ else
+ {
+ // Java: add set.
+ //
+ modifier_regex.push_back ("/([^,]+),([^,]+)/set\\u$1\\u$2/");
+ modifier_regex.push_back ("/([^,]+)/set\\u$1/");
+ }
+
+ compile_regex (options.value<CLI::modifier_regex> (),
+ modifier_regex,
+ "modifier");
+
+ compile_regex (options.value<CLI::one_modifier_regex> (),
+ one_modifier_regex,
+ "one modifier");
+
+ compile_regex (options.value<CLI::opt_modifier_regex> (),
+ opt_modifier_regex,
+ "optional modifier");
+
+ compile_regex (options.value<CLI::seq_modifier_regex> (),
+ seq_modifier_regex,
+ "sequence modifier");
+ }
+
+
+ // Parser name regex.
+ //
+ {
+ if (fn == "lcc")
+ {
+ parser_regex.push_back ("/(.+)/\\l$1/");
+ }
+ else if (fn == "java")
+ {
+ // Java: add parse.
+ //
+ parser_regex.push_back ("/(.+)/parse\\u$1/");
+ }
+
+ compile_regex (options.value<CLI::parser_regex> (),
+ parser_regex,
+ "parser");
+ }
+
+ // Serializer name regex.
+ //
+ {
+ if (fn == "lcc")
+ {
+ serializer_regex.push_back ("/(.+)/\\l$1/");
+ }
+ else if (fn == "java")
+ {
+ // Java: add serialize.
+ //
+ serializer_regex.push_back ("/(.+)/serialize\\u$1/");
+ }
+
+ compile_regex (options.value<CLI::serializer_regex> (),
+ serializer_regex,
+ "serializer");
+ }
+
+ // Enumerator name regex.
+ //
+ {
+ compile_regex (options.value<CLI::enumerator_regex> (),
+ enumerator_regex,
+ "enumerator");
+ }
+
+ // Element type regex.
+ //
+ compile_regex (options.value<CLI::element_type_regex> (),
+ element_type_regex,
+ "element_type");
+ }
+
+ protected:
+ Context (Context& c)
+ : Tree::Context (c),
+ schema_path (c.schema_path),
+ global_type_names (c.global_type_names),
+ global_element_names (c.global_element_names),
+ type_regex (c.type_regex),
+ accessor_regex (c.accessor_regex),
+ one_accessor_regex (c.one_accessor_regex),
+ opt_accessor_regex (c.opt_accessor_regex),
+ seq_accessor_regex (c.seq_accessor_regex),
+ modifier_regex (c.modifier_regex),
+ one_modifier_regex (c.one_modifier_regex),
+ opt_modifier_regex (c.opt_modifier_regex),
+ seq_modifier_regex (c.seq_modifier_regex),
+ parser_regex (c.parser_regex),
+ serializer_regex (c.serializer_regex),
+ enumerator_regex (c.enumerator_regex),
+ element_type_regex (c.element_type_regex)
+ {
+ }
+
+ public:
+ typedef BackendElements::Regex::Expression<WideChar> Regex;
+ typedef BackendElements::Regex::Format<WideChar> RegexFormat;
+ typedef Cult::Containers::Vector<Regex> RegexVector;
+
+ String
+ process_regex (String const& name,
+ RegexVector const& rv,
+ String const& id)
+ {
+ Boolean trace (options.value<CLI::name_regex_trace> ());
+
+ if (trace)
+ os << id << " name: '" << name << "'" << endl;
+
+ for (RegexVector::ConstReverseIterator i (rv.rbegin ());
+ i != rv.rend (); ++i)
+ {
+ if (trace)
+ os << "try: '" << i->pattern () << "' : ";
+
+ if (i->match (name))
+ {
+ String r (i->merge (name));
+
+ if (trace)
+ os << "'" << r << "' : +" << endl;
+
+ return r;
+ }
+
+ if (trace)
+ os << '-' << endl;
+ }
+
+ return name;
+ }
+
+ String
+ process_regex (String const& name,
+ RegexVector const& primary,
+ RegexVector const& backup,
+ String const& id)
+ {
+ Boolean trace (options.value<CLI::name_regex_trace> ());
+
+ if (trace)
+ os << id << " name: '" << name << "'" << endl;
+
+ for (RegexVector::ConstReverseIterator i (primary.rbegin ());
+ i != primary.rend (); ++i)
+ {
+ if (trace)
+ os << "try: '" << i->pattern () << "' : ";
+
+ if (i->match (name))
+ {
+ String r (i->merge (name));
+
+ if (trace)
+ os << "'" << r << "' : +" << endl;
+
+ return r;
+ }
+
+ if (trace)
+ os << '-' << endl;
+ }
+
+ for (RegexVector::ConstReverseIterator i (backup.rbegin ());
+ i != backup.rend (); ++i)
+ {
+ if (trace)
+ os << "try: '" << i->pattern () << "' : ";
+
+ if (i->match (name))
+ {
+ String r (i->merge (name));
+
+ if (trace)
+ os << "'" << r << "' : +" << endl;
+
+ return r;
+ }
+
+ if (trace)
+ os << '-' << endl;
+ }
+
+ return name;
+ }
+
+ String
+ process_regex (String const& ns,
+ String const& name,
+ RegexVector const& rv,
+ String const& id)
+ {
+ String s (ns + L' ' + name);
+ Boolean trace (options.value<CLI::name_regex_trace> ());
+
+ if (trace)
+ os << id << " name: '" << s << "'" << endl;
+
+ for (RegexVector::ConstReverseIterator i (rv.rbegin ());
+ i != rv.rend (); ++i)
+ {
+ if (trace)
+ os << "try: '" << i->pattern () << "' : ";
+
+ if (i->match (s))
+ {
+ String r (i->merge (s));
+
+ if (trace)
+ os << "'" << r << "' : +" << endl;
+
+ return r;
+ }
+
+ if (trace)
+ os << '-' << endl;
+ }
+
+ return name;
+ }
+
+ String
+ process_regex (String const& ns,
+ String const& name,
+ RegexVector const& primary,
+ RegexVector const& backup,
+ String const& id)
+ {
+ String s (ns + L' ' + name);
+ Boolean trace (options.value<CLI::name_regex_trace> ());
+
+ if (trace)
+ os << id << " name: '" << s << "'" << endl;
+
+ for (RegexVector::ConstReverseIterator i (primary.rbegin ());
+ i != primary.rend (); ++i)
+ {
+ if (trace)
+ os << "try: '" << i->pattern () << "' : ";
+
+ if (i->match (s))
+ {
+ String r (i->merge (s));
+
+ if (trace)
+ os << "'" << r << "' : +" << endl;
+
+ return r;
+ }
+
+ if (trace)
+ os << '-' << endl;
+ }
+
+ for (RegexVector::ConstReverseIterator i (backup.rbegin ());
+ i != backup.rend (); ++i)
+ {
+ if (trace)
+ os << "try: '" << i->pattern () << "' : ";
+
+ if (i->match (s))
+ {
+ String r (i->merge (s));
+
+ if (trace)
+ os << "'" << r << "' : +" << endl;
+
+ return r;
+ }
+
+ if (trace)
+ os << '-' << endl;
+ }
+
+ return name;
+ }
+
+ public:
+ String
+ find_name (String const& base_name,
+ NameSet& set,
+ Boolean insert = true)
+ {
+ String name (base_name);
+
+ for (UnsignedLong i (1); set.find (name) != set.end (); ++i)
+ {
+ std::wostringstream os;
+ os << i;
+ name = base_name + os.str ();
+ }
+
+ if (insert)
+ set.insert (name);
+
+ return name;
+ }
+
+ private:
+ Void
+ compile_regex (Containers::Vector<NarrowString> const& sv,
+ RegexVector& rv,
+ String const& id)
+ {
+ typedef Containers::Vector<NarrowString> Vector;
+
+ for (Vector::ConstIterator i (sv.begin ()); i != sv.end (); ++i)
+ {
+ try
+ {
+ rv.push_back (Regex (*i));
+ }
+ catch (RegexFormat const& e)
+ {
+ os << "error: invalid " << id << " name regex: '" <<
+ e.expression () << "': " << e.description () << endl;
+
+ throw Failed ();
+ }
+ }
+ }
+
+ private:
+ SemanticGraph::Path const schema_path_;
+
+ Cult::Containers::Map<String, NameSet> global_type_names_;
+ Cult::Containers::Map<String, NameSet> global_element_names_;
+
+ RegexVector type_regex_;
+ RegexVector accessor_regex_;
+ RegexVector one_accessor_regex_;
+ RegexVector opt_accessor_regex_;
+ RegexVector seq_accessor_regex_;
+ RegexVector modifier_regex_;
+ RegexVector one_modifier_regex_;
+ RegexVector opt_modifier_regex_;
+ RegexVector seq_modifier_regex_;
+ RegexVector parser_regex_;
+ RegexVector serializer_regex_;
+ RegexVector enumerator_regex_;
+ RegexVector element_type_regex_;
+
+ public:
+ SemanticGraph::Path const& schema_path;
+
+ Cult::Containers::Map<String, NameSet>& global_type_names;
+ Cult::Containers::Map<String, NameSet>& global_element_names;
+
+ RegexVector& type_regex;
+ RegexVector& accessor_regex;
+ RegexVector& one_accessor_regex;
+ RegexVector& opt_accessor_regex;
+ RegexVector& seq_accessor_regex;
+ RegexVector& modifier_regex;
+ RegexVector& one_modifier_regex;
+ RegexVector& opt_modifier_regex;
+ RegexVector& seq_modifier_regex;
+ RegexVector& parser_regex;
+ RegexVector& serializer_regex;
+ RegexVector& enumerator_regex;
+ RegexVector& element_type_regex;
+ };
+
+ //
+ //
+ struct Enumerator: Traversal::Enumerator, Context
+ {
+ Enumerator (Context& c, NameSet& set)
+ : Context (c), set_ (set)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ // Process the name with enumerator name regex.
+ //
+ String name (
+ process_regex (e.name (), enumerator_regex, L"enumerator"));
+
+ // Escape and unclash.
+ //
+ name = find_name (escape (name), set_);
+ e.context ().set ("name", name);
+ }
+
+ private:
+ NameSet& set_;
+ };
+
+ //
+ //
+ struct Enumeration: Traversal::Enumeration, Context
+ {
+ Enumeration (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ // Use processed name.
+ //
+ String name (e.context ().get<String> ("name"));
+
+ // If renamed name is empty then we are not generating
+ // anything for this type and name processing is not
+ // required.
+ //
+ if (renamed_type (e, name) && !name)
+ return;
+
+ NameSet enum_set;
+ enum_set.insert (name);
+
+ Enumerator enumerator (*this, enum_set);
+ Traversal::Names names (enumerator);
+
+ Traversal::Enumeration::names (e, names);
+
+ // Assign name to the value type. First process the name
+ // with type name regex.
+ //
+ String value_name (
+ escape (process_regex ("value", type_regex, L"type")));
+ e.context ().set ("value", find_name (value_name, enum_set));
+ }
+ };
+
+ //
+ //
+ struct PrimaryMember: Traversal::Member, Context
+ {
+ PrimaryMember (Context& c, NameSet& name_set, NameSet& stem_set)
+ : Context (c), name_set_ (name_set), stem_set_ (stem_set)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (Tree::Context::skip (m))
+ return;
+
+ String stem (find_name (m.name (), stem_set_));
+
+ m.context ().set ("stem", stem);
+ m.context ().set ("name",
+ find_name (escape (stem), name_set_, false));
+ }
+
+ private:
+ NameSet& name_set_;
+ NameSet& stem_set_;
+ };
+
+ //
+ //
+ struct DerivedMember: Traversal::Member, Context
+ {
+ DerivedMember (Context& c, NameSet& name_set)
+ : Context (c), name_set_ (name_set)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (Tree::Context::skip (m))
+ return;
+
+ UnsignedLong max (Tree::Context::max (m));
+ UnsignedLong min (Tree::Context::min (m));
+
+ String const& s (m.context ().get<String> ("stem"));
+ String const& b (m.context ().get<String> ("name"));
+
+ Boolean def_attr (m.default_ () &&
+ m.is_a<SemanticGraph::Attribute> () &&
+ !Tree::Context::is_qname (m.type ()));
+
+ // Accessors/modifiers. Note that we postpone inserting the
+ // names into the name_set to avoid over-escaping.
+ //
+ String an, mn;
+
+ if (max != 1)
+ {
+ an = find_name (
+ escape (process_regex (s,
+ seq_accessor_regex,
+ accessor_regex,
+ L"sequence accessor")),
+ name_set_,
+ false);
+
+ mn = find_name (
+ escape (process_regex (s,
+ seq_modifier_regex,
+ modifier_regex,
+ L"sequence modifier")),
+ name_set_,
+ false);
+ }
+ else if (min == 0 && !def_attr)
+ {
+ an = find_name (
+ escape (process_regex (s,
+ opt_accessor_regex,
+ accessor_regex,
+ L"optional accessor")),
+ name_set_,
+ false);
+
+ mn = find_name (
+ escape (process_regex (s,
+ opt_modifier_regex,
+ modifier_regex,
+ L"optional modifier")),
+ name_set_,
+ false);
+ }
+ else
+ {
+ an = find_name (
+ escape (process_regex (s,
+ one_accessor_regex,
+ accessor_regex,
+ L"one accessor")),
+ name_set_,
+ false);
+
+ mn = find_name (
+ escape (process_regex (s,
+ one_modifier_regex,
+ modifier_regex,
+ L"one modifier")),
+ name_set_,
+ false);
+ }
+
+ m.context ().set ("aname", an);
+ m.context ().set ("mname", mn);
+
+ name_set_.insert (b);
+
+ if (an != b)
+ name_set_.insert (an);
+
+ if (mn != b && mn != an)
+ name_set_.insert (mn);
+
+
+ // Types.
+ //
+ m.context ().set (
+ "type",
+ find_name (
+ escape (process_regex (s + L",type", type_regex, L"type")),
+ name_set_));
+
+ m.context ().set (
+ "traits",
+ find_name (
+ escape (process_regex (s + L",traits", type_regex, L"type")),
+ name_set_));
+
+ if (max != 1)
+ {
+ m.context ().set (
+ "container",
+ find_name (
+ escape (process_regex (s + L",sequence", type_regex, L"type")),
+ name_set_));
+
+ m.context ().set (
+ "iterator",
+ find_name (
+ escape (process_regex (s + L",iterator", type_regex, L"type")),
+ name_set_));
+
+ m.context ().set (
+ "const-iterator",
+ find_name (
+ escape (
+ process_regex (s + L",const,iterator", type_regex, L"type")),
+ name_set_));
+ }
+ else if (min == 0 && !def_attr)
+ {
+ m.context ().set (
+ "container",
+ find_name (
+ escape (process_regex (s + L",optional", type_regex, L"type")),
+ name_set_));
+ }
+
+ // Data member.
+ //
+ m.context ().set ("member", find_name (b + L"_", name_set_));
+
+ // Default value.
+ //
+ if (m.default_ () && !Tree::Context::is_qname (m.type ()))
+ {
+ Boolean simple (true);
+
+ if (m.is_a<SemanticGraph::Element> ())
+ {
+ IsSimpleType test (simple);
+ test.dispatch (m.type ());
+ }
+
+ if (simple)
+ {
+ String an (
+ escape (
+ process_regex (
+ s + L",default,value", accessor_regex, L"accessor")));
+
+ m.context ().set ( "default-value", find_name (an, name_set_));
+
+ m.context ().set (
+ "default-value-member",
+ find_name (b + L"_default_value_", name_set_));
+ }
+ }
+ }
+
+ private:
+ NameSet& name_set_;
+ };
+
+
+ //
+ //
+ struct Any: Traversal::Any, Traversal::AnyAttribute, Context
+ {
+ Any (Context& c,
+ NameSet& name_set,
+ NameSet& stem_set,
+ Boolean& has_wildcard)
+ : Context (c),
+ name_set_ (name_set),
+ stem_set_ (stem_set),
+ has_wildcard_ (has_wildcard)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ UnsignedLong max (Tree::Context::max (a));
+ UnsignedLong min (Tree::Context::min (a));
+
+ String s (find_name (L"any", stem_set_));
+
+ String b (find_name (escape (s), name_set_, false));
+ a.context ().set ("name", b);
+
+ // Accessors/modifiers. Note that we postpone inserting the
+ // names into the name_set to avoid over-escaping.
+ //
+ String an, mn;
+
+ if (max != 1)
+ {
+ an = find_name (
+ escape (process_regex (s,
+ seq_accessor_regex,
+ accessor_regex,
+ L"sequence accessor")),
+ name_set_,
+ false);
+
+ mn = find_name (
+ escape (process_regex (s,
+ seq_modifier_regex,
+ modifier_regex,
+ L"sequence modifier")),
+ name_set_,
+ false);
+ }
+ else if (min == 0)
+ {
+ an = find_name (
+ escape (process_regex (s,
+ opt_accessor_regex,
+ accessor_regex,
+ L"optional accessor")),
+ name_set_,
+ false);
+
+ mn = find_name (
+ escape (process_regex (s,
+ opt_modifier_regex,
+ modifier_regex,
+ L"optional modifier")),
+ name_set_,
+ false);
+ }
+ else
+ {
+ an = find_name (
+ escape (process_regex (s,
+ one_accessor_regex,
+ accessor_regex,
+ L"one accessor")),
+ name_set_,
+ false);
+
+ mn = find_name (
+ escape (process_regex (s,
+ one_modifier_regex,
+ modifier_regex,
+ L"one modifier")),
+ name_set_,
+ false);
+ }
+
+ a.context ().set ("aname", an);
+ a.context ().set ("mname", mn);
+
+ name_set_.insert (b);
+
+ if (an != b)
+ name_set_.insert (an);
+
+ if (mn != b && mn != an)
+ name_set_.insert (mn);
+
+ // Types
+ //
+ if (max != 1)
+ {
+ a.context ().set (
+ "container",
+ find_name (
+ escape (process_regex (s + L",sequence", type_regex, L"type")),
+ name_set_));
+
+ a.context ().set (
+ "iterator",
+ find_name (
+ escape (process_regex (s + L",iterator", type_regex, L"type")),
+ name_set_));
+
+ a.context ().set (
+ "const-iterator",
+ find_name (
+ escape (
+ process_regex (s + L",const,iterator", type_regex, L"type")),
+ name_set_));
+ }
+ else if (min == 0)
+ {
+ a.context ().set (
+ "container",
+ find_name (
+ escape (process_regex (s + L",optional", type_regex, L"type")),
+ name_set_));
+ }
+
+ // Data member.
+ //
+ a.context ().set ("member", find_name (b + L"_", name_set_));
+
+ if (!has_wildcard_)
+ has_wildcard_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute& a)
+ {
+ String s (find_name (L"any,attribute", stem_set_));
+
+ String b (find_name (escape (s), name_set_, false));
+ a.context ().set ("name", b);
+
+ // Accessors/modifiers. Note that we postpone inserting the
+ // names into the name_set to avoid over-escaping.
+ //
+ String an (
+ find_name (
+ escape (process_regex (s, accessor_regex, L"accessor")),
+ name_set_,
+ false));
+
+ String mn (
+ find_name (
+ escape (process_regex (s, modifier_regex, L"modifier")),
+ name_set_,
+ false));
+
+ a.context ().set ("aname", an);
+ a.context ().set ("mname", mn);
+
+ name_set_.insert (b);
+
+ if (an != b)
+ name_set_.insert (an);
+
+ if (mn != b && mn != an)
+ name_set_.insert (mn);
+
+ // Types
+ //
+ a.context ().set (
+ "container",
+ find_name (
+ escape (process_regex (s + L",set", type_regex, L"type")),
+ name_set_));
+
+ a.context ().set (
+ "iterator",
+ find_name (
+ escape (process_regex (s + L",iterator", type_regex, L"type")),
+ name_set_));
+
+ a.context ().set (
+ "const-iterator",
+ find_name (
+ escape (
+ process_regex (s + L",const,iterator", type_regex, L"type")),
+ name_set_));
+
+ // Data member.
+ //
+ a.context ().set ("member", find_name (b + L"_", name_set_));
+
+ if (!has_wildcard_)
+ has_wildcard_ = true;
+ }
+
+ private:
+ NameSet& name_set_;
+ NameSet& stem_set_;
+ Boolean& has_wildcard_;
+ };
+
+ //
+ //
+ struct Complex: Traversal::Complex, Context
+ {
+ Complex (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ SemanticGraph::Context& cc (c.context ());
+
+ // Use processed name.
+ //
+ String name (cc.get<String> ("name"));
+
+ // If renamed name is empty then we are not generating
+ // anything for this type and name processing is not
+ // required.
+ //
+ if (renamed_type (c, name) && !name)
+ return;
+
+ // We leave this set around to allow other mappings to use
+ // this information.
+ //
+ cc.set ("cxx-tree-name-processor-stem-set", NameSet ());
+ cc.set ("cxx-tree-name-processor-member-set", NameSet ());
+
+ NameSet& stem_set (
+ cc.get<NameSet> ("cxx-tree-name-processor-stem-set"));
+
+ NameSet& member_set (
+ cc.get<NameSet> ("cxx-tree-name-processor-member-set"));
+
+ stem_set.insert (c.name ());
+ member_set.insert (name);
+
+ // Add our base's stems and members to the initial list.
+ //
+ if (c.inherits_p ())
+ {
+ // @@ What if this types name is the same as one of base's
+ // members?
+ //
+ SemanticGraph::Type& base (c.inherits ().base ());
+
+ if (base.is_a<SemanticGraph::Complex> ())
+ {
+ if (!base.context ().count (
+ "cxx-tree-name-processor-member-set"))
+ {
+ dispatch (base);
+ }
+
+ NameSet const& base_stem_set (
+ base.context ().get<NameSet> (
+ "cxx-tree-name-processor-stem-set"));
+
+ stem_set.insert (base_stem_set.begin (), base_stem_set.end ());
+
+ NameSet const& base_member_set (
+ base.context ().get<NameSet> (
+ "cxx-tree-name-processor-member-set"));
+
+ member_set.insert (base_member_set.begin (),
+ base_member_set.end ());
+ }
+ }
+
+ // First assign the "primary" names.
+ //
+ {
+ PrimaryMember member (*this, member_set, stem_set);
+ Traversal::Names names (member);
+
+ Complex::names (c, names);
+ }
+
+ // Derived names for members.
+ //
+ {
+ DerivedMember member (*this, member_set);
+ Traversal::Names names (member);
+
+ Complex::names (c, names);
+ }
+
+ // Names for wildcards.
+ //
+ if (options.value<CLI::generate_wildcard> ())
+ {
+ Boolean has_wildcard (false);
+ Any any (*this, member_set, stem_set, has_wildcard);
+ Traversal::Names names (any);
+ Complex::names (c, names);
+
+ // Assign names for dom_document.
+ //
+ if (has_wildcard)
+ {
+ // Check if we already have dom_document down inheritance
+ // hierarchy.
+ //
+ for (SemanticGraph::Complex* p (&c); p->inherits_p ();)
+ {
+ if (SemanticGraph::Complex* base =
+ dynamic_cast<SemanticGraph::Complex*> (
+ &p->inherits ().base ()))
+ {
+ if (base->context ().count ("dom-document"))
+ {
+ c.context ().set (
+ "dom-document",
+ base->context ().get<String> ("dom-document"));
+ break;
+ }
+
+ p = base;
+ }
+ else
+ break;
+ }
+
+ // If not, set up the names.
+ //
+ if (!c.context ().count ("dom-document"))
+ {
+ String stem (find_name (L"dom,document", stem_set));
+
+ String an (
+ escape (
+ process_regex (stem, accessor_regex, L"accessor")));
+
+ c.context ().set ("dom-document", find_name (an, member_set));
+
+ c.context ().set (
+ "dom-document-member",
+ find_name (escape (stem + L"_"), member_set));
+ }
+ }
+ }
+ }
+ };
+
+
+ //
+ //
+ struct GlobalType: Traversal::Type, Context
+ {
+ GlobalType (Context& c, NameSet& set)
+ : Context (c), set_ (set)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type& t)
+ {
+ // Process the name with type name regex.
+ //
+ String name (process_regex (
+ namespace_ (t).name (),
+ t.name (),
+ type_regex,
+ L"type"));
+
+ // Escape and unclash.
+ //
+ name = find_name (escape (name), set_);
+ t.context ().set ("name", name);
+
+ // Also add renamed name if any.
+ //
+ if (renamed_type (t, name) && name)
+ set_.insert (name);
+ }
+
+ private:
+ NameSet& set_;
+ };
+
+
+ //
+ //
+ struct GlobalElement: Traversal::Element,
+ GlobalElementBase,
+ Context
+ {
+ GlobalElement (Context& c,
+ NameSet const& type_set,
+ NameSet& element_set)
+ : GlobalElementBase (c),
+ Context (c),
+ type_set_ (type_set),
+ element_set_ (element_set)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ // First we need to figure out if we need to process this
+ // global element.
+ //
+ if (!generate_p (e))
+ return;
+
+ if (options.value<CLI::generate_element_type> ())
+ {
+ SemanticGraph::Context& ec (e.context ());
+
+ String name;
+
+ if (doc_root_p (e))
+ {
+ name = find_name (
+ escape (
+ process_regex (
+ namespace_ (e).name (),
+ e.name (),
+ element_type_regex,
+ type_regex,
+ L"element type")));
+
+ // Assign inner names.
+ //
+ NameSet set;
+ set.insert (name);
+
+ ec.set (
+ "type",
+ Context::find_name (
+ escape (process_regex (L"value,type", type_regex, L"type")),
+ set));
+
+ ec.set (
+ "traits",
+ Context::find_name (
+ escape (process_regex (L"value,traits", type_regex, L"type")),
+ set));
+
+ String an = Context::find_name (
+ escape (process_regex ("value",
+ one_accessor_regex,
+ accessor_regex,
+ L"one accessor")),
+ set,
+ false);
+
+ String mn = Context::find_name (
+ escape (process_regex ("value",
+ one_modifier_regex,
+ modifier_regex,
+ L"one modifier")),
+ set,
+ false);
+
+ ec.set ("aname", an);
+ ec.set ("mname", mn);
+
+ set.insert (an);
+
+ if (an != mn)
+ set.insert (mn);
+
+ // Assign name() and namespace_() names.
+ //
+ ec.set (
+ "element-name",
+ Context::find_name (
+ escape (
+ process_regex ("name", accessor_regex, L"modifier")),
+ set));
+
+ ec.set (
+ "element-ns",
+ Context::find_name (
+ escape (
+ process_regex ("namespace", accessor_regex, L"modifier")),
+ set));
+
+ // Data members.
+ //
+ ec.set ("member", Context::find_name ("value_", set));
+ ec.set ("element-name-member",
+ Context::find_name ("name_", set));
+ ec.set ("element-ns-member",
+ Context::find_name ("namespace__", set));
+ }
+ else
+ name = find_name (escape (e.name ()));
+
+ ec.set ("name", name);
+ element_set_.insert (name);
+ }
+ else
+ {
+ // Make sure the name is unique among global elements and
+ // does not collide with a global type name.
+ //
+ String base (find_name (escape (e.name ())));
+ e.context ().set ("name", base);
+
+ String n (e.name ());
+
+ // Assign the parsing function name.
+ //
+ String p;
+
+ if (!options.value<CLI::suppress_parsing> () && doc_root_p (e))
+ {
+ p = find_name (
+ escape (
+ process_regex (n, parser_regex, L"parsing function")));
+
+ e.context ().set ("parser", p);
+ }
+
+ // Assign the serialization function name.
+ //
+ String s;
+
+ if (options.value<CLI::generate_serialization> () &&
+ doc_root_p (e))
+ {
+ s = find_name (
+ escape (
+ process_regex (
+ n, serializer_regex, L"serialization function")));
+
+ e.context ().set ("serializer", s);
+ }
+
+ // Add the names to the set only after processing parsing and
+ // serialization function names so that we do not over-escape
+ // them.
+ //
+ element_set_.insert (base);
+
+ if (p && p != base)
+ element_set_.insert (p);
+
+ if (s && s != base && s != p)
+ element_set_.insert (s);
+ }
+ }
+
+ private:
+ String
+ find_name (String const& name)
+ {
+ String r (name);
+
+ // If we are conflicting with a type name let's first try to
+ // simply append an underscore and only resort to ugly names
+ // like name1, etc., if this fails.
+ //
+ if (type_set_.find (r) != type_set_.end ())
+ r += L"_";
+
+ for (UnsignedLong i (1);
+ element_set_.find (r) != element_set_.end () ||
+ type_set_.find (r) != type_set_.end (); ++i)
+ {
+ std::wostringstream os;
+ os << i;
+ r = name + os.str ();
+ }
+
+ return r;
+ }
+
+ private:
+ NameSet const& type_set_;
+ NameSet& element_set_;
+ };
+
+ struct NamespacePassOne: Traversal::Namespace, Context
+ {
+ NamespacePassOne (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& ns)
+ {
+ NameSet& type_set (global_type_names[ns.name ()]);
+
+ GlobalType type (*this, type_set);
+ Traversal::Names names (type);
+
+ Traversal::Namespace::names (ns, names);
+ Traversal::Namespace::names (ns);
+ }
+ };
+
+
+ struct NamespacePassThree: Traversal::Namespace, Context
+ {
+ NamespacePassThree (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& ns)
+ {
+ String const& name (ns.name ());
+
+ NameSet const& type_set (global_type_names[name]);
+ NameSet& element_set (global_element_names[name]);
+
+ GlobalElement element (*this, type_set, element_set);
+ Traversal::Names names (element);
+
+ Traversal::Namespace::names (ns, names);
+ }
+ };
+
+
+ struct FundamentalNamespace : Traversal::Namespace,
+
+ Traversal::AnyType,
+ Traversal::AnySimpleType,
+
+ Traversal::Fundamental::Byte,
+ Traversal::Fundamental::UnsignedByte,
+ Traversal::Fundamental::Short,
+ Traversal::Fundamental::UnsignedShort,
+ Traversal::Fundamental::Int,
+ Traversal::Fundamental::UnsignedInt,
+ Traversal::Fundamental::Long,
+ Traversal::Fundamental::UnsignedLong,
+ Traversal::Fundamental::Integer,
+ Traversal::Fundamental::NonPositiveInteger,
+ Traversal::Fundamental::NonNegativeInteger,
+ Traversal::Fundamental::PositiveInteger,
+ Traversal::Fundamental::NegativeInteger,
+
+ Traversal::Fundamental::Boolean,
+
+ Traversal::Fundamental::Float,
+ Traversal::Fundamental::Double,
+ Traversal::Fundamental::Decimal,
+
+ Traversal::Fundamental::String,
+ Traversal::Fundamental::NormalizedString,
+ Traversal::Fundamental::Token,
+ Traversal::Fundamental::Name,
+ Traversal::Fundamental::NameToken,
+ Traversal::Fundamental::NameTokens,
+ Traversal::Fundamental::NCName,
+ Traversal::Fundamental::Language,
+
+ Traversal::Fundamental::Id,
+ Traversal::Fundamental::IdRef,
+ Traversal::Fundamental::IdRefs,
+
+ Traversal::Fundamental::AnyURI,
+
+ Traversal::Fundamental::QName,
+
+ Traversal::Fundamental::Base64Binary,
+ Traversal::Fundamental::HexBinary,
+
+ Traversal::Fundamental::Date,
+ Traversal::Fundamental::DateTime,
+ Traversal::Fundamental::Duration,
+ Traversal::Fundamental::Day,
+ Traversal::Fundamental::Month,
+ Traversal::Fundamental::MonthDay,
+ Traversal::Fundamental::Year,
+ Traversal::Fundamental::YearMonth,
+ Traversal::Fundamental::Time,
+
+ Traversal::Fundamental::Entity,
+ Traversal::Fundamental::Entities,
+
+ Context
+ {
+ FundamentalNamespace (Context& c)
+ : Context (c)
+ {
+ *this >> names_ >> *this;
+ }
+
+ Void
+ process_name (SemanticGraph::Type& t, String const& name)
+ {
+ String r (
+ process_regex (
+ namespace_ (t).name (), name, type_regex, L"type"));
+
+ t.context ().set ("name", escape (r));
+ }
+
+ Void
+ process_name (SemanticGraph::Namespace& n,
+ String const& name,
+ Char const* key)
+ {
+ String r (process_regex (name, type_regex, L"type"));
+ n.context ().set (key, escape (r));
+ }
+
+ // anyType and anySimpleType
+ //
+ virtual Void
+ traverse (SemanticGraph::AnyType& t)
+ {
+ process_name (t, "type");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnySimpleType& t)
+ {
+ process_name (t, "simple,type");
+ }
+
+ // Integrals.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Byte& t)
+ {
+ process_name (t, "byte");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedByte& t)
+ {
+ process_name (t, "unsigned,byte");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Short& t)
+ {
+ process_name (t, "short");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedShort& t)
+ {
+ process_name (t, "unsigned,short");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Int& t)
+ {
+ process_name (t, "int");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedInt& t)
+ {
+ process_name (t, "unsigned,int");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Long& t)
+ {
+ process_name (t, "long");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::UnsignedLong& t)
+ {
+ process_name (t, "unsigned,long");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Integer& t)
+ {
+ process_name (t, "integer");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonPositiveInteger& t)
+ {
+ process_name (t, "non,positive,integer");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NonNegativeInteger& t)
+ {
+ process_name (t, "non,negative,integer");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::PositiveInteger& t)
+ {
+ process_name (t, "positive,integer");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NegativeInteger& t)
+ {
+ process_name (t, "negative,integer");
+ }
+
+ // Boolean.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Boolean& t)
+ {
+ process_name (t, "boolean");
+ }
+
+ // Floats.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Float& t)
+ {
+ process_name (t, "float");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Double& t)
+ {
+ process_name (t, "double");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Decimal& t)
+ {
+ process_name (t, "decimal");
+ }
+
+ // Strings.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::String& t)
+ {
+ process_name (t, "string");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NormalizedString& t)
+ {
+ process_name (t, "normalized,string");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Token& t)
+ {
+ process_name (t, "token");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameToken& t)
+ {
+ process_name (t, "nmtoken");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NameTokens& t)
+ {
+ process_name (t, "nmtokens");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Name& t)
+ {
+ process_name (t, "name");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::NCName& t)
+ {
+ process_name (t, "ncname");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Language& t)
+ {
+ process_name (t, "language");
+ }
+
+ // ID/IDREF.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Id& t)
+ {
+ process_name (t, "id");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRef& t)
+ {
+ process_name (t, "idref");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::IdRefs& t)
+ {
+ process_name (t, "idrefs");
+ }
+
+
+ // URI.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::AnyURI& t)
+ {
+ process_name (t, "uri");
+ }
+
+ // Qualified name.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::QName& t)
+ {
+ process_name (t, "qname");
+ }
+
+ // Binary.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Base64Binary& t)
+ {
+ process_name (t, "base64,binary");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::HexBinary& t)
+ {
+ process_name (t, "hex,binary");
+ }
+
+
+ // Date/time.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Date& t)
+ {
+ process_name (t, "date");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::DateTime& t)
+ {
+ process_name (t, "date,time");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Duration& t)
+ {
+ process_name (t, "duration");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Day& t)
+ {
+ process_name (t, "gday");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Month& t)
+ {
+ process_name (t, "gmonth");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::MonthDay& t)
+ {
+ process_name (t, "gmonth,day");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Year& t)
+ {
+ process_name (t, "gyear");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::YearMonth& t)
+ {
+ process_name (t, "gyear,month");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Time& t)
+ {
+ process_name (t, "time");
+ }
+
+ // Entity.
+ //
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entity& t)
+ {
+ process_name (t, "entity");
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Entities& t)
+ {
+ process_name (t, "entities");
+ }
+
+ virtual Void
+ post (SemanticGraph::Namespace& n)
+ {
+ // Assign names to extra stuff in the XML Schema namespace.
+ //
+ process_name (n, "container", "container");
+ process_name (n, "buffer", "buffer");
+ process_name (n, "time,zone", "time-zone");
+
+ if (options.value<CLI::generate_element_type> ())
+ process_name (n, "element,type", "element-type");
+
+ if (options.value<CLI::generate_element_map> ())
+ process_name (n, "element,map", "element-map");
+
+ if (options.value<CLI::generate_serialization> ())
+ {
+ process_name (n, "namespace,info", "namespace-info");
+ process_name (n, "namespace,infomap", "namespace-infomap");
+ process_name (n, "list,stream", "list-stream");
+ process_name (n, "as,double", "as-double");
+ process_name (n, "as,decimal", "as-decimal");
+ process_name (n, "facet", "facet");
+ }
+
+ if (!options.value<CLI::generate_insertion> ().empty ())
+ {
+ process_name (n, "ostream", "ostream");
+ }
+
+ if (!options.value<CLI::generate_extraction> ().empty ())
+ {
+ process_name (n, "istream", "istream");
+ }
+
+ process_name (n, "flags", "flags");
+ process_name (n, "properties", "properties");
+
+ NarrowString fn (options.value<CLI::function_naming> ());
+
+ if (fn == "knr")
+ n.context ().set ("tree-node-key", String ("tree_node_key"));
+ else
+ n.context ().set ("tree-node-key", String ("treeNodeKey"));
+
+ process_name (n, "exception", "exception");
+ process_name (n, "parsing", "parsing");
+ process_name (n, "expected,element", "expected-element");
+ process_name (n, "unexpected,element", "unexpected-element");
+ process_name (n, "expected,attribute", "expected-attribute");
+ process_name (n, "unexpected,enumerator", "unexpected-enumerator");
+ process_name (n, "expected,text,content", "expected-text-content");
+ process_name (n, "no,type,info", "no-type-info");
+ process_name (n, "no,element,info", "no-element-info");
+ process_name (n, "not,derived", "not-derived");
+ process_name (n, "duplicate,id", "duplicate-id");
+ process_name (n, "serialization", "serialization");
+ process_name (n, "no,namespace,mapping", "no-namespace-mapping");
+ process_name (n, "no,prefix,mapping", "no-prefix-mapping");
+ process_name (n, "xsi,already,in,use", "xsi-already-in-use");
+ process_name (n, "bounds", "bounds");
+
+ process_name (n, "severity", "severity");
+ process_name (n, "error", "error");
+ process_name (n, "diagnostics", "diagnostics");
+
+ if (!options.value<CLI::suppress_parsing> () ||
+ options.value<CLI::generate_serialization> ())
+ {
+ process_name (n, "error,handler", "error-handler");
+ }
+
+ Namespace::post (n);
+ }
+
+ private:
+ Traversal::Names names_;
+ };
+
+
+ // Go into sourced/included/imported schemas while making sure
+ // we don't process the same stuff more than once.
+ //
+ struct UsesPassOne: Traversal::Uses
+ {
+ virtual Void
+ traverse (Type& u)
+ {
+ SemanticGraph::Schema& s (u.schema ());
+
+ if (!s.context ().count ("cxx-tree-name-processor-pass-1"))
+ {
+ s.context ().set ("cxx-tree-name-processor-pass-1", true);
+ Traversal::Uses::traverse (u);
+ }
+ }
+ };
+
+ struct UsesPassThree: Traversal::Uses
+ {
+ virtual Void
+ traverse (Type& u)
+ {
+ SemanticGraph::Schema& s (u.schema ());
+
+ if (!s.context ().count ("cxx-tree-name-processor-pass-3"))
+ {
+ s.context ().set ("cxx-tree-name-processor-pass-3", true);
+ Traversal::Uses::traverse (u);
+ }
+ }
+ };
+
+ // Go into implied schemas while making sure we don't process
+ // the same stuff more than once.
+ //
+ struct Implies: Traversal::Implies
+ {
+ virtual Void
+ traverse (SemanticGraph::Implies& i)
+ {
+ SemanticGraph::Schema& s (i.schema ());
+
+ if (!s.context ().count ("cxx-tree-name-processor-seen"))
+ {
+ s.context ().set ("cxx-tree-name-processor-seen", true);
+ Traversal::Implies::traverse (i);
+ }
+ }
+ };
+
+ Boolean
+ process_impl (CLI::Options const& ops,
+ SemanticGraph::Schema& tu,
+ SemanticGraph::Path const& file)
+ {
+ try
+ {
+ Counts counts;
+ Context ctx (ops, counts, false, tu, file);
+
+ if (tu.names_begin ()->named ().name () ==
+ L"http://www.w3.org/2001/XMLSchema")
+ {
+ // XML Schema namespace.
+ //
+ Traversal::Schema xs_schema;
+ Traversal::Names xs_schema_names;
+ FundamentalNamespace xs_ns (ctx);
+
+ xs_schema >> xs_schema_names >> xs_ns;
+
+ xs_schema.dispatch (tu);
+ }
+ else
+ {
+
+ // Pass one - assign names to global types. This pass cannot
+ // be combined with pass two because of possible recursive
+ // schema inclusions. Also note that we check first if this
+ // schema has already been processed which may happen in the
+ // file-per-type compilation mode.
+ //
+ if (!tu.context ().count ("cxx-tree-name-processor-pass-1"))
+ {
+ Traversal::Schema schema;
+ Traversal::Schema xs_schema;
+ UsesPassOne uses;
+ Implies implies;
+
+ schema >> uses >> schema;
+ schema >> implies >> xs_schema;
+
+ Traversal::Names schema_names;
+ Traversal::Names xs_schema_names;
+ NamespacePassOne ns (ctx);
+ FundamentalNamespace xs_ns (ctx);
+
+ schema >> schema_names >> ns;
+ xs_schema >> xs_schema_names >> xs_ns;
+
+ // Some twisted schemas do recusive self-inclusion.
+ //
+ tu.context ().set ("cxx-tree-name-processor-pass-1", true);
+
+ schema.dispatch (tu);
+ }
+
+ // Pass two - assign names inside complex types. Here
+ // we don't need to go into included/imported schemas.
+ //
+ {
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+
+ schema >> sources >> schema;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+
+ schema >> schema_names >> ns >> ns_names;
+
+ Complex complex (ctx);
+ Traversal::Enumeration enumeration; // Avoid fallback on complex.
+
+ ns_names >> complex;
+ ns_names >> enumeration;
+
+ schema.dispatch (tu);
+ }
+
+ // Pass three - assign names to global elements as well as
+ // inside enums. Also note that we check first if this schema
+ // has already been processed which may happen in the file-per-
+ // type compilation mode.
+ //
+ if (!tu.context ().count ("cxx-tree-name-processor-pass-3"))
+ {
+ Traversal::Schema schema;
+ UsesPassThree uses;
+
+ schema >> uses >> schema;
+
+ Traversal::Names schema_names;
+ NamespacePassThree ns (ctx);
+ Traversal::Namespace ns_enum;
+
+ schema >> schema_names;
+
+ schema_names >> ns;
+ schema_names >> ns_enum;
+
+ Traversal::Names ns_names;
+ Enumeration enumeration (ctx);
+
+ ns_enum >> ns_names >> enumeration;
+
+ // Some twisted schemas do recusive self-inclusion.
+ //
+ tu.context ().set ("cxx-tree-name-processor-pass-3", true);
+
+ schema.dispatch (tu);
+ }
+ }
+ }
+ catch (Context::Failed const&)
+ {
+ // Diagnostics has already been issued.
+ //
+ return false;
+ }
+
+ return true;
+ }
+ }
+
+ Boolean NameProcessor::
+ process (CLI::Options const& ops,
+ SemanticGraph::Schema& tu,
+ SemanticGraph::Path const& file)
+ {
+ return process_impl (ops, tu, file);
+ }
+ }
+}
diff --git a/xsd/cxx/tree/name-processor.hxx b/xsd/cxx/tree/name-processor.hxx
new file mode 100644
index 0000000..9b8eac9
--- /dev/null
+++ b/xsd/cxx/tree/name-processor.hxx
@@ -0,0 +1,34 @@
+// file : xsd/cxx/tree/name-processor.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_NAME_PROCESSOR_HXX
+#define CXX_TREE_NAME_PROCESSOR_HXX
+
+#include <cult/types.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+
+#include <cxx/tree/cli.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ using namespace Cult::Types;
+
+ class NameProcessor
+ {
+ public:
+ NameProcessor (); // Dummy ctor, helps with long symbols on HP-UX.
+
+ Boolean
+ process (CLI::Options const&,
+ XSDFrontend::SemanticGraph::Schema&,
+ XSDFrontend::SemanticGraph::Path const& file);
+ };
+ }
+}
+
+#endif // CXX_TREE_NAME_PROCESSOR_HXX
diff --git a/xsd/cxx/tree/parser-header.cxx b/xsd/cxx/tree/parser-header.cxx
new file mode 100644
index 0000000..bf49821
--- /dev/null
+++ b/xsd/cxx/tree/parser-header.cxx
@@ -0,0 +1,474 @@
+// file : xsd/cxx/tree/parser-header.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/parser-header.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ struct ElementFunction : Traversal::Element,
+ GlobalElementBase,
+ protected virtual Context
+ {
+ ElementFunction (Context& c)
+ : Context (c), GlobalElementBase (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (!doc_root_p (e))
+ return;
+
+ String const& name (eparser (e));
+ String const& error_handler (error_handler_type);
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @name Parsing functions for the %" <<
+ comment (e.name ()) << " document root." << endl;
+
+ if (e.annotated ())
+ {
+ os << " *" << endl;
+ write_annotation (e.annotation ());
+ }
+
+ os << " */" << endl
+ << "//@{" << endl
+ << endl;
+ }
+
+ if (!doxygen)
+ {
+ os << "// Parse a URI or a local file." << endl
+ << "//" << endl
+ << endl;
+ }
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a URI or a local file." << endl
+ << " *" << endl
+ << " * @param uri A URI or a local file name." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " *" << endl
+ << " * This function uses exceptions to report parsing errors." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (const " << string_type << "& uri," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a URI or a local file with an error handler." << endl
+ << " *" << endl
+ << " * @param uri A URI or a local file name." << endl
+ << " * @param eh An error handler." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " *" << endl
+ << " * This function reports parsing errors by calling the " <<
+ "error handler." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (const " << string_type << "& uri," << endl
+ << error_handler << "& eh," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a URI or a local file with a Xerces-C++ " <<
+ "DOM error" << endl
+ << " * handler." << endl
+ << " *" << endl
+ << " * @param uri A URI or a local file name." << endl
+ << " * @param eh A Xerces-C++ DOM error handler." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " *" << endl
+ << " * This function reports parsing errors by calling the " <<
+ "error handler." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (const " << string_type << "& uri," << endl
+ << xerces_ns << "::DOMErrorHandler& eh," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (!doxygen)
+ {
+ os << "// Parse std::istream." << endl
+ << "//" << endl
+ << endl;
+ }
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a standard input stream." << endl
+ << " *" << endl
+ << " * @param is A standrad input stream." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " *" << endl
+ << " * This function uses exceptions to report parsing errors." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (::std::istream& is," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a standard input stream with an error handler." << endl
+ << " *" << endl
+ << " * @param is A standrad input stream." << endl
+ << " * @param eh An error handler." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " *" << endl
+ << " * This function reports parsing errors by calling the " <<
+ "error handler." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (::std::istream& is," << endl
+ << error_handler << "& eh," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a standard input stream with a " <<
+ "Xerces-C++ DOM error" << endl
+ << " * handler." << endl
+ << " *" << endl
+ << " * @param is A standrad input stream." << endl
+ << " * @param eh A Xerces-C++ DOM error handler." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " *" << endl
+ << " * This function reports parsing errors by calling the " <<
+ "error handler." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (::std::istream& is," << endl
+ << xerces_ns << "::DOMErrorHandler& eh," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a standard input stream with a resource id." << endl
+ << " *" << endl
+ << " * @param is A standrad input stream." << endl
+ << " * @param id A resource id." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " *" << endl
+ << " * The resource id is used to identify the document " <<
+ "being parsed in" << endl
+ << " * diagnostics as well as to resolve relative paths." << endl
+ << " *" << endl
+ << " * This function uses exceptions to report parsing errors." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (::std::istream& is," << endl
+ << "const " << string_type << "& id," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a standard input stream with a resource " <<
+ "id and an" << endl
+ << " * error handler." << endl
+ << " *" << endl
+ << " * @param is A standrad input stream." << endl
+ << " * @param id A resource id." << endl
+ << " * @param eh An error handler." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " *" << endl
+ << " * The resource id is used to identify the document " <<
+ "being parsed in" << endl
+ << " * diagnostics as well as to resolve relative paths." << endl
+ << " *" << endl
+ << " * This function reports parsing errors by calling the " <<
+ "error handler." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (::std::istream& is," << endl
+ << "const " << string_type << "& id," << endl
+ << error_handler << "& eh," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a standard input stream with a resource " <<
+ "id and a" << endl
+ << " * Xerces-C++ DOM error handler." << endl
+ << " *" << endl
+ << " * @param is A standrad input stream." << endl
+ << " * @param id A resource id." << endl
+ << " * @param eh A Xerces-C++ DOM error handler." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " *" << endl
+ << " * The resource id is used to identify the document " <<
+ "being parsed in" << endl
+ << " * diagnostics as well as to resolve relative paths." << endl
+ << " *" << endl
+ << " * This function reports parsing errors by calling the " <<
+ "error handler." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (::std::istream& is," << endl
+ << "const " << string_type << "& id," << endl
+ << xerces_ns << "::DOMErrorHandler& eh," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (!doxygen)
+ {
+ os << "// Parse xercesc::InputSource." << endl
+ << "//" << endl
+ << endl;
+ }
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a Xerces-C++ input source." << endl
+ << " *" << endl
+ << " * @param is A Xerces-C++ input source." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " *" << endl
+ << " * This function uses exceptions to report parsing errors." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (" << xerces_ns << "::InputSource& is," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a Xerces-C++ input source with an " <<
+ "error handler." << endl
+ << " *" << endl
+ << " * @param is A Xerces-C++ input source." << endl
+ << " * @param eh An error handler." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " *" << endl
+ << " * This function reports parsing errors by calling the " <<
+ "error handler." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (" << xerces_ns << "::InputSource& is," << endl
+ << error_handler << "& eh," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a Xerces-C++ input source with a " <<
+ "Xerces-C++ DOM" << endl
+ << " * error handler." << endl
+ << " *" << endl
+ << " * @param is A Xerces-C++ input source." << endl
+ << " * @param eh A Xerces-C++ DOM error handler." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " *" << endl
+ << " * This function reports parsing errors by calling the " <<
+ "error handler." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (" << xerces_ns << "::InputSource& is," << endl
+ << xerces_ns << "::DOMErrorHandler& eh," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (!doxygen)
+ {
+ os << "// Parse xercesc::DOMDocument." << endl
+ << "//" << endl
+ << endl;
+ }
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a Xerces-C++ DOM document." << endl
+ << " *" << endl
+ << " * @param d A Xerces-C++ DOM document." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (const " << xerces_ns << "::DOMDocument& d," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Parse a Xerces-C++ DOM document." << endl
+ << " *" << endl
+ << " * @param d A pointer to the Xerces-C++ DOM document." << endl
+ << " * @param f Parsing flags." << endl
+ << " * @param p Parsing properties. " << endl
+ << " * @return A pointer to the root of the object model." << endl
+ << " *" << endl
+ << " * This function is normally used together with the " <<
+ "keep_dom and" << endl
+ << " * own_dom parsing flags to assign ownership of the DOM " <<
+ "document" << endl
+ << " * to the object model." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "::std::auto_ptr< " << type_name (e) << " >" << endl
+ << name << " (" << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument >& d," << endl
+ << flags_type << " f = 0," << endl
+ << "const " << properties_type << "& p = " << properties_type << " ());"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "//@}" << endl
+ << endl;
+ }
+ }
+
+ private:
+ String
+ type_name (Type& e)
+ {
+ std::wostringstream o;
+
+ MemberTypeName type (*this, o);
+ type.dispatch (e.type ());
+
+ return o.str ();
+ }
+ };
+ }
+
+
+ Void
+ generate_parser_header (Context& ctx)
+ {
+ ctx.os << "#include <iosfwd>" << endl
+ << endl
+ << "#include <xercesc/sax/InputSource.hpp>" << endl
+ << "#include <xercesc/dom/DOMDocument.hpp>" << endl
+ << "#include <xercesc/dom/DOMErrorHandler.hpp>" << endl
+ << endl;
+
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+ Traversal::Names names_ns, names;
+ Namespace ns (ctx);
+ ElementFunction element (ctx);
+
+ schema >> sources >> schema;
+ schema >> names_ns >> ns >> names >> element;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/tree/parser-header.hxx b/xsd/cxx/tree/parser-header.hxx
new file mode 100644
index 0000000..ff43926
--- /dev/null
+++ b/xsd/cxx/tree/parser-header.hxx
@@ -0,0 +1,23 @@
+// file : xsd/cxx/tree/parser-header.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_PARSER_HEADER_HXX
+#define CXX_TREE_PARSER_HEADER_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+
+namespace CXX
+{
+ namespace Tree
+ {
+ Void
+ generate_parser_header (Context&);
+ }
+}
+
+#endif // CXX_TREE_PARSER_HEADER_HXX
diff --git a/xsd/cxx/tree/parser-source.cxx b/xsd/cxx/tree/parser-source.cxx
new file mode 100644
index 0000000..5c121f2
--- /dev/null
+++ b/xsd/cxx/tree/parser-source.cxx
@@ -0,0 +1,544 @@
+// file : xsd/cxx/tree/parser-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/parser-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ struct ElementFunction: Traversal::Element,
+ GlobalElementBase,
+ protected virtual Context
+ {
+ ElementFunction (Context& c)
+ : Context (c), GlobalElementBase (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (!doc_root_p (e))
+ return;
+
+ String const& name (eparser (e));
+ SemanticGraph::Type& t (e.type ());
+ String type (type_name (e));
+ String const& error_handler (error_handler_type);
+
+ // Note that I am using fq-name in function calls because g++ gets
+ // confused if the name is 'type'. (see tests/schema/anonymous)
+ //
+
+ // URI.
+ //
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (const " << string_type << "& u," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "& p)"
+ << "{"
+ << "::xsd::cxx::xml::auto_initializer i (" << endl
+ << "(f & " << flags_type << "::dont_initialize) == 0," << endl
+ << "(f & " << flags_type << "::keep_dom) == 0);"
+ << endl
+ << "::xsd::cxx::tree::error_handler< " << char_type << " > h;"
+ << endl
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > d (" << endl
+ << "::xsd::cxx::xml::dom::parse< " << char_type << " > (" << endl
+ << "u, h, p, f";
+
+ if (options.value<CLI::disable_multi_import> ())
+ os << " | ::xsd::cxx::xml::dom::no_muliple_imports";
+
+ os << "));"
+ << endl
+ << "h.throw_if_failed< ::xsd::cxx::tree::parsing< " <<
+ char_type << " > > ();"
+ << endl
+ << "::std::auto_ptr< " << type << " > r (" << endl
+ << fq_name (e, "parser") << " (" << endl
+ << "d, f | " << flags_type << "::own_dom, p));"
+ << endl
+ << "return r;"
+ << "}";
+
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (const " << string_type << "& u," << endl
+ << error_handler << "& h," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "& p)"
+ << "{"
+ << "::xsd::cxx::xml::auto_initializer i (" << endl
+ << "(f & " << flags_type << "::dont_initialize) == 0," << endl
+ << "(f & " << flags_type << "::keep_dom) == 0);"
+ << endl
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > d (" << endl
+ << "::xsd::cxx::xml::dom::parse< " << char_type << " > (" << endl
+ << "u, h, p, f";
+
+ if (options.value<CLI::disable_multi_import> ())
+ os << " | ::xsd::cxx::xml::dom::no_muliple_imports";
+
+ os << "));"
+ << endl
+ << "if (!d.get ())" << endl
+ << "throw ::xsd::cxx::tree::parsing< " << char_type << " > ();"
+ << endl
+ << "::std::auto_ptr< " << type << " > r (" << endl
+ << fq_name (e, "parser") << " (" << endl
+ << "d, f | " << flags_type << "::own_dom, p));"
+ << endl
+ << "return r;"
+ << "}";
+
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (const " << string_type << "& u," << endl
+ << xerces_ns << "::DOMErrorHandler& h," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "& p)"
+ << "{"
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > d (" << endl
+ << "::xsd::cxx::xml::dom::parse< " << char_type << " > (" << endl
+ << "u, h, p, f";
+
+ if (options.value<CLI::disable_multi_import> ())
+ os << " | ::xsd::cxx::xml::dom::no_muliple_imports";
+
+ os << "));"
+ << endl
+ << "if (!d.get ())" << endl
+ << "throw ::xsd::cxx::tree::parsing< " << char_type << " > ();"
+ << endl
+ << "::std::auto_ptr< " << type << " > r (" << endl
+ << fq_name (e, "parser") << " (" << endl
+ << "d, f | " << flags_type << "::own_dom, p));"
+ << endl
+ << "return r;"
+ << "}";
+
+
+ // istream
+ //
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (::std::istream& is," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "& p)"
+ << "{"
+ << "::xsd::cxx::xml::auto_initializer i (" << endl
+ << "(f & " << flags_type << "::dont_initialize) == 0," << endl
+ << "(f & " << flags_type << "::keep_dom) == 0);"
+ << endl
+ << "::xsd::cxx::xml::sax::std_input_source isrc (is);"
+ << "return " << fq_name (e, "parser") << " (isrc, f, p);"
+ << "}";
+
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (::std::istream& is," << endl
+ << error_handler << "& h," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "& p)"
+ << "{"
+ << "::xsd::cxx::xml::auto_initializer i (" << endl
+ << "(f & " << flags_type << "::dont_initialize) == 0," << endl
+ << "(f & " << flags_type << "::keep_dom) == 0);"
+ << endl
+ << "::xsd::cxx::xml::sax::std_input_source isrc (is);"
+ << "return " << fq_name (e, "parser") << " (isrc, h, f, p);"
+ << "}";
+
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (::std::istream& is," << endl
+ << xerces_ns << "::DOMErrorHandler& h," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "& p)"
+ << "{"
+ << "::xsd::cxx::xml::sax::std_input_source isrc (is);"
+ << "return " << fq_name (e, "parser") << " (isrc, h, f, p);"
+ << "}";
+
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (::std::istream& is," << endl
+ << "const " << string_type << "& sid," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "& p)"
+ << "{"
+ << "::xsd::cxx::xml::auto_initializer i (" << endl
+ << "(f & " << flags_type << "::dont_initialize) == 0," << endl
+ << "(f & " << flags_type << "::keep_dom) == 0);"
+ << endl
+ << "::xsd::cxx::xml::sax::std_input_source isrc (is, sid);"
+ << "return " << fq_name (e, "parser") << " (isrc, f, p);"
+ << "}";
+
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (::std::istream& is," << endl
+ << "const " << string_type << "& sid," << endl
+ << error_handler << "& h," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "& p)"
+ << "{"
+ << "::xsd::cxx::xml::auto_initializer i (" << endl
+ << "(f & " << flags_type << "::dont_initialize) == 0," << endl
+ << "(f & " << flags_type << "::keep_dom) == 0);"
+ << endl
+ << "::xsd::cxx::xml::sax::std_input_source isrc (is, sid);"
+ << "return " << fq_name (e, "parser") << " (isrc, h, f, p);"
+ << "}";
+
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (::std::istream& is," << endl
+ << "const " << string_type << "& sid," << endl
+ << xerces_ns << "::DOMErrorHandler& h," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "& p)"
+ << "{"
+ << "::xsd::cxx::xml::sax::std_input_source isrc (is, sid);"
+ << "return " << fq_name (e, "parser") << " (isrc, h, f, p);"
+ << "}";
+
+
+ // InputSource.
+ //
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (" << xerces_ns << "::InputSource& i," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "& p)"
+ << "{"
+ << "::xsd::cxx::tree::error_handler< " << char_type << " > h;"
+ << endl
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > d (" << endl
+ << "::xsd::cxx::xml::dom::parse< " << char_type << " > (" << endl
+ << "i, h, p, f";
+
+ if (options.value<CLI::disable_multi_import> ())
+ os << " | ::xsd::cxx::xml::dom::no_muliple_imports";
+
+ os << "));"
+ << endl
+ << "h.throw_if_failed< ::xsd::cxx::tree::parsing< " <<
+ char_type << " > > ();"
+ << endl
+ << "::std::auto_ptr< " << type << " > r (" << endl
+ << fq_name (e, "parser") << " (" << endl
+ << "d, f | " << flags_type << "::own_dom, p));"
+ << endl
+ << "return r;"
+ << "}";
+
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (" << xerces_ns << "::InputSource& i," << endl
+ << error_handler << "& h," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "& p)"
+ << "{"
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > d (" << endl
+ << "::xsd::cxx::xml::dom::parse< " << char_type << " > (" << endl
+ << "i, h, p, f";
+
+ if (options.value<CLI::disable_multi_import> ())
+ os << " | ::xsd::cxx::xml::dom::no_muliple_imports";
+
+ os << "));"
+ << endl
+ << "if (!d.get ())" << endl
+ << "throw ::xsd::cxx::tree::parsing< " << char_type << " > ();"
+ << endl
+ << "::std::auto_ptr< " << type << " > r (" << endl
+ << fq_name (e, "parser") << " (" << endl
+ << "d, f | " << flags_type << "::own_dom, p));"
+ << endl
+ << "return r;"
+ << "}";
+
+
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (" << xerces_ns << "::InputSource& i," << endl
+ << xerces_ns << "::DOMErrorHandler& h," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "& p)"
+ << "{"
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > d (" << endl
+ << "::xsd::cxx::xml::dom::parse< " << char_type << " > (" << endl
+ << "i, h, p, f";
+
+ if (options.value<CLI::disable_multi_import> ())
+ os << " | ::xsd::cxx::xml::dom::no_muliple_imports";
+
+ os << "));"
+ << endl
+ << "if (!d.get ())" << endl
+ << "throw ::xsd::cxx::tree::parsing< " << char_type << " > ();"
+ << endl
+ << "::std::auto_ptr< " << type << " > r (" << endl
+ << fq_name (e, "parser") << " (" << endl
+ << "d, f | " << flags_type << "::own_dom, p));"
+ << endl
+ << "return r;"
+ << "}";
+
+
+ // DOM.
+ //
+
+ Boolean fund (false);
+
+ {
+ IsFundamentalType test (fund);
+ test.dispatch (t);
+ }
+
+ // Check if we need to handle xsi:type and substitution groups.
+ // If this element's type is anonymous or mapped to a fundamental
+ // C++ type then we don't need to do anything.
+ //
+ Boolean poly (!fund && polymorphic &&
+ !t.context ().count ("anonymous"));
+
+ // const DOMDocument&
+ //
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (const " << xerces_ns << "::DOMDocument& d," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "& p)"
+ << "{"
+ << "if (f & " << flags_type << "::keep_dom)"
+ << "{"
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > c (" << endl
+ << "static_cast< " << xerces_ns <<
+ "::DOMDocument* > (d.cloneNode (true)));"
+ << endl
+ << "::std::auto_ptr< " << type << " > r (" << endl
+ << fq_name (e, "parser") << " (" << endl
+ << "c, f | " << flags_type << "::own_dom, p));"
+ << endl
+ << "return r;"
+ << "}"
+ << "const " << xerces_ns << "::DOMElement& e (*d.getDocumentElement ());"
+ << "const " << qname_type << " n (" << endl
+ << "::xsd::cxx::xml::dom::name< " << char_type << " > (e));"
+ << endl;
+
+ if (poly)
+ {
+ // aCC cannot handle an inline call to type_factory_map_instance.
+ //
+ os << "::xsd::cxx::tree::type_factory_map< " << char_type <<
+ " >& tfm (" << endl
+ << "::xsd::cxx::tree::type_factory_map_instance< 0, " <<
+ char_type << " > ());"
+ << endl
+ << "::std::auto_ptr< ::xsd::cxx::tree::type > tmp (" << endl
+ << "tfm.create (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (e.namespace_().name ()) << "," << endl
+ << "&::xsd::cxx::tree::factory_impl< " << type << " >," << endl
+ << "true, true, e, n, f, 0));"
+ << endl
+ << "if (tmp.get () != 0)"
+ << "{"
+ << "::std::auto_ptr< " << type << " > r (" << endl
+ << "dynamic_cast< " << type << "* > (tmp.get ()));"
+ << endl
+ << "if (r.get ())" << endl
+ << "tmp.release ();"
+ << "else" << endl
+ << "throw ::xsd::cxx::tree::not_derived< " << char_type <<
+ " > ();"
+ << endl;
+ }
+ else
+ {
+ os << "if (n.name () == " << L << strlit (e.name ()) << " &&" << endl
+ << "n.namespace_ () == " << L << strlit (e.namespace_().name ()) << ")"
+ << "{";
+
+ if (fund)
+ {
+ os << "::std::auto_ptr< " << type << " > r (" << endl
+ << "new " << type << " (" << endl
+ << "::xsd::cxx::tree::traits< " << type << ", " <<
+ char_type;
+
+ if (t.is_a<SemanticGraph::Fundamental::Double> ())
+ os << ", ::xsd::cxx::tree::schema_type::double_";
+ else if (t.is_a<SemanticGraph::Fundamental::Decimal> ())
+ os << ", ::xsd::cxx::tree::schema_type::decimal";
+
+ os << " >::create (" << endl
+ << "e, f, 0)));";
+ }
+ else
+ {
+ os << "::std::auto_ptr< " << type << " > r (" << endl
+ << "::xsd::cxx::tree::traits< " << type << ", " <<
+ char_type << " >::create (" << endl
+ << "e, f, 0));";
+ }
+ }
+
+ os << "return r;"
+ << "}"
+ << "throw ::xsd::cxx::tree::unexpected_element < " <<
+ char_type << " > (" << endl
+ << "n.name ()," << endl
+ << "n.namespace_ ()," << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (e.namespace_().name ()) << ");"
+ << "}";
+
+
+ // dom::auto_ptr<DOMDocument>
+ //
+ os << "::std::auto_ptr< " << type << " >" << endl
+ << name << " (" << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument >& d," << endl
+ << flags_type << " f," << endl
+ << "const " << properties_type << "&)"
+ << "{"
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > c (" << endl
+ << "((f & " << flags_type << "::keep_dom) &&" << endl
+ << "!(f & " << flags_type << "::own_dom))" << endl
+ << "? static_cast< " << xerces_ns << "::DOMDocument* > (" <<
+ "d->cloneNode (true))" << endl
+ << ": 0);"
+ << endl
+ << xerces_ns << "::DOMDocument& doc (c.get () ? *c : *d);"
+ << "const " << xerces_ns << "::DOMElement& e (" <<
+ "*doc.getDocumentElement ());"
+ << endl
+ << "const " << qname_type << " n (" << endl
+ << "::xsd::cxx::xml::dom::name< " << char_type << " > (e));"
+ << endl
+ << "if (f & " << flags_type << "::keep_dom)" << endl
+ << "doc.setUserData (" << dom_node_key << "," << endl
+ << "(c.get () ? &c : &d)," << endl
+ << "0);"
+ << endl;
+
+ if (poly)
+ {
+ // aCC cannot handle an inline call to type_factory_map_instance.
+ //
+ os << "::xsd::cxx::tree::type_factory_map< " << char_type <<
+ " >& tfm (" << endl
+ << "::xsd::cxx::tree::type_factory_map_instance< 0, " <<
+ char_type << " > ());"
+ << endl
+ << "::std::auto_ptr< ::xsd::cxx::tree::type > tmp (" << endl
+ << "tfm.create (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (e.namespace_().name ()) << "," << endl
+ << "&::xsd::cxx::tree::factory_impl< " << type << " >," << endl
+ << "true, true, e, n, f, 0));"
+ << endl
+ << "if (tmp.get () != 0)"
+ << "{";
+ }
+ else
+ {
+ os << "if (n.name () == " << L << strlit (e.name ()) << " &&" << endl
+ << "n.namespace_ () == " << L << strlit (e.namespace_().name ()) << ")"
+ << "{";
+
+ if (fund)
+ {
+ os << "::std::auto_ptr< " << type << " > r (" << endl
+ << "new " << type << " (" << endl
+ << "::xsd::cxx::tree::traits< " << type << ", " <<
+ char_type;
+
+ if (t.is_a<SemanticGraph::Fundamental::Double> ())
+ os << ", ::xsd::cxx::tree::schema_type::double_";
+ else if (t.is_a<SemanticGraph::Fundamental::Decimal> ())
+ os << ", ::xsd::cxx::tree::schema_type::decimal";
+
+ os << " >::create (" << endl
+ << "e, f, 0)));";
+ }
+ else
+ {
+ os << "::std::auto_ptr< " << type << " > r (" << endl
+ << "::xsd::cxx::tree::traits< " << type << ", " <<
+ char_type << " >::create (" << endl
+ << "e, f, 0));";
+ }
+ }
+
+ if (poly)
+ {
+ os << endl
+ << "::std::auto_ptr< " << type << " > r (" << endl
+ << "dynamic_cast< " << type << "* > (tmp.get ()));"
+ << endl
+ << "if (r.get ())" << endl
+ << "tmp.release ();"
+ << "else" << endl
+ << "throw ::xsd::cxx::tree::not_derived< " << char_type <<
+ " > ();"
+ << endl;
+ }
+
+ os << "return r;"
+ << "}"
+ << "throw ::xsd::cxx::tree::unexpected_element < " <<
+ char_type << " > (" << endl
+ << "n.name ()," << endl
+ << "n.namespace_ ()," << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (e.namespace_().name ()) << ");"
+ << "}";
+ }
+
+ private:
+ String
+ type_name (Type& e)
+ {
+ std::wostringstream o;
+
+ MemberTypeName type (*this, o);
+ type.dispatch (e.type ());
+
+ return o.str ();
+ }
+ };
+ }
+
+ Void
+ generate_parser_source (Context& ctx,
+ UnsignedLong first,
+ UnsignedLong last)
+ {
+ ctx.os << "#include <istream>" << endl
+ << "#include <xsd/cxx/xml/sax/std-input-source.hxx>" << endl
+ << "#include <xsd/cxx/tree/error-handler.hxx>" << endl
+ << endl;
+
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+ Traversal::Names names_ns, names;
+ Namespace ns (ctx, first, last);
+ ElementFunction element (ctx);
+
+ schema >> sources >> schema;
+ schema >> names_ns >> ns >> names >> element;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/tree/parser-source.hxx b/xsd/cxx/tree/parser-source.hxx
new file mode 100644
index 0000000..9b0875d
--- /dev/null
+++ b/xsd/cxx/tree/parser-source.hxx
@@ -0,0 +1,24 @@
+// file : xsd/cxx/tree/parser-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_PARSER_SOURCE_HXX
+#define CXX_TREE_PARSER_SOURCE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ Void
+ generate_parser_source (Context&,
+ UnsignedLong first,
+ UnsignedLong last);
+ }
+}
+
+#endif // CXX_TREE_PARSER_SOURCE_HXX
diff --git a/xsd/cxx/tree/serialization-header.cxx b/xsd/cxx/tree/serialization-header.cxx
new file mode 100644
index 0000000..090f0f5
--- /dev/null
+++ b/xsd/cxx/tree/serialization-header.cxx
@@ -0,0 +1,581 @@
+// file : xsd/cxx/tree/serialization-header.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/serialization-header.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ struct List: Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String name (ename (l));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (l, name) && !name)
+ return;
+
+ // operator<< (xercesc::DOMElement)
+ //
+ os << inst_exp
+ << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMElement&, " <<
+ "const " << name << "&);"
+ << endl;
+
+ // operator<< (xercesc::DOMAttr)
+ //
+ os << inst_exp
+ << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMAttr&, " <<
+ "const " << name << "&);"
+ << endl;
+
+ // operator<< (list_stream)
+ //
+ os << inst_exp
+ << "void" << endl
+ << "operator<< (" << list_stream_type << "&," << endl
+ << "const " << name << "&);"
+ << endl;
+
+ }
+ };
+
+
+ struct Union: Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String name (ename (u));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (u, name) && !name)
+ return;
+
+ // operator<< (xercesc::DOMElement)
+ //
+ os << inst_exp
+ << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMElement&, " <<
+ "const " << name << "&);"
+ << endl;
+
+ // operator<< (xercesc::DOMAttr)
+ //
+ os << inst_exp
+ << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMAttr&, " <<
+ "const " << name << "&);"
+ << endl;
+
+ // operator<< (list_stream)
+ //
+ os << inst_exp
+ << "void" << endl
+ << "operator<< (" << list_stream_type << "&," << endl
+ << "const " << name << "&);"
+ << endl;
+ }
+ };
+
+
+ struct Enumeration: Traversal::Enumeration, protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String name (ename (e));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (e, name) && !name)
+ return;
+
+ // operator<< (xercesc::DOMElement)
+ //
+ os << inst_exp
+ << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMElement&, " <<
+ "const " << name << "&);"
+ << endl;
+
+ // operator<< (xercesc::DOMAttr)
+ //
+ os << inst_exp
+ << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMAttr&, " <<
+ "const " << name << "&);"
+ << endl;
+
+ // operator<< (list_stream)
+ //
+ os << inst_exp
+ << "void" << endl
+ << "operator<< (" << list_stream_type << "&," << endl
+ << "const " << name << "&);"
+ << endl;
+ }
+ };
+
+ struct Complex : Traversal::Complex, protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String name (ename (c));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (c, name) && !name)
+ return;
+
+ // operator<< (xercesc::DOMElement)
+ //
+ os << inst_exp
+ << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMElement&, " <<
+ "const " << name << "&);"
+ << endl;
+
+ Boolean simple (true);
+ {
+ IsSimpleType t (simple);
+ t.dispatch (c);
+ }
+
+ if (simple)
+ {
+ // operator<< (xercesc::DOMAttr)
+ //
+ os << inst_exp
+ << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMAttr&, " <<
+ "const " << name << "&);"
+ << endl;
+
+ // operator<< (list_stream)
+ //
+ os << inst_exp
+ << "void" << endl
+ << "operator<< (" << list_stream_type << "&," << endl
+ << "const " << name << "&);"
+ << endl;
+ }
+ }
+ };
+
+ struct ElementType: Traversal::Element,
+ GlobalElementBase,
+ protected virtual Context
+ {
+ ElementType (Context& c)
+ : Context (c), GlobalElementBase (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (doc_root_p (e))
+ {
+ // operator<< (xercesc::DOMElement)
+ //
+ os << inst_exp
+ << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMElement&, " <<
+ "const " << ename (e) << "&);"
+ << endl;
+ }
+ }
+ };
+
+ struct ElementFunction: Traversal::Element,
+ GlobalElementBase,
+ protected virtual Context
+ {
+ ElementFunction (Context& c)
+ : Context (c), GlobalElementBase (c)
+ {
+ }
+
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (!doc_root_p (e))
+ return;
+
+ String const& name (eserializer (e));
+ String const& error_handler (error_handler_type);
+ String const& namespace_infomap (namespace_infomap_type);
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @name Serialization functions for the %" <<
+ comment (e.name ()) << " document root." << endl;
+
+ if (e.annotated ())
+ {
+ os << " *" << endl;
+ write_annotation (e.annotation ());
+ }
+
+ os << " */" << endl
+ << "//@{" << endl
+ << endl;
+ }
+
+ if (!doxygen)
+ {
+ os << "// Serialize to std::ostream." << endl
+ << "//" << endl
+ << endl;
+ }
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Serialize to a standard output stream." << endl
+ << " *" << endl
+ << " * @param os A standrad output stream." << endl
+ << " * @param x An object model to serialize." << endl
+ << " * @param m A namespace information map." << endl
+ << " * @param e A character encoding to produce XML in." << endl
+ << " * @param f Serialization flags." << endl
+ << " *" << endl
+ << " * This function uses exceptions to report " <<
+ "serialization errors." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "void" << endl
+ << name << " (::std::ostream& os," << endl
+ << "const " << type_name (e) << "& x, " << endl
+ << "const " << namespace_infomap << "& m = " <<
+ namespace_infomap << " ()," << endl
+ << "const " << string_type << "& e = " << L << "\"UTF-8\"," << endl
+ << flags_type << " f = 0);"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Serialize to a standard output stream with an " <<
+ "error handler." << endl
+ << " *" << endl
+ << " * @param os A standrad output stream." << endl
+ << " * @param x An object model to serialize." << endl
+ << " * @param eh An error handler." << endl
+ << " * @param m A namespace information map." << endl
+ << " * @param e A character encoding to produce XML in." << endl
+ << " * @param f Serialization flags." << endl
+ << " *" << endl
+ << " * This function reports serialization errors by " <<
+ "calling the error" << endl
+ << " * handler." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "void" << endl
+ << name << " (::std::ostream& os," << endl
+ << "const " << type_name (e) << "& x, " << endl
+ << error_handler << "& eh," << endl
+ << "const " << namespace_infomap << "& m = " <<
+ namespace_infomap << " ()," << endl
+ << "const " << string_type << "& e = " << L << "\"UTF-8\"," << endl
+ << flags_type << " f = 0);"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Serialize to a standard output stream with a " <<
+ "Xerces-C++ DOM" << endl
+ << " * error handler." << endl
+ << " *" << endl
+ << " * @param os A standrad output stream." << endl
+ << " * @param x An object model to serialize." << endl
+ << " * @param eh A Xerces-C++ DOM error handler." << endl
+ << " * @param m A namespace information map." << endl
+ << " * @param e A character encoding to produce XML in." << endl
+ << " * @param f Serialization flags." << endl
+ << " *" << endl
+ << " * This function reports serialization errors by " <<
+ "calling the error" << endl
+ << " * handler." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "void" << endl
+ << name << " (::std::ostream& os," << endl
+ << "const " << type_name (e) << "& x, " << endl
+ << xerces_ns << "::DOMErrorHandler& eh," << endl
+ << "const " << namespace_infomap << "& m = " <<
+ namespace_infomap << " ()," << endl
+ << "const " << string_type << "& e = " << L << "\"UTF-8\"," << endl
+ << flags_type << " f = 0);"
+ << endl;
+
+ if (!doxygen)
+ {
+ os << "// Serialize to xercesc::XMLFormatTarget." << endl
+ << "//" << endl
+ << endl;
+ }
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Serialize to a Xerces-C++ XML format target." << endl
+ << " *" << endl
+ << " * @param ft A Xerces-C++ XML format target." << endl
+ << " * @param x An object model to serialize." << endl
+ << " * @param m A namespace information map." << endl
+ << " * @param e A character encoding to produce XML in." << endl
+ << " * @param f Serialization flags." << endl
+ << " *" << endl
+ << " * This function uses exceptions to report " <<
+ "serialization errors." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "void" << endl
+ << name << " (" << xerces_ns << "::XMLFormatTarget& ft," << endl
+ << "const " << type_name (e) << "& x, " << endl
+ << "const " << namespace_infomap << "& m = " <<
+ namespace_infomap << " ()," << endl
+ << "const " << string_type << "& e = " << L << "\"UTF-8\"," << endl
+ << flags_type << " f = 0);"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Serialize to a Xerces-C++ XML format target " <<
+ "with an error" << endl
+ << " * handler." << endl
+ << " *" << endl
+ << " * @param ft A Xerces-C++ XML format target." << endl
+ << " * @param x An object model to serialize." << endl
+ << " * @param eh An error handler." << endl
+ << " * @param m A namespace information map." << endl
+ << " * @param e A character encoding to produce XML in." << endl
+ << " * @param f Serialization flags." << endl
+ << " *" << endl
+ << " * This function reports serialization errors by " <<
+ "calling the error" << endl
+ << " * handler." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "void" << endl
+ << name << " (" << xerces_ns << "::XMLFormatTarget& ft," << endl
+ << "const " << type_name (e) << "& x, " << endl
+ << error_handler << "& eh," << endl
+ << "const " << namespace_infomap << "& m = " <<
+ namespace_infomap << " ()," << endl
+ << "const " << string_type << "& e = " << L << "\"UTF-8\"," << endl
+ << flags_type << " f = 0);"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Serialize to a Xerces-C++ XML format target " <<
+ "with a" << endl
+ << " * Xerces-C++ DOM error handler." << endl
+ << " *" << endl
+ << " * @param ft A Xerces-C++ XML format target." << endl
+ << " * @param x An object model to serialize." << endl
+ << " * @param eh A Xerces-C++ DOM error handler." << endl
+ << " * @param m A namespace information map." << endl
+ << " * @param e A character encoding to produce XML in." << endl
+ << " * @param f Serialization flags." << endl
+ << " *" << endl
+ << " * This function reports serialization errors by " <<
+ "calling the error" << endl
+ << " * handler." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << "void" << endl
+ << name << " (" << xerces_ns << "::XMLFormatTarget& ft," << endl
+ << "const " << type_name (e) << "& x, " << endl
+ << xerces_ns << "::DOMErrorHandler& eh," << endl
+ << "const " << namespace_infomap << "& m = " <<
+ namespace_infomap << " ()," << endl
+ << "const " << string_type << "& e = " << L << "\"UTF-8\"," << endl
+ << flags_type << " f = 0);"
+ << endl;
+
+ if (!doxygen)
+ {
+ os << "// Serialize to an existing xercesc::DOMDocument." << endl
+ << "//" << endl
+ << endl;
+ }
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Serialize to an existing Xerces-C++ DOM document." << endl
+ << " *" << endl
+ << " * @param d A Xerces-C++ DOM document." << endl
+ << " * @param x An object model to serialize." << endl
+ << " * @param f Serialization flags." << endl
+ << " *" << endl
+ << " * Note that it is your responsibility to create the " <<
+ "DOM document" << endl
+ << " * with the correct root element as well as set the " <<
+ "necessary" << endl
+ << " * namespace mapping attributes." << endl
+ << " */" << endl;
+ }
+ os << inst_exp
+ << "void" << endl
+ << name << " (" << xerces_ns << "::DOMDocument& d," << endl
+ << "const " << type_name (e) << "& x," << endl
+ << flags_type << " f = 0);"
+ << endl;
+
+ if (!doxygen)
+ {
+ os << "// Serialize to a new xercesc::DOMDocument." << endl
+ << "//" << endl
+ << endl;
+ }
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Serialize to a new Xerces-C++ DOM document." << endl
+ << " *" << endl
+ << " * @param x An object model to serialize." << endl
+ << " * @param m A namespace information map." << endl
+ << " * @param f Serialization flags." << endl
+ << " * @return A pointer to the new Xerces-C++ DOM document." << endl
+ << " */" << endl;
+ }
+
+ os << inst_exp
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument >" << endl
+ << name << " (const " << type_name (e) << "& x, " << endl
+ << "const " << namespace_infomap << "& m = " <<
+ namespace_infomap << " ()," << endl
+ << flags_type << " f = 0);"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "//@}" << endl
+ << endl;
+ }
+ }
+
+ private:
+ String
+ type_name (Type& e)
+ {
+ std::wostringstream o;
+
+ MemberTypeName type (*this, o);
+ type.dispatch (e.type ());
+
+ return o.str ();
+ }
+ };
+
+ }
+
+ Void
+ generate_serialization_header (Context& ctx)
+ {
+ Boolean elemen_type (ctx.options.value<CLI::generate_element_type> ());
+
+ if (!elemen_type)
+ ctx.os << "#include <iosfwd>" << endl
+ << endl
+ << "#include <xercesc/dom/DOMDocument.hpp>" << endl
+ << "#include <xercesc/dom/DOMErrorHandler.hpp>" << endl
+ << "#include <xercesc/framework/XMLFormatter.hpp>" << endl
+ << endl
+ << "#include <xsd/cxx/xml/dom/auto-ptr.hxx>" << endl
+ << endl;
+
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names names_ns, names;
+
+ Namespace ns (ctx);
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+ ElementType element_type (ctx);
+ ElementFunction element_function (ctx);
+
+ schema >> sources >> schema;
+ schema >> names_ns >> ns >> names;
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ if (elemen_type)
+ names >> element_type;
+ else
+ names >> element_function;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/tree/serialization-header.hxx b/xsd/cxx/tree/serialization-header.hxx
new file mode 100644
index 0000000..c6909c8
--- /dev/null
+++ b/xsd/cxx/tree/serialization-header.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/tree/serialization-header.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_SERIALIZATION_HEADER_HXX
+#define CXX_TREE_SERIALIZATION_HEADER_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ Void
+ generate_serialization_header (Context&);
+ }
+}
+
+#endif // CXX_TREE_SERIALIZATION_HEADER_HXX
diff --git a/xsd/cxx/tree/serialization-source.cxx b/xsd/cxx/tree/serialization-source.cxx
new file mode 100644
index 0000000..1d96883
--- /dev/null
+++ b/xsd/cxx/tree/serialization-source.cxx
@@ -0,0 +1,1342 @@
+// file : xsd/cxx/tree/serialization-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/serialization-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ enum schema_type
+ {
+ st_other,
+ st_double,
+ st_decimal
+ };
+
+ enum schema_type
+ schema_type (SemanticGraph::Type& t)
+ {
+ if (t.is_a<SemanticGraph::Fundamental::Double> ())
+ return st_double;
+ else if (t.is_a<SemanticGraph::Fundamental::Decimal> ())
+ return st_decimal;
+ else
+ return st_other;
+ }
+
+
+ //
+ //
+ struct List : Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String name (ename (l));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (l, name) && !name)
+ return;
+
+ SemanticGraph::Type& item_type (l.argumented ().type ());
+ String base (L"::xsd::cxx::tree::list< " +
+ item_type_name (item_type) + L", " + char_type);
+
+ if (item_type.is_a<SemanticGraph::Fundamental::Double> ())
+ base += L", ::xsd::cxx::tree::schema_type::double_";
+ else if (item_type.is_a<SemanticGraph::Fundamental::Decimal> ())
+ base += L", ::xsd::cxx::tree::schema_type::decimal";
+
+ base += L" >";
+
+ // operator<< (xercesc::DOMElement)
+ //
+ os << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMElement& e, " <<
+ "const " << name << "& i)"
+ << "{"
+ << "e << static_cast< const " << base << "& > (i);"
+ << "}";
+
+ // operator<< (xercesc::DOMAttr)
+ //
+ os << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMAttr& a, " <<
+ "const " << name << "& i)"
+ << "{"
+ << "a << static_cast< const " << base << "& > (i);"
+ << "}";
+
+ // operator<< (list_stream)
+ //
+ os << "void" << endl
+ << "operator<< (" << list_stream_type << "& l," << endl
+ << "const " << name << "& i)"
+ << "{"
+ << "l << static_cast< const " << base << "& > (i);"
+ << "}";
+
+ // Register with type factory map.
+ //
+ if (polymorphic && !l.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (l));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::type_serializer_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_type_serializer_init (" << endl
+ << L << strlit (l.name ()) << "," << endl
+ << L << strlit (xml_ns_name (l)) << ");"
+ << endl
+ << endl;
+ }
+ }
+
+ private:
+ String
+ item_type_name (SemanticGraph::Type& t)
+ {
+ std::wostringstream o;
+
+ MemberTypeName type (*this, o);
+ type.dispatch (t);
+
+ return o.str ();
+ }
+ };
+
+
+ struct Union : Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String name (ename (u));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (u, name) && !name)
+ return;
+
+ String const& base (xs_string_type);
+
+ // operator<< (xercesc::DOMElement)
+ //
+ os << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMElement& e, " <<
+ "const " << name << "& i)"
+ << "{"
+ << "e << static_cast< const " << base << "& > (i);"
+ << "}";
+
+ // operator<< (xercesc::DOMAttr)
+ //
+ os << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMAttr& a, " <<
+ "const " << name << "& i)"
+ << "{"
+ << "a << static_cast< const " << base << "& > (i);"
+ << "}";
+
+ // operator<< (list_stream)
+ //
+ os << "void" << endl
+ << "operator<< (" << list_stream_type << "& l," << endl
+ << "const " << name << "& i)"
+ << "{"
+ << "l << static_cast< const " << base << "& > (i);"
+ << "}";
+
+ // Register with type factory map.
+ //
+ if (polymorphic && !u.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (u));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::type_serializer_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_type_serializer_init (" << endl
+ << L << strlit (u.name ()) << "," << endl
+ << L << strlit (xml_ns_name (u)) << ");"
+ << endl
+ << endl;
+ }
+ }
+ };
+
+
+ struct Enumeration : Traversal::Enumeration, protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c), base_ (c)
+ {
+ inherits_base_ >> base_;
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String name (ename (e));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (e, name) && !name)
+ return;
+
+ // operator<< (xercesc::DOMElement)
+ //
+ os << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMElement& e, " <<
+ "const " << name << "& i)"
+ << "{"
+ << "e << static_cast< const ";
+
+ inherits (e, inherits_base_);
+
+ os << "& > (i);"
+ << "}";
+
+
+ // operator<< (xercesc::DOMAttr)
+ //
+ os << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMAttr& a, " <<
+ "const " << name << "& i)"
+ << "{"
+ << "a << static_cast< const ";
+
+ inherits (e, inherits_base_);
+
+ os << "& > (i);"
+ << "}";
+
+
+ // operator<< (list_stream)
+ //
+ os << "void" << endl
+ << "operator<< (" << list_stream_type << "& l," << endl
+ << "const " << name << "& i)"
+ << "{"
+ << "l << static_cast< const ";
+
+ inherits (e, inherits_base_);
+
+ os << "& > (i);"
+ << "}";
+
+
+ // Register with type factory map.
+ //
+ if (polymorphic && !e.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (e));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::type_serializer_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_type_serializer_init (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (xml_ns_name (e)) << ");"
+ << endl
+ << endl;
+ }
+ }
+
+ private:
+ Traversal::Inherits inherits_base_;
+ BaseTypeName base_;
+ };
+
+ struct Element : Traversal::Element, protected virtual Context
+ {
+ Element (Context& c, String const& scope_)
+ : Context (c), scope (scope_)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (skip (e))
+ return;
+
+ String const& aname (eaname (e));
+ String ns (e.qualified () ? e.namespace_ ().name () : "");
+ String type (scope + L"::" + etype (e));
+
+ // Check if we need to handle xsi:type and substitution groups.
+ // If this element's type is anonymous or mapped to a fundamental
+ // C++ type then we don't need to do anything. Note that if the
+ // type is anonymous then it can't be derived from which makes it
+ // impossible to substitute or dynamically-type with xsi:type.
+ //
+ SemanticGraph::Type& t (e.type ());
+ Boolean poly (polymorphic && !t.context ().count ("anonymous"));
+
+ if (poly)
+ {
+ Boolean fund (false);
+ IsFundamentalType traverser (fund);
+ traverser.dispatch (t);
+ poly = !fund;
+ }
+
+ os << "// " << comment (e.name ()) << endl
+ << "//" << endl;
+
+ // aCC cannot handle an inline call to type_serializer_map_instance.
+ //
+ if (poly)
+ {
+ os << "{"
+ << "::xsd::cxx::tree::type_serializer_map< " << char_type
+ << " >& tsm (" << endl
+ << "::xsd::cxx::tree::type_serializer_map_instance< 0, " <<
+ char_type << " > ());"
+ << endl;
+ }
+
+ if (max (e) != 1)
+ {
+ // sequence
+ //
+ os << "for (" << scope << "::" << econst_iterator (e) << endl
+ << "b (i." << aname << " ().begin ()), " <<
+ "n (i." << aname << " ().end ());" << endl
+ << "b != n; ++b)"
+ << "{";
+
+ if (poly)
+ {
+ os << "if (typeid (" << type << ") == typeid (*b))"
+ << "{"
+ << xerces_ns << "::DOMElement& s (" << endl
+ << "::xsd::cxx::xml::dom::create_element (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << (ns ? L + strlit (ns) + L",\n" : L"")
+ << "e));"
+ << endl
+ << "s << *b;"
+ << "}"
+ << "else" << endl
+ << "tsm.serialize (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (ns) << "," << endl
+ << (e.global () ? "true" : "false") << ", " <<
+ (e.qualified () ? "true" : "false") << ", e, *b);";
+ }
+ else
+ {
+ os << xerces_ns << "::DOMElement& s (" << endl
+ << "::xsd::cxx::xml::dom::create_element (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << (ns ? L + strlit (ns) + L",\n" : L"")
+ << "e));"
+ << endl;
+
+ switch (schema_type (t))
+ {
+ case st_other:
+ {
+ os << "s << *b;";
+ break;
+ }
+ case st_double:
+ {
+ os << "s << " << as_double_type << " (*b);";
+ break;
+ }
+ case st_decimal:
+ {
+ os << "s << " << as_decimal_type << " (*b);";
+ break;
+ }
+ }
+ }
+
+ os << "}";
+ }
+ else if (min (e) == 0)
+ {
+ // optional
+ //
+ os << "if (i." << aname << " ())"
+ << "{";
+
+ if (poly)
+ {
+ os << "const " << type << "& x (*i." << aname << " ());"
+ << "if (typeid (" << type << ") == typeid (x))"
+ << "{"
+ << xerces_ns << "::DOMElement& s (" << endl
+ << "::xsd::cxx::xml::dom::create_element (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << (ns ? L + strlit (ns) + L",\n" : L"")
+ << "e));"
+ << endl
+ << "s << x;"
+ << "}"
+ << "else" << endl
+ << "tsm.serialize (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (ns) << "," << endl
+ << (e.global () ? "true" : "false") << ", " <<
+ (e.qualified () ? "true" : "false") << ", e, x);";
+ }
+ else
+ {
+ os << xerces_ns << "::DOMElement& s (" << endl
+ << "::xsd::cxx::xml::dom::create_element (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << (ns ? L + strlit (ns) + L",\n" : L"")
+ << "e));"
+ << endl;
+
+ switch (schema_type (t))
+ {
+ case st_other:
+ {
+ os << "s << *i." << aname << " ();";
+ break;
+ }
+ case st_double:
+ {
+ os << "s << " << as_double_type << "(*i." << aname << " ());";
+ break;
+ }
+ case st_decimal:
+ {
+ os << "s << " << as_decimal_type << "(*i." << aname << " ());";
+ break;
+ }
+ }
+ }
+
+ os << "}";
+ }
+ else
+ {
+ // one
+ //
+ if (poly)
+ {
+ os << "const " << type << "& x (i." << aname << " ());"
+ << "if (typeid (" << type << ") == typeid (x))"
+ << "{"
+ << xerces_ns << "::DOMElement& s (" << endl
+ << "::xsd::cxx::xml::dom::create_element (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << (ns ? L + strlit (ns) + L",\n" : L"")
+ << "e));"
+ << endl
+ << "s << x;"
+ << "}"
+ << "else" << endl
+ << "tsm.serialize (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (ns) << "," << endl
+ << (e.global () ? "true" : "false") << ", " <<
+ (e.qualified () ? "true" : "false") << ", e, x);";
+ }
+ else
+ {
+ os << "{"
+ << xerces_ns << "::DOMElement& s (" << endl
+ << "::xsd::cxx::xml::dom::create_element (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << (ns ? L + strlit (ns) + L",\n" : L"")
+ << "e));"
+ << endl;
+
+ switch (schema_type (t))
+ {
+ case st_other:
+ {
+ os << "s << i." << aname << " ();";
+ break;
+ }
+ case st_double:
+ {
+ os << "s << " << as_double_type << "(i." << aname << " ());";
+ break;
+ }
+ case st_decimal:
+ {
+ os << "s << " << as_decimal_type << "(i." << aname << " ());";
+ break;
+ }
+ }
+
+ os << "}";
+ }
+ }
+
+ if (poly)
+ os << "}";
+ }
+
+ private:
+ String scope;
+ };
+
+ struct Any : Traversal::Any, protected virtual Context
+ {
+ Any (Context& c, String const& scope_)
+ : Context (c), scope (scope_)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ String const& aname (eaname (a));
+
+ os << "// " << ename (a) << endl
+ << "//" << endl;
+
+ if (max (a) != 1)
+ {
+ // sequence
+ //
+ os << "for (" << scope << "::" << econst_iterator (a) << endl
+ << "b (i." << aname << " ().begin ()), " <<
+ "n (i." << aname << " ().end ());" << endl
+ << "b != n; ++b)"
+ << "{"
+ << "e.appendChild (" << endl
+ << "e.getOwnerDocument ()->importNode (" << endl
+ << "const_cast< " << xerces_ns <<
+ "::DOMElement* > (&(*b)), true));"
+ << "}";
+ }
+ else if (min (a) == 0)
+ {
+ // optional
+ //
+ os << "if (i." << aname << " ())"
+ << "{"
+ << "e.appendChild (" << endl
+ << "e.getOwnerDocument ()->importNode (" << endl
+ << "const_cast< " << xerces_ns << "::DOMElement* > (&(*i." <<
+ aname << " ())), true));"
+ << "}";
+ }
+ else
+ {
+ // one
+ //
+ os << "e.appendChild (" << endl
+ << "e.getOwnerDocument ()->importNode (" << endl
+ << "const_cast< " << xerces_ns << "::DOMElement* > (&(i." <<
+ aname << " ())), true));"
+ << endl;
+ }
+ }
+
+ private:
+ String scope;
+ };
+
+ struct Attribute : Traversal::Attribute, protected virtual Context
+ {
+ Attribute (Context& c, String const& scope_)
+ : Context (c), scope (scope_)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ String const& aname (eaname (a));
+ String ns (a.qualified () ? a.namespace_ ().name () : "");
+
+ os << "// " << comment (a.name ()) << endl
+ << "//" << endl;
+
+ Boolean def (a.default_ () && !is_qname (a.type ()));
+
+ if (a.optional () && !def)
+ {
+ os << "if (i." << aname << " ())"
+ << "{"
+ << xerces_ns << "::DOMAttr& a (" << endl
+ << "::xsd::cxx::xml::dom::create_attribute (" << endl
+ << L << strlit (a.name ()) << "," << endl
+ << (ns ? L + strlit (ns) + L",\n" : L"")
+ << "e));"
+ << endl;
+
+ switch (schema_type (a.type ()))
+ {
+ case st_other:
+ {
+ os << "a << *i." << aname << " ();";
+ break;
+ }
+ case st_double:
+ {
+ os << "a << " << as_double_type << "(*i." << aname << " ());";
+ break;
+ }
+ case st_decimal:
+ {
+ os << "a << " << as_decimal_type << "(*i." << aname << " ());";
+ break;
+ }
+ }
+
+ os << "}";
+ }
+ else
+ {
+ // Make sure we serialize required fixed attributes.
+ //
+ if (a.optional () &&
+ options.value<CLI::omit_default_attributes> ())
+ {
+ os << "if (i." << aname << " () != " << scope <<
+ "::" << edefault_value (a) << " ())";
+ }
+
+ os << "{"
+ << xerces_ns << "::DOMAttr& a (" << endl
+ << "::xsd::cxx::xml::dom::create_attribute (" << endl
+ << L << strlit (a.name ()) << "," << endl
+ << (ns ? L + strlit (ns) + L",\n" : L"")
+ << "e));"
+ << endl;
+
+ switch (schema_type (a.type ()))
+ {
+ case st_other:
+ {
+ os << "a << i." << aname << " ();";
+ break;
+ }
+ case st_double:
+ {
+ os << "a << " << as_double_type << "(i." << aname << " ());";
+ break;
+ }
+ case st_decimal:
+ {
+ os << "a << " << as_decimal_type << "(i." << aname << " ());";
+ break;
+ }
+ }
+
+ os << "}";
+ }
+ }
+
+ private:
+ String scope;
+ };
+
+ struct AnyAttribute : Traversal::AnyAttribute,
+ protected virtual Context
+ {
+ AnyAttribute (Context& c, String const& scope_)
+ : Context (c), scope (scope_)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ String const& aname (eaname (a));
+
+ os << "// " << ename (a) << endl
+ << "//" << endl;
+
+ os << "for (" << scope << "::" << econst_iterator (a) << endl
+ << "b (i." << aname << " ().begin ()), " <<
+ "n (i." << aname << " ().end ());" << endl
+ << "b != n; ++b)"
+ << "{"
+ << xerces_ns << "::DOMAttr* a (" << endl
+ << "static_cast< " << xerces_ns << "::DOMAttr* > (" << endl
+ << "e.getOwnerDocument ()->importNode (" << endl
+ << "const_cast< " << xerces_ns << "::DOMAttr* > (&(*b)), true)));"
+ << endl
+ << "if (a->getLocalName () == 0)" << endl
+ << "e.setAttributeNode (a);"
+ << "else" << endl
+ << "e.setAttributeNodeNS (a);"
+ << "}";
+ }
+
+ private:
+ String scope;
+ };
+
+ struct Complex : Traversal::Complex, protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c), base_ (c)
+ {
+ inherits_ >> base_;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String name (ename (c));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (c, name) && !name)
+ return;
+
+ // operator<< (xercesc::DOMElement)
+ //
+ os << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMElement& e, " <<
+ "const " << name << "& i)"
+ << "{";
+
+ if (c.inherits_p ())
+ {
+ os << "e << static_cast< const ";
+ inherits (c, inherits_);
+ os << "& > (i);"
+ << endl;
+ }
+ else
+ os << "e << static_cast< const " << any_type << "& > (i);"
+ << endl;
+
+ // Serialize anyAttribute content first so that is gets
+ // overriden by schema-defined attributes.
+ //
+ if (options.value<CLI::generate_wildcard> ())
+ {
+ AnyAttribute any_attribute (*this, name);
+ Traversal::Names names (any_attribute);
+
+ Complex::names (c, names);
+ }
+
+ {
+ Traversal::Names names;
+ Any any (*this, name);
+ Element element (*this, name);
+ Attribute attribute (*this, name);
+
+ names >> element;
+ names >> attribute;
+
+ if (options.value<CLI::generate_wildcard> ())
+ names >> any;
+
+ Complex::names (c, names);
+ }
+
+ os << "}";
+
+
+ Boolean simple (true);
+ {
+ IsSimpleType t (simple);
+ t.dispatch (c);
+ }
+
+ if (simple)
+ {
+ Boolean hb (c.inherits_p ());
+
+ // operator<< (xercesc::DOMAttr)
+ //
+ os << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMAttr&" <<
+ (hb ? " a" : "") << ", " <<
+ "const " << name << "&" << (hb ? " i" : "") << ")"
+ << "{";
+
+ if (hb)
+ {
+ os << "a << static_cast< const ";
+
+ inherits (c, inherits_);
+
+ os << "& > (i);";
+ }
+
+ os << "}";
+
+
+ // operator<< (list_stream)
+ //
+ os << "void" << endl
+ << "operator<< (" << list_stream_type << "&" <<
+ (hb ? " l" : "") << "," << endl
+ << "const " << name << "&" << (hb ? " i" : "") << ")"
+ << "{";
+
+ if (hb)
+ {
+ os << "l << static_cast< const ";
+
+ inherits (c, inherits_);
+
+ os << "& > (i);";
+ }
+
+ os << "}";
+ }
+
+ // Register with type factory map.
+ //
+ if (polymorphic && !c.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (c));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::type_serializer_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_type_serializer_init (" << endl
+ << L << strlit (c.name ()) << "," << endl
+ << L << strlit (xml_ns_name (c)) << ");"
+ << endl
+ << endl;
+ }
+ }
+
+ private:
+ Traversal::Inherits inherits_;
+ BaseTypeName base_;
+ };
+
+
+ // Generate substitution group map entry.
+ //
+ struct GlobalElement : Traversal::Element,
+ GlobalElementBase,
+ protected virtual Context
+ {
+ GlobalElement (Context& c)
+ : Context (c), GlobalElementBase (c), type_name_ (c)
+ {
+ belongs_ >> type_name_;
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (polymorphic && e.substitutes_p ())
+ {
+ Type& r (e.substitutes ().root ());
+
+ String const& name (ename (e));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::type_serializer_initializer< 0, " <<
+ char_type << ", ";
+
+ belongs (e, belongs_);
+
+ os << " >" << endl
+ << "_xsd_" << name << "_element_name_init (" << endl
+ << L << strlit (r.name ()) << "," << endl
+ << L << strlit (r.namespace_ ().name ()) << "," << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (e.namespace_ ().name ()) << ");"
+ << endl
+ << endl;
+ }
+ }
+
+ private:
+ Traversal::Belongs belongs_;
+ MemberTypeName type_name_;
+
+ };
+
+ struct ElementType: Traversal::Element,
+ GlobalElementBase,
+ protected virtual Context
+ {
+ ElementType (Context& c)
+ : Context (c),
+ GlobalElementBase (c),
+ element_map_ (c.options.value<CLI::generate_element_map> ())
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (doc_root_p (e))
+ {
+ String const& name (ename (e));
+
+ // operator<< (xercesc::DOMElement)
+ //
+ os << "void" << endl
+ << "operator<< (" << xerces_ns << "::DOMElement& e, " <<
+ "const " << name << "& i)"
+ << "{"
+ << "e << i." << eaname (e) << " ();"
+ << "}";
+
+ // Element map registration.
+ //
+ if (element_map_)
+ {
+ SemanticGraph::Context& ec (e.context ());
+ String const& aname (ec.get<String> ("element-name"));
+ String const& ans (ec.get<String> ("element-ns"));
+
+ os << "static " << endl
+ << "const ::xsd::cxx::tree::serializer_init< " <<
+ name << ", " << char_type << ", " << any_type << " >" << endl
+ << "_xsd_" << name << "_serializer_init (" <<
+ name << "::" << aname << " (), " <<
+ name << "::" << ans << " ());"
+ << endl;
+ }
+ }
+ }
+
+ private:
+ Boolean element_map_;
+ };
+
+ struct ElementFunction: Traversal::Element,
+ GlobalElementBase,
+ protected virtual Context
+ {
+ ElementFunction (Context& c)
+ : Context (c), GlobalElementBase (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (!doc_root_p (e))
+ return;
+
+ String const& name (eserializer (e));
+ String ns (e.namespace_ ().name ());
+ String const& error_handler (error_handler_type);
+ String const& namespace_infomap (namespace_infomap_type);
+
+ SemanticGraph::Type& type (e.type ());
+
+ // Note that I am using fq-name in function calls because g++ gets
+ // confused if the name is 'type'. (see tests/schema/anonymous)
+ //
+
+ Boolean fund (false);
+ {
+ IsFundamentalType t (fund);
+ t.dispatch (type);
+ }
+
+ // Check if we need to handle xsi:type and substitution groups.
+ // If this element's type is anonymous or mapped to a fundamental
+ // C++ type then we don't need to do anything.
+ //
+ Boolean poly (!fund && polymorphic &&
+ !type.context ().count ("anonymous"));
+
+ // To std::ostream.
+ //
+ os << "void" << endl
+ << name << " (::std::ostream& o," << endl
+ << "const " << type_name (e) << "& s," << endl
+ << "const " << namespace_infomap << "& m," << endl
+ << "const " << string_type << "& e," << endl
+ << flags_type << " f)"
+ << "{"
+ << "::xsd::cxx::xml::auto_initializer i (" << endl
+ << "(f & " << flags_type << "::dont_initialize) == 0);"
+ << endl
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > d (" << endl
+ << fq_name (e, "serializer") << " (s, m, f));"
+ << endl
+ << "::xsd::cxx::tree::error_handler< " << char_type << " > h;"
+ << endl
+ << "::xsd::cxx::xml::dom::ostream_format_target t (o);"
+ << "if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f))"
+ << "{"
+ << "h.throw_if_failed< ::xsd::cxx::tree::serialization< " <<
+ char_type << " > > ();"
+ << "}"
+ << "}";
+
+ os << "void" << endl
+ << name << " (::std::ostream& o," << endl
+ << "const " << type_name (e) << "& s," << endl
+ << error_handler << "& h," << endl
+ << "const " << namespace_infomap << "& m," << endl
+ << "const " << string_type << "& e," << endl
+ << flags_type << " f)"
+ << "{"
+ << "::xsd::cxx::xml::auto_initializer i (" << endl
+ << "(f & " << flags_type << "::dont_initialize) == 0);"
+ << endl
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > d (" << endl
+ << fq_name (e, "serializer") << " (s, m, f));"
+ << "::xsd::cxx::xml::dom::ostream_format_target t (o);"
+ << "if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f))"
+ << "{"
+ << "throw ::xsd::cxx::tree::serialization< " <<
+ char_type << " > ();"
+ << "}"
+ << "}";
+
+ os << "void" << endl
+ << name << " (::std::ostream& o," << endl
+ << "const " << type_name (e) << "& s," << endl
+ << xerces_ns << "::DOMErrorHandler& h," << endl
+ << "const " << namespace_infomap << "& m," << endl
+ << "const " << string_type << "& e," << endl
+ << flags_type << " f)"
+ << "{"
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > d (" << endl
+ << fq_name (e, "serializer") << " (s, m, f));"
+ << "::xsd::cxx::xml::dom::ostream_format_target t (o);"
+ << "if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f))"
+ << "{"
+ << "throw ::xsd::cxx::tree::serialization< " <<
+ char_type << " > ();"
+ << "}"
+ << "}";
+
+ // To XMLFormatTarget.
+ //
+ os << "void" << endl
+ << name << " (" << xerces_ns << "::XMLFormatTarget& t," << endl
+ << "const " << type_name (e) << "& s," << endl
+ << "const " << namespace_infomap << "& m," << endl
+ << "const " << string_type << "& e," << endl
+ << flags_type << " f)"
+ << "{"
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > d (" << endl
+ << fq_name (e, "serializer") << " (s, m, f));"
+ << endl
+ << "::xsd::cxx::tree::error_handler< " << char_type << " > h;"
+ << endl
+ << "if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f))"
+ << "{"
+ << "h.throw_if_failed< ::xsd::cxx::tree::serialization< " <<
+ char_type << " > > ();"
+ << "}"
+ << "}";
+
+ os << "void" << endl
+ << name << " (" << xerces_ns << "::XMLFormatTarget& t," << endl
+ << "const " << type_name (e) << "& s," << endl
+ << error_handler << "& h," << endl
+ << "const " << namespace_infomap << "& m," << endl
+ << "const " << string_type << "& e," << endl
+ << flags_type << " f)"
+ << "{"
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > d (" << endl
+ << fq_name (e, "serializer") << " (s, m, f));"
+ << "if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f))"
+ << "{"
+ << "throw ::xsd::cxx::tree::serialization< " <<
+ char_type << " > ();"
+ << "}"
+ << "}";
+
+ os << "void" << endl
+ << name << " (" << xerces_ns << "::XMLFormatTarget& t," << endl
+ << "const " << type_name (e) << "& s," << endl
+ << xerces_ns << "::DOMErrorHandler& h," << endl
+ << "const " << namespace_infomap << "& m," << endl
+ << "const " << string_type << "& e," << endl
+ << flags_type << " f)"
+ << "{"
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > d (" << endl
+ << fq_name (e, "serializer") << " (s, m, f));"
+ << "if (!::xsd::cxx::xml::dom::serialize (t, *d, e, h, f))"
+ << "{"
+ << "throw ::xsd::cxx::tree::serialization< " <<
+ char_type << " > ();"
+ << "}"
+ << "}";
+
+ // To an existing DOM instance.
+ //
+ os << "void" << endl
+ << name << " (" << xerces_ns << "::DOMDocument& d," << endl
+ << "const " << type_name (e) << "& s," << endl
+ << flags_type << ")"
+ << "{"
+ << xerces_ns << "::DOMElement& e (*d.getDocumentElement ());"
+ << "const " << qname_type << " n (" << endl
+ << "::xsd::cxx::xml::dom::name< " << char_type << " > (e));"
+ << endl;
+
+ if (poly)
+ {
+ os << "if (typeid (" << type_name (e) << ") == typeid (s))"
+ << "{";
+ }
+
+ os << "if (n.name () == " << L << strlit (e.name ()) << " &&" << endl
+ << "n.namespace_ () == " << L << strlit (ns) << ")"
+ << "{";
+
+ switch (schema_type (type))
+ {
+ case st_other:
+ {
+ os << "e << s;";
+ break;
+ }
+ case st_double:
+ {
+ os << "e << " << as_double_type << "(s);";
+ break;
+ }
+ case st_decimal:
+ {
+ os << "e << " << as_decimal_type << "(s);";
+ break;
+ }
+ }
+
+ os << "}"
+ << "else"
+ << "{"
+ << "throw ::xsd::cxx::tree::unexpected_element < " <<
+ char_type << " > (" << endl
+ << "n.name ()," << endl
+ << "n.namespace_ ()," << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (ns) << ");"
+ << "}";
+
+ if (poly)
+ {
+ // aCC cannot handle an inline call to
+ // type_serializer_map_instance.
+ //
+ os << "}"
+ << "else"
+ << "{"
+ << "::xsd::cxx::tree::type_serializer_map< " << char_type
+ << " >& tsm (" << endl
+ << "::xsd::cxx::tree::type_serializer_map_instance< 0, " <<
+ char_type << " > ());"
+ << endl
+ << "tsm.serialize (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (e.namespace_().name ()) << "," << endl
+ << "e, n, s);"
+ << "}";
+ }
+
+ os << "}";
+
+
+ // To a new DOM instance.
+ //
+ os << dom_auto_ptr << "< " << xerces_ns << "::DOMDocument >" << endl
+ << name << " (const " << type_name (e) << "& s," << endl
+ << "const " << namespace_infomap << "& m," << endl
+ << flags_type << " f)"
+ << "{";
+
+ if (poly)
+ {
+ // aCC cannot handle an inline call to
+ // type_serializer_map_instance as well as the direct
+ // auto_ptr assignment.
+ //
+ os << dom_auto_ptr << "< " << xerces_ns << "::DOMDocument > d;"
+ << endl
+ << "if (typeid (" << type_name (e) << ") == typeid (s))"
+ << "{"
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > r (" << endl
+ << "::xsd::cxx::xml::dom::serialize< " <<
+ char_type << " > (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (ns) << "," << endl
+ << "m, f));"
+ << "d = r;"
+ << "}"
+ << "else"
+ << "{"
+ << "::xsd::cxx::tree::type_serializer_map< " << char_type
+ << " >& tsm (" << endl
+ << "::xsd::cxx::tree::type_serializer_map_instance< 0, " <<
+ char_type << " > ());"
+ << endl
+ << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > r (" << endl
+ << "tsm.serialize (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (e.namespace_().name ()) << "," << endl
+ << "m, s, f));"
+ << "d = r;"
+ << "}";
+ }
+ else
+ {
+ os << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > d (" << endl
+ << "::xsd::cxx::xml::dom::serialize< " <<
+ char_type << " > (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (ns) << "," << endl
+ << "m, f));"
+ << endl;
+ }
+
+ os << fq_name (e, "serializer") << " (*d, s, f);"
+ << "return d;"
+ << "}";
+
+ }
+
+ private:
+ String
+ type_name (Type& e)
+ {
+ std::wostringstream o;
+
+ MemberTypeName type (*this, o);
+ type.dispatch (e.type ());
+
+ return o.str ();
+ }
+ };
+ }
+
+ Void
+ generate_serialization_source (Context& ctx,
+ UnsignedLong first,
+ UnsignedLong last)
+ {
+ Boolean elemen_type (ctx.options.value<CLI::generate_element_type> ());
+
+ if (!elemen_type)
+ ctx.os << "#include <ostream>" << endl
+ << "#include <xsd/cxx/tree/error-handler.hxx>" << endl;
+
+ ctx.os << "#include <xsd/cxx/xml/dom/serialization-source.hxx>" << endl
+ << endl;
+
+ if (ctx.polymorphic)
+ {
+ ctx.os << "#include <xsd/cxx/tree/type-serializer-map.hxx>" << endl
+ << endl;
+
+ Boolean import_maps (ctx.options.value<CLI::import_maps> ());
+ Boolean export_maps (ctx.options.value<CLI::export_maps> ());
+
+ if (import_maps || export_maps)
+ {
+ ctx.os << "#ifdef _MSC_VER" << endl
+ << endl
+ << "namespace xsd"
+ << "{"
+ << "namespace cxx"
+ << "{"
+ << "namespace tree"
+ << "{";
+
+ if (export_maps)
+ ctx.os << "template struct __declspec (dllexport) " <<
+ "type_serializer_plate< 0, " << ctx.char_type << " >;";
+
+ if (import_maps)
+ ctx.os << "template struct __declspec (dllimport) " <<
+ "type_serializer_plate< 0, " << ctx.char_type << " >;";
+
+ ctx.os << "}" // tree
+ << "}" // cxx
+ << "}" // xsd
+ << "#endif // _MSC_VER" << endl
+ << endl;
+ }
+
+ ctx.os << "namespace _xsd"
+ << "{"
+ << "static" << endl
+ << "const ::xsd::cxx::tree::type_serializer_plate< 0, " <<
+ ctx.char_type << " >" << endl
+ << "type_serializer_plate_init;"
+ << "}";
+ }
+
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names names_ns, names;
+
+ Namespace ns (ctx, first, last);
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+ GlobalElement element (ctx);
+ ElementType element_type (ctx);
+ ElementFunction element_function (ctx);
+
+
+ schema >> sources >> schema;
+ schema >> names_ns >> ns >> names;
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+ names >> element;
+
+ if (elemen_type)
+ names >> element_type;
+ else
+ names >> element_function;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/tree/serialization-source.hxx b/xsd/cxx/tree/serialization-source.hxx
new file mode 100644
index 0000000..3ea85b4
--- /dev/null
+++ b/xsd/cxx/tree/serialization-source.hxx
@@ -0,0 +1,24 @@
+// file : xsd/cxx/tree/serialization-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_SERIALIZATION_SOURCE_HXX
+#define CXX_TREE_SERIALIZATION_SOURCE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ Void
+ generate_serialization_source (Context&,
+ UnsignedLong first,
+ UnsignedLong last);
+ }
+}
+
+#endif // CXX_TREE_SERIALIZATION_SOURCE_HXX
diff --git a/xsd/cxx/tree/stream-extraction-source.cxx b/xsd/cxx/tree/stream-extraction-source.cxx
new file mode 100644
index 0000000..8b92040
--- /dev/null
+++ b/xsd/cxx/tree/stream-extraction-source.cxx
@@ -0,0 +1,754 @@
+// file : xsd/cxx/tree/stream-extraction-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/stream-extraction-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ typedef Containers::Vector<NarrowString> Streams;
+
+ struct List : Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String name (ename (l));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (l, name) && !name)
+ return;
+
+ SemanticGraph::Type& item_type (l.argumented ().type ());
+ String base (L"::xsd::cxx::tree::list< " +
+ item_type_name (item_type) + L", " + char_type);
+
+ if (item_type.is_a<SemanticGraph::Fundamental::Double> ())
+ base += L", ::xsd::cxx::tree::schema_type::double_";
+ else if (item_type.is_a<SemanticGraph::Fundamental::Decimal> ())
+ base += L", ::xsd::cxx::tree::schema_type::decimal";
+
+ base += L" >";
+
+ UnsignedLong n (0);
+ Streams const& st (options.value<CLI::generate_extraction> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ os << name << "::" << endl
+ << name << " (" << istream_type << "< " <<
+ i->c_str () << " >& s," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << any_simple_type << " (s, f, c)," << endl
+ << " " << base << " (s, f, c)"
+ << "{"
+ << "}";
+
+ // Register with type map.
+ //
+ if (polymorphic && !l.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (l));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::stream_extraction_initializer< " <<
+ "0, " << i->c_str () << ", " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_stream_extraction_init_" <<
+ n++ << " (" << endl
+ << L << strlit (l.name ()) << "," << endl
+ << L << strlit (xml_ns_name (l)) << ");"
+ << endl;
+ }
+ }
+ }
+
+ private:
+ String
+ item_type_name (SemanticGraph::Type& t)
+ {
+ std::wostringstream o;
+
+ MemberTypeName type (*this, o);
+ type.dispatch (t);
+
+ return o.str ();
+ }
+ };
+
+
+ struct Union : Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String name (ename (u));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (u, name) && !name)
+ return;
+
+ String const& base (xs_string_type);
+
+ UnsignedLong n (0);
+ Streams const& st (options.value<CLI::generate_extraction> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ os << name << "::" << endl
+ << name << " (" << istream_type << "< " <<
+ i->c_str () << " >& s," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << base << " (s, f, c)"
+ << "{"
+ << "}";
+
+ // Register with type map.
+ //
+ if (polymorphic && !u.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (u));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::stream_extraction_initializer< " <<
+ "0, " << i->c_str () << ", " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_stream_extraction_init_" <<
+ n++ << " (" << endl
+ << L << strlit (u.name ()) << "," << endl
+ << L << strlit (xml_ns_name (u)) << ");"
+ << endl;
+ }
+ }
+ }
+ };
+
+
+ struct Enumeration : Traversal::Enumeration, protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c), base_ (c)
+ {
+ inherits_base_ >> base_;
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String name (ename (e));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (e, name) && !name)
+ return;
+
+ Boolean string_based (false);
+ {
+ IsStringBasedType t (string_based);
+ t.dispatch (e);
+ }
+
+ UnsignedLong n (0);
+ Streams const& st (options.value<CLI::generate_extraction> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ os << name << "::" << endl
+ << name << " (" << istream_type << "< " <<
+ i->c_str () << " >& s," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": ";
+
+ inherits (e, inherits_base_);
+
+ os << " (s, f, c)"
+ << "{";
+
+ if (string_based)
+ os << "_xsd_" << name << "_convert ();";
+
+ os << "}";
+
+ // Register with type map.
+ //
+ if (polymorphic && !e.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (e));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::stream_extraction_initializer< " <<
+ "0, " << i->c_str () << ", " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_stream_extraction_init_" <<
+ n++ << " (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (xml_ns_name (e)) << ");"
+ << endl;
+ }
+ }
+ }
+
+ private:
+ Traversal::Inherits inherits_base_;
+ BaseTypeName base_;
+ };
+
+ struct CtorMember : Traversal::Member,
+ protected virtual Context
+ {
+ CtorMember (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Member& m)
+ {
+ if (skip (m))
+ return;
+
+ os << "," << endl
+ << " " << emember (m) << " (f, this)";
+ }
+ };
+
+ struct CtorAny : Traversal::Any,
+ Traversal::AnyAttribute,
+ protected virtual Context
+ {
+ CtorAny (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ String const& member (emember (a));
+ String const& dom_doc (
+ edom_document (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ())));
+
+ os << "," << endl
+ << " " << member << " (this->" << dom_doc << " ())";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute& a)
+ {
+ String const& member (emember (a));
+ String const& dom_doc (
+ edom_document (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ())));
+
+ os << "," << endl
+ << " " << member << " (this->" << dom_doc << " ())";
+ }
+ };
+
+ struct Element : Traversal::Element, protected virtual Context
+ {
+ Element (Context& c, String const& stream_)
+ : Context (c), stream (stream_)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (skip (e))
+ return;
+
+ String const& member (emember (e));
+
+ SemanticGraph::Type& t (e.type ());
+ String type (etype (e));
+
+ Boolean fund (false);
+ {
+ IsFundamentalType traverser (fund);
+ traverser.dispatch (t);
+ }
+
+ // Figure out if we need to generate polymorphic code. If this
+ // elemen's type is anonymous or mapped to a fundamental C++
+ // type then we don't need to do anything. Note that if the type
+ // is anonymous then it can't be derived from which makes it
+ // impossible to substitute or dynamically-type with xsi:type.
+ //
+ Boolean poly (!fund && polymorphic &&
+ !t.context ().count ("anonymous"));
+
+ if (max (e) != 1)
+ {
+ // sequence
+ //
+ String container (econtainer (e));
+
+ os << "{"
+ << "::std::size_t n;"
+ << "::xsd::cxx::tree::istream_common::as_size< " <<
+ "::std::size_t > as (n);"
+ << "s >> as;"
+ << "if (n > 0)"
+ << "{"
+ << container << "& c (this->" << member << ");"
+ << "c.reserve (n);"
+ << "while (n--)"
+ << "{";
+
+ if (poly)
+ {
+ os << "bool d;"
+ << "::std::auto_ptr< " << type << " > r;"
+ << "s >> d;"
+ << endl
+ << "if (!d)" << endl
+ << "r.reset (new " << type << " (s, f, this));"
+ << "else"
+ << "{"
+ << "::std::auto_ptr< ::xsd::cxx::tree::type > tmp (" << endl
+ << "::xsd::cxx::tree::stream_extraction_map_instance< 0, " <<
+ stream << ", " << char_type << " > ().extract (" << endl
+ << "s, f, this));"
+ << "r.reset (dynamic_cast< " << type << "* > (tmp.get ()));"
+ << "if (r.get ())" << endl
+ << "tmp.release ();"
+ << "else" << endl
+ << "throw ::xsd::cxx::tree::not_derived< " << char_type <<
+ " > ();"
+ << "}";
+ }
+ else if (fund)
+ {
+ os << type << " r;"
+ << "s >> r;";
+ }
+ else
+ {
+ os << "::std::auto_ptr< " << type << " > r (new " << type <<
+ " (s, f, this));";
+ }
+
+ os << "c.push_back (r);"
+ << "}" // while
+ << "}" // if
+ << "}";
+ }
+ else if (min (e) == 0)
+ {
+ // optional
+ //
+ os << "{"
+ << "bool p;"
+ << "s >> p;"
+ << "if (p)"
+ << "{";
+
+ if (poly)
+ {
+ os << "bool d;"
+ << "::std::auto_ptr< " << type << " > r;"
+ << "s >> d;"
+ << endl
+ << "if (!d)" << endl
+ << "r.reset (new " << type << " (s, f, this));"
+ << "else"
+ << "{"
+ << "::std::auto_ptr< ::xsd::cxx::tree::type > tmp (" << endl
+ << "::xsd::cxx::tree::stream_extraction_map_instance< 0, " <<
+ stream << ", " << char_type << " > ().extract (" << endl
+ << "s, f, this));"
+ << "r.reset (dynamic_cast< " << type << "* > (tmp.get ()));"
+ << "if (r.get ())" << endl
+ << "tmp.release ();"
+ << "else" << endl
+ << "throw ::xsd::cxx::tree::not_derived< " << char_type <<
+ " > ();"
+ << "}";
+ }
+ else if (fund)
+ {
+ os << type << " r;"
+ << "s >> r;";
+ }
+ else
+ {
+ os << "::std::auto_ptr< " << type << " > r (new " << type <<
+ " (s, f, this));";
+ }
+
+ os << "this->" << member << ".set (r);"
+ << "}" // if (p)
+ << "}";
+ }
+ else
+ {
+ // one
+ //
+ os << "{";
+
+ if (poly)
+ {
+ os << "bool d;"
+ << "::std::auto_ptr< " << type << " > r;"
+ << "s >> d;"
+ << endl
+ << "if (!d)" << endl
+ << "r.reset (new " << type << " (s, f, this));"
+ << "else"
+ << "{"
+ << "::std::auto_ptr< ::xsd::cxx::tree::type > tmp (" << endl
+ << "::xsd::cxx::tree::stream_extraction_map_instance< 0, " <<
+ stream << ", " << char_type << " > ().extract (" << endl
+ << "s, f, this));"
+ << "r.reset (dynamic_cast< " << type << "* > (tmp.get ()));"
+ << "if (r.get ())" << endl
+ << "tmp.release ();"
+ << "else" << endl
+ << "throw ::xsd::cxx::tree::not_derived< " << char_type <<
+ " > ();"
+ << "}";
+ }
+ else if (fund)
+ {
+ os << type << " r;"
+ << "s >> r;";
+ }
+ else
+ {
+ os << "::std::auto_ptr< " << type << " > r (new " << type <<
+ " (s, f, this));";
+ }
+
+ os << "this->" << member << ".set (r);"
+ << "}";
+ }
+ }
+
+ private:
+ String stream;
+ };
+
+ struct Attribute : Traversal::Attribute, protected virtual Context
+ {
+ Attribute (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ String const& member (emember (a));
+ String type (etype (a));
+
+ Boolean fund (false);
+ {
+ IsFundamentalType traverser (fund);
+ traverser.dispatch (a.type ());
+ }
+
+ Boolean def (a.default_ () && !is_qname (a.type ()));
+
+ if (a.optional () && !def)
+ {
+ os << "{"
+ << "bool p;"
+ << "s >> p;"
+ << "if (p)"
+ << "{";
+
+ if (fund)
+ {
+ os << type << " r;"
+ << "s >> r;"
+ << "this->" << member << ".set (r);";
+ }
+ else
+ {
+ os << "::std::auto_ptr< " << type << " > r (new " << type <<
+ " (s, f, this));"
+ << "this->" << member << ".set (r);";
+ }
+
+ os << "}" // if (p)
+ << "}";
+ }
+ else
+ {
+ os << "{";
+
+ if (fund)
+ {
+ os << type << " r;"
+ << "s >> r;"
+ << "this->" << member << ".set (r);";
+ }
+ else
+ {
+ os << "::std::auto_ptr< " << type << " > r (new " << type <<
+ " (s, f, this));"
+ << "this->" << member << ".set (r);";
+ }
+
+ os << "}";
+ }
+ }
+ };
+
+ struct Complex : Traversal::Complex, protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c), base_ (c), ctor_any_ (c), ctor_member_ (c)
+ {
+ inherits_ >> base_;
+ names_ctor_member_ >> ctor_member_;
+
+ if (options.value<CLI::generate_wildcard> ())
+ names_ctor_member_ >> ctor_any_;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String name (ename (c));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (c, name) && !name)
+ return;
+
+ Boolean has_members (has<Traversal::Member> (c));
+
+ Boolean facets (false);
+ if (c.inherits_p ())
+ {
+ // See if we have any facets that we need to handle.
+ //
+ using SemanticGraph::Restricts;
+ using SemanticGraph::Fundamental::Decimal;
+
+ if (Restricts* r = dynamic_cast<Restricts*> (&c.inherits ()))
+ {
+ if (!r->facet_empty () &&
+ (r->facet_find ("fractionDigits") != r->facet_end () ||
+ r->facet_find ("totalDigits") != r->facet_end ()) &&
+ ultimate_base (c).is_a<Decimal> ())
+ facets = true;
+ }
+ }
+
+ UnsignedLong n (0);
+ Streams const& st (options.value<CLI::generate_extraction> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+
+ os << name << "::" << endl
+ << name << " (" << istream_type << "< " <<
+ i->c_str () << " >& s," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": ";
+
+ if (c.inherits_p ())
+ inherits (c, inherits_);
+ else
+ os << any_type;
+
+ os << " (s, f, c)";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, names_ctor_member_);
+
+ os << "{";
+
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);"
+ << endl;
+
+ if (has_members)
+ os << "this->" << unclash (name, "parse") << " (s, f);";
+
+ os << "}";
+
+ // Parse
+ //
+ if (has_members)
+ {
+ os << "void " << name << "::" << endl
+ << unclash (name, "parse") << " (" <<
+ istream_type << "< " << i->c_str () << " >& s," << endl
+ << flags_type << " f)"
+ << "{";
+ {
+ Element element (*this, *i);
+ Attribute attribute (*this);
+ Traversal::Names names_;
+
+ names_ >> element;
+ names_ >> attribute;
+
+ names (c, names_);
+ }
+
+ os << "}";
+ }
+
+
+ // Register with type map.
+ //
+ if (polymorphic && !c.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (c));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::stream_extraction_initializer< " <<
+ "0, " << i->c_str () << ", " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_stream_extraction_init_" <<
+ n++ << " (" << endl
+ << L << strlit (c.name ()) << "," << endl
+ << L << strlit (xml_ns_name (c)) << ");"
+ << endl;
+ }
+ }
+ }
+
+ private:
+ Traversal::Inherits inherits_;
+ BaseTypeName base_;
+
+ CtorAny ctor_any_;
+ CtorMember ctor_member_;
+
+ Traversal::Names names_ctor_member_;
+ };
+ }
+
+ Void
+ generate_stream_extraction_source (Context& ctx)
+ {
+ if (ctx.polymorphic)
+ {
+ Streams const& st (ctx.options.value<CLI::generate_extraction> ());
+
+ ctx.os << "#include <xsd/cxx/tree/stream-extraction-map.hxx>" << endl
+ << endl;
+
+ Boolean import_maps (ctx.options.value<CLI::import_maps> ());
+ Boolean export_maps (ctx.options.value<CLI::export_maps> ());
+
+ if (import_maps || export_maps)
+ {
+ ctx.os << "#ifdef _MSC_VER" << endl
+ << endl
+ << "namespace xsd"
+ << "{"
+ << "namespace cxx"
+ << "{"
+ << "namespace tree"
+ << "{";
+
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ String stream (*i);
+
+ if (export_maps)
+ ctx.os << "template struct __declspec (dllexport) " <<
+ "stream_extraction_plate< 0, " << stream << ", " <<
+ ctx.char_type << " >;";
+
+ if (import_maps)
+ ctx.os << "template struct __declspec (dllimport) " <<
+ "stream_extraction_plate< 0, " << stream << ", " <<
+ ctx.char_type << " >;";
+ }
+
+ ctx.os << "}" // tree
+ << "}" // cxx
+ << "}" // xsd
+ << "#endif // _MSC_VER" << endl
+ << endl;
+ }
+
+ ctx.os << "namespace _xsd"
+ << "{";
+
+ UnsignedLong n (0);
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ String stream (*i);
+
+ ctx.os << "static" << endl
+ << "const ::xsd::cxx::tree::stream_extraction_plate< 0, " <<
+ stream << ", " << ctx.char_type << " >" << endl
+ << "stream_extraction_plate_init_" << n++ << ";";
+ }
+
+ ctx.os << "}";
+ }
+
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names names_ns, names;
+
+ Namespace ns (ctx);
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+
+ schema >> sources >> schema;
+ schema >> names_ns >> ns >> names;
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/tree/stream-extraction-source.hxx b/xsd/cxx/tree/stream-extraction-source.hxx
new file mode 100644
index 0000000..c6524f7
--- /dev/null
+++ b/xsd/cxx/tree/stream-extraction-source.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/tree/stream-extraction-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_EXTRACTION_SOURCE_HXX
+#define CXX_TREE_EXTRACTION_SOURCE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ Void
+ generate_stream_extraction_source (Context&);
+ }
+}
+
+#endif // CXX_TREE_EXTRACTION_SOURCE_HXX
diff --git a/xsd/cxx/tree/stream-header.cxx b/xsd/cxx/tree/stream-header.cxx
new file mode 100644
index 0000000..64964a3
--- /dev/null
+++ b/xsd/cxx/tree/stream-header.cxx
@@ -0,0 +1,183 @@
+// file : xsd/cxx/tree/stream-header.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/stream-header.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ struct List: Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String name (ename (l));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (l, name) && !name)
+ return;
+
+ os << inst_exp
+ << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "&, const " <<
+ name << "&);"
+ << endl;
+ }
+ };
+
+
+ struct Union: Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String name (ename (u));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (u, name) && !name)
+ return;
+
+ os << inst_exp
+ << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "&, const " <<
+ name << "&);"
+ << endl;
+ }
+ };
+
+
+ struct Enumeration: Traversal::Enumeration, protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String name (ename (e));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (e, name) && !name)
+ return;
+
+ Boolean string_based (false);
+ {
+ IsStringBasedType t (string_based);
+ t.dispatch (e);
+ }
+
+ Boolean enum_based (false);
+ if (string_based)
+ {
+ SemanticGraph::Enumeration* be (0);
+ IsEnumBasedType t (be);
+ t.dispatch (e);
+
+ enum_based = (be != 0);
+ }
+
+ // If we are based on an enum then the value type is just an
+ // alias and we don't need to generate this operator again.
+ //
+ if (string_based && !enum_based)
+ {
+ os << inst_exp
+ << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "&, " <<
+ name << "::" << evalue (e) << ");"
+ << endl;
+ }
+
+ os << inst_exp
+ << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "&, const " <<
+ name << "&);"
+ << endl;
+ }
+ };
+
+ struct Complex : Traversal::Complex, protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String name (ename (c));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (c, name) && !name)
+ return;
+
+ os << inst_exp
+ << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "&, const " <<
+ name << "&);"
+ << endl;
+ }
+ };
+ }
+
+ Void
+ generate_stream_header (Context& ctx)
+ {
+ String c (ctx.char_type);
+
+ ctx.os << "#include <iosfwd>" << endl
+ << endl;
+
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names names_ns, names;
+
+ Namespace ns (ctx);
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+
+ schema >> sources >> schema;
+ schema >> names_ns >> ns >> names;
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/tree/stream-header.hxx b/xsd/cxx/tree/stream-header.hxx
new file mode 100644
index 0000000..c34c763
--- /dev/null
+++ b/xsd/cxx/tree/stream-header.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/tree/stream-header.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_STREAM_HEADER_HXX
+#define CXX_TREE_STREAM_HEADER_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ Void
+ generate_stream_header (Context&);
+ }
+}
+
+#endif // CXX_TREE_STREAM_HEADER_HXX
diff --git a/xsd/cxx/tree/stream-insertion-header.cxx b/xsd/cxx/tree/stream-insertion-header.cxx
new file mode 100644
index 0000000..32cb402
--- /dev/null
+++ b/xsd/cxx/tree/stream-insertion-header.cxx
@@ -0,0 +1,178 @@
+// file : xsd/cxx/tree/stream-insertion-header.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/stream-insertion-header.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ typedef Containers::Vector<NarrowString> Streams;
+
+ struct List: Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String name (ename (l));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (l, name) && !name)
+ return;
+
+ Streams const& st (options.value<CLI::generate_insertion> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ String stream_type (ostream_type + L"< " + String (*i) + L" >");
+
+ os << inst_exp
+ << stream_type << "&" << endl
+ << "operator<< (" << stream_type << "&," << endl
+ << "const " << name << "&);"
+ << endl;
+ }
+ }
+ };
+
+
+ struct Union: Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String name (ename (u));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (u, name) && !name)
+ return;
+
+ Streams const& st (options.value<CLI::generate_insertion> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ String stream_type (ostream_type + L"< " + String (*i) + L" >");
+
+ os << inst_exp
+ << stream_type << "&" << endl
+ << "operator<< (" << stream_type << "&," << endl
+ << "const " << name << "&);"
+ << endl;
+ }
+ }
+ };
+
+
+ struct Enumeration: Traversal::Enumeration, protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String name (ename (e));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (e, name) && !name)
+ return;
+
+ Streams const& st (options.value<CLI::generate_insertion> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ String stream_type (ostream_type + L"< " + String (*i) + L" >");
+
+ os << inst_exp
+ << stream_type << "&" << endl
+ << "operator<< (" << stream_type << "&," << endl
+ << "const " << name << "&);"
+ << endl;
+ }
+ }
+ };
+
+ struct Complex : Traversal::Complex, protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String name (ename (c));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (c, name) && !name)
+ return;
+
+ Streams const& st (options.value<CLI::generate_insertion> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ String stream_type (ostream_type + L"< " + String (*i) + L" >");
+
+ os << inst_exp
+ << stream_type << "&" << endl
+ << "operator<< (" << stream_type << "&," << endl
+ << "const " << name << "&);"
+ << endl;
+ }
+ }
+ };
+ }
+
+ Void
+ generate_stream_insertion_header (Context& ctx)
+ {
+ String c (ctx.char_type);
+
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names names_ns, names;
+
+ Namespace ns (ctx);
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+
+ schema >> sources >> schema;
+ schema >> names_ns >> ns >> names;
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/tree/stream-insertion-header.hxx b/xsd/cxx/tree/stream-insertion-header.hxx
new file mode 100644
index 0000000..95bfc2c
--- /dev/null
+++ b/xsd/cxx/tree/stream-insertion-header.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/tree/stream-insertion-header.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_STREAM_INSERTION_HEADER_HXX
+#define CXX_TREE_STREAM_INSERTION_HEADER_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ Void
+ generate_stream_insertion_header (Context&);
+ }
+}
+
+#endif // CXX_TREE_STREAM_INSERTION_HEADER_HXX
diff --git a/xsd/cxx/tree/stream-insertion-source.cxx b/xsd/cxx/tree/stream-insertion-source.cxx
new file mode 100644
index 0000000..87c7caa
--- /dev/null
+++ b/xsd/cxx/tree/stream-insertion-source.cxx
@@ -0,0 +1,532 @@
+// file : xsd/cxx/tree/stream-insertion-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/stream-insertion-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ typedef Containers::Vector<NarrowString> Streams;
+
+ struct List : Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String name (ename (l));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (l, name) && !name)
+ return;
+
+ SemanticGraph::Type& item_type (l.argumented ().type ());
+ String base (L"::xsd::cxx::tree::list< " +
+ item_type_name (item_type) + L", " + char_type);
+
+ if (item_type.is_a<SemanticGraph::Fundamental::Double> ())
+ base += L", ::xsd::cxx::tree::schema_type::double_";
+ else if (item_type.is_a<SemanticGraph::Fundamental::Decimal> ())
+ base += L", ::xsd::cxx::tree::schema_type::decimal";
+
+ base += L" >";
+
+ UnsignedLong n (0);
+ Streams const& st (options.value<CLI::generate_insertion> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ String stream_type ("::xsd::cxx::tree::ostream< " + *i + " >");
+
+ os << stream_type << "&" << endl
+ << "operator<< (" << stream_type << "& s," << endl
+ << "const " << name << "& x)"
+ << "{"
+ << "return s << static_cast< const " << base << "& > (x);"
+ << "}";
+
+ // Register with type map.
+ //
+ if (polymorphic && !l.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (l));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::stream_insertion_initializer< " <<
+ "0, " << i->c_str () << ", " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_stream_insertion_init_" <<
+ n++ << " (" << endl
+ << L << strlit (l.name ()) << "," << endl
+ << L << strlit (xml_ns_name (l)) << ");"
+ << endl;
+ }
+ }
+ }
+
+ private:
+ String
+ item_type_name (SemanticGraph::Type& t)
+ {
+ std::wostringstream o;
+
+ MemberTypeName type (*this, o);
+ type.dispatch (t);
+
+ return o.str ();
+ }
+ };
+
+
+ struct Union : Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String name (ename (u));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (u, name) && !name)
+ return;
+
+ String const& base (xs_string_type);
+
+ UnsignedLong n (0);
+ Streams const& st (options.value<CLI::generate_insertion> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ String stream_type ("::xsd::cxx::tree::ostream< " + *i + " >");
+
+ os << stream_type << "&" << endl
+ << "operator<< (" << stream_type << "& s," << endl
+ << "const " << name << "& x)"
+ << "{"
+ << "return s << static_cast< const " << base << "& > (x);"
+ << "}";
+
+ // Register with type map.
+ //
+ if (polymorphic && !u.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (u));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::stream_insertion_initializer< " <<
+ "0, " << i->c_str () << ", " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_stream_insertion_init_" <<
+ n++ << " (" << endl
+ << L << strlit (u.name ()) << "," << endl
+ << L << strlit (xml_ns_name (u)) << ");"
+ << endl;
+ }
+ }
+ }
+ };
+
+
+ struct Enumeration : Traversal::Enumeration, protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c), base_ (c)
+ {
+ inherits_base_ >> base_;
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String name (ename (e));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (e, name) && !name)
+ return;
+
+ UnsignedLong n (0);
+ Streams const& st (options.value<CLI::generate_insertion> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ String stream_type ("::xsd::cxx::tree::ostream< " + *i + " >");
+
+ os << stream_type << "&" << endl
+ << "operator<< (" << stream_type << "& s," << endl
+ << "const " << name << "& x)"
+ << "{"
+ << "return s << static_cast< const ";
+
+ inherits (e, inherits_base_);
+
+ os << "& > (x);"
+ << "}";
+
+ // Register with type map.
+ //
+ if (polymorphic && !e.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (e));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::stream_insertion_initializer< " <<
+ "0, " << i->c_str () << ", " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_stream_insertion_init_" <<
+ n++ << " (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (xml_ns_name (e)) << ");"
+ << endl;
+ }
+ }
+ }
+
+ private:
+ Traversal::Inherits inherits_base_;
+ BaseTypeName base_;
+ };
+
+ struct Element : Traversal::Element, protected virtual Context
+ {
+ Element (Context& c, String const& scope_, String const& stream_)
+ : Context (c), scope (scope_), stream (stream_)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (skip (e)) return;
+
+ String const& aname (eaname (e));
+ SemanticGraph::Type& t (e.type ());
+ String type (scope + L"::" + etype (e));
+
+ // Figure out if we need to generate polymorphic code. If this
+ // elemen's type is anonymous or mapped to a fundamental C++
+ // type then we don't need to do anything. Note that if the type
+ // is anonymous then it can't be derived from which makes it
+ // impossible to substitute or dynamically-type with xsi:type.
+ //
+ Boolean poly (polymorphic && !t.context ().count ("anonymous"));
+
+ if (poly)
+ {
+ Boolean fund (false);
+ IsFundamentalType traverser (fund);
+ traverser.dispatch (t);
+ poly = !fund;
+ }
+
+ if (max (e) != 1)
+ {
+ // sequence
+ //
+ os << "{"
+ << "const " << scope << "::" << econtainer (e) << "& c (" <<
+ "x." << aname << " ());"
+ << "s << ::xsd::cxx::tree::ostream_common::as_size< " <<
+ "::std::size_t > (c.size ());";
+
+ os << "for (" << scope << "::" << econst_iterator (e) << endl
+ << "i (c.begin ()), e (c.end ());" << endl
+ << "i != e; ++i)"
+ << "{";
+
+ if (poly)
+ {
+ os << "bool d (typeid (" << type << ") != typeid (*i));"
+ << "s << d;"
+ << "if (!d)" << endl
+ << "s << *i;"
+ << "else" << endl
+ << "::xsd::cxx::tree::stream_insertion_map_instance< 0, " <<
+ stream << ", " << char_type << " > ().insert (s, *i);";
+ }
+ else
+ os << "s << *i;";
+
+ os << "}" // for
+ << "}";
+ }
+ else if (min (e) == 0)
+ {
+ // optional
+ //
+ os << "{"
+ << "bool p (x." << aname << " ());"
+ << "s << p;"
+ << "if (p)";
+
+ if (poly)
+ {
+ os << "{"
+ << "const " << type << "& i (*x." << aname << " ());"
+ << "bool d (typeid (" << type << ") != typeid (i));"
+ << "s << d;"
+ << "if (!d)" << endl
+ << "s << i;"
+ << "else" << endl
+ << "::xsd::cxx::tree::stream_insertion_map_instance< 0, " <<
+ stream << ", " << char_type << " > ().insert (s, i);"
+ << "}";
+ }
+ else
+ os << endl
+ << "s << *x." << aname << " ();";
+
+ os << "}";
+ }
+ else
+ {
+ // one
+ //
+ if (poly)
+ {
+ os << "{"
+ << "const " << type << "& i (x." << aname << " ());"
+ << "bool d (typeid (" << type << ") != typeid (i));"
+ << "s << d;"
+ << "if (!d)" << endl
+ << "s << i;"
+ << "else" << endl
+ << "::xsd::cxx::tree::stream_insertion_map_instance< 0, " <<
+ stream << ", " << char_type << " > ().insert (s, i);"
+ << "}";
+ }
+ else
+ os << "s << x." << aname << " ();";
+ }
+ }
+
+ private:
+ String scope;
+ String stream;
+ };
+
+ struct Attribute : Traversal::Attribute, protected virtual Context
+ {
+ Attribute (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ String const& aname (eaname (a));
+
+ Boolean def (a.default_ () && !is_qname (a.type ()));
+
+ if (a.optional () && !def)
+ {
+ os << "{"
+ << "bool p (x." << aname << " ());"
+ << "s << p;"
+ << "if (p)" << endl
+ << "s << *x." << aname << " ();"
+ << "}";
+ }
+ else
+ {
+ os << "s << x." << aname << " ();";
+ }
+ }
+ };
+
+
+ struct Complex : Traversal::Complex, protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c), base_ (c)
+ {
+ inherits_ >> base_;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String name (ename (c));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (c, name) && !name)
+ return;
+
+ Boolean has_body (has<Traversal::Member> (c) || c.inherits_p ());
+
+ UnsignedLong n (0);
+ Streams const& st (options.value<CLI::generate_insertion> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ String stream_type ("::xsd::cxx::tree::ostream< " + *i + " >");
+
+ os << stream_type << "&" << endl
+ << "operator<< (" << stream_type << "& s," << endl
+ << "const " << name << "&" << (has_body ? " x" : "") << ")"
+ << "{";
+
+ if (c.inherits_p ())
+ {
+ os << "s << static_cast< const ";
+
+ inherits (c, inherits_);
+
+ os << "& > (x);";
+ }
+
+ {
+ Traversal::Names names_member;
+ Element element (*this, name, *i);
+ Attribute attribute (*this);
+
+ names_member >> element;
+ names_member >> attribute;
+
+ names (c, names_member);
+ }
+
+ os << "return s;"
+ << "}";
+
+
+ // Register with type map.
+ //
+ if (polymorphic && !c.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (c));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::stream_insertion_initializer< " <<
+ "0, " << i->c_str () << ", " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_stream_insertion_init_" <<
+ n++ << " (" << endl
+ << L << strlit (c.name ()) << "," << endl
+ << L << strlit (xml_ns_name (c)) << ");"
+ << endl;
+ }
+ }
+ }
+
+ private:
+ Traversal::Inherits inherits_;
+ BaseTypeName base_;
+ };
+ }
+
+ Void
+ generate_stream_insertion_source (Context& ctx)
+ {
+ if (ctx.polymorphic)
+ {
+ Streams const& st (ctx.options.value<CLI::generate_insertion> ());
+
+ ctx.os << "#include <xsd/cxx/tree/stream-insertion-map.hxx>" << endl
+ << endl;
+
+ Boolean import_maps (ctx.options.value<CLI::import_maps> ());
+ Boolean export_maps (ctx.options.value<CLI::export_maps> ());
+
+ if (import_maps || export_maps)
+ {
+ ctx.os << "#ifdef _MSC_VER" << endl
+ << endl
+ << "namespace xsd"
+ << "{"
+ << "namespace cxx"
+ << "{"
+ << "namespace tree"
+ << "{";
+
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ String stream (*i);
+
+ if (export_maps)
+ ctx.os << "template struct __declspec (dllexport) " <<
+ "stream_insertion_plate< 0, " << stream << ", " <<
+ ctx.char_type << " >;";
+
+ if (import_maps)
+ ctx.os << "template struct __declspec (dllimport) " <<
+ "stream_insertion_plate< 0, " << stream << ", " <<
+ ctx.char_type << " >;";
+ }
+
+ ctx.os << "}" // tree
+ << "}" // cxx
+ << "}" // xsd
+ << "#endif // _MSC_VER" << endl
+ << endl;
+ }
+
+ ctx.os << "namespace _xsd"
+ << "{";
+
+ UnsignedLong n (0);
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ String stream (*i);
+
+ ctx.os << "static" << endl
+ << "const ::xsd::cxx::tree::stream_insertion_plate< 0, " <<
+ stream << ", " << ctx.char_type << " >" << endl
+ << "stream_insertion_plate_init_" << n++ << ";";
+ }
+
+ ctx.os << "}";
+ }
+
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names names_ns, names;
+
+ Namespace ns (ctx);
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+
+ schema >> sources >> schema;
+ schema >> names_ns >> ns >> names;
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/tree/stream-insertion-source.hxx b/xsd/cxx/tree/stream-insertion-source.hxx
new file mode 100644
index 0000000..d5d4256
--- /dev/null
+++ b/xsd/cxx/tree/stream-insertion-source.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/tree/stream-insertion-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_INSERTION_SOURCE_HXX
+#define CXX_TREE_INSERTION_SOURCE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ Void
+ generate_stream_insertion_source (Context&);
+ }
+}
+
+#endif // CXX_TREE_INSERTION_SOURCE_HXX
diff --git a/xsd/cxx/tree/stream-source.cxx b/xsd/cxx/tree/stream-source.cxx
new file mode 100644
index 0000000..e30a4ab
--- /dev/null
+++ b/xsd/cxx/tree/stream-source.cxx
@@ -0,0 +1,489 @@
+// file : xsd/cxx/tree/stream-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/stream-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ struct List : Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String name (ename (l));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (l, name) && !name)
+ return;
+
+ SemanticGraph::Type& item_type (l.argumented ().type ());
+ String base (L"::xsd::cxx::tree::list< " +
+ item_type_name (item_type) + L", " + char_type);
+
+ if (item_type.is_a<SemanticGraph::Fundamental::Double> ())
+ base += L", ::xsd::cxx::tree::schema_type::double_";
+ else if (item_type.is_a<SemanticGraph::Fundamental::Decimal> ())
+ base += L", ::xsd::cxx::tree::schema_type::decimal";
+
+ base += L" >";
+
+ os << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "& o, " <<
+ "const " << name << "& i)"
+ << "{"
+ << "return o << static_cast< const " << base << "& > (i);"
+ << "}";
+
+ // Register with ostream map.
+ //
+ if (polymorphic && !l.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (l));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::std_ostream_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_std_ostream_init;"
+ << endl;
+ }
+ }
+
+ private:
+ String
+ item_type_name (SemanticGraph::Type& t)
+ {
+ std::wostringstream o;
+
+ MemberTypeName type (*this, o);
+ type.dispatch (t);
+
+ return o.str ();
+ }
+ };
+
+
+ struct Union : Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String name (ename (u));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (u, name) && !name)
+ return;
+
+ os << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "& o, " <<
+ "const " << name << "& i)"
+ << "{"
+ << "return o << static_cast< const " << xs_string_type << "& > (i);"
+ << "}";
+
+ // Register with ostream map.
+ //
+ if (polymorphic && !u.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (u));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::std_ostream_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_std_ostream_init;"
+ << endl;
+ }
+ }
+ };
+
+
+ struct Enumeration : Traversal::Enumeration, protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c), base_ (c)
+ {
+ inherits_base_ >> base_;
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String name (ename (e));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (e, name) && !name)
+ return;
+
+ Boolean string_based (false);
+ {
+ IsStringBasedType t (string_based);
+ t.dispatch (e);
+ }
+
+ Boolean enum_based (false);
+ if (string_based)
+ {
+ SemanticGraph::Enumeration* be (0);
+ IsEnumBasedType t (be);
+ t.dispatch (e);
+
+ enum_based = (be != 0);
+ }
+
+ // If we are based on an enum then the value type is just an
+ // alias and we don't need to generate this operator again.
+ //
+ if (string_based && !enum_based)
+ {
+ os << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "& o, " <<
+ name << "::" << evalue (e) << " i)"
+ << "{"
+ << "return o << " << name << "::_xsd_" << name <<
+ "_literals_[i];"
+ << "}";
+ }
+
+ os << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "& o, " <<
+ "const " << name << "& i)"
+ << "{"
+ << "return o << static_cast< const ";
+
+ inherits (e, inherits_base_);
+
+ os << "& > (i);"
+ << "}";
+
+ // Register with ostream map.
+ //
+ if (polymorphic && !e.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (e));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::std_ostream_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_std_ostream_init;"
+ << endl;
+ }
+ }
+
+ private:
+ Traversal::Inherits inherits_base_;
+ BaseTypeName base_;
+ };
+
+ struct Element : Traversal::Element, protected virtual Context
+ {
+ Element (Context& c, String const& scope_)
+ : Context (c), scope (scope_)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (skip (e))
+ return;
+
+ String const& aname (eaname (e));
+
+ // Check if we need to handle xsi:type and substitution groups.
+ // If this element's type is anonymous or mapped to a fundamental
+ // C++ type then we don't need to do anything. Note that if the
+ // type is anonymous then it can't be derived from which makes it
+ // impossible to substitute or dynamically-type with xsi:type.
+ //
+ SemanticGraph::Type& t (e.type ());
+ Boolean poly (polymorphic && !t.context ().count ("anonymous"));
+
+ if (poly)
+ {
+ Boolean fund (false);
+ IsFundamentalType traverser (fund);
+ traverser.dispatch (t);
+ poly = !fund;
+ }
+
+ // aCC cannot handle an inline call to std_ostream_map_instance.
+ //
+ if (poly)
+ {
+ os << "{"
+ << "::xsd::cxx::tree::std_ostream_map< " << char_type
+ << " >& om (" << endl
+ << "::xsd::cxx::tree::std_ostream_map_instance< 0, " <<
+ char_type << " > ());"
+ << endl;
+ }
+
+ if (max (e) != 1)
+ {
+ // sequence
+ //
+ os << "for (" << scope << "::" << econst_iterator (e) << endl
+ << "b (i." << aname << " ().begin ()), " <<
+ "e (i." << aname << " ().end ());" << endl
+ << "b != e; ++b)"
+ << "{"
+ << "o << ::std::endl << " << L << strlit (e.name () + L": ");
+
+ if (!poly)
+ os << " << *b;";
+ else
+ os << ";"
+ << "om.insert (o, *b);";
+
+ os << "}";
+ }
+ else if (min (e) == 0)
+ {
+ // optional
+ //
+
+ os << "if (i." << aname << " ())"
+ << "{"
+ << "o << ::std::endl << " << L << strlit (e.name () + L": ");
+
+ if (!poly)
+ os << " << *i." << aname << " ();";
+ else
+ os << ";"
+ << "om.insert (o, *i." << aname << " ());";
+
+ os << "}";
+ }
+ else
+ {
+ // one
+ //
+ os << "o << ::std::endl << " << L << strlit (e.name () + L": ");
+
+ if (!poly)
+ os << " << i." << aname << " ();";
+ else
+ os << ";"
+ << "om.insert (o, i." << aname << " ());";
+ }
+
+ if (poly)
+ os << "}";
+ }
+
+ private:
+ String scope;
+ };
+
+ struct Attribute : Traversal::Attribute, protected virtual Context
+ {
+ Attribute (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ String const& aname (eaname (a));
+
+ Boolean def (a.default_ () && !is_qname (a.type ()));
+
+ if (a.optional () && !def)
+ {
+ os << "if (i." << aname << " ())"
+ << "{"
+ << "o << ::std::endl << " << L << strlit (a.name () + L": ") <<
+ " << *i." << aname << " ();"
+ << "}";
+ }
+ else
+ {
+ os << "o << ::std::endl << " << L << strlit (a.name () + L": ") <<
+ " << i." << aname << " ();";
+ }
+ }
+ };
+
+
+ struct Complex : Traversal::Complex, protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c), base_ (c)
+ {
+ inherits_ >> base_;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String name (ename (c));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (c, name) && !name)
+ return;
+
+ //
+ //
+ Boolean has_body (has<Traversal::Member> (c) || c.inherits_p ());
+
+ os << std_ostream_type << "&" << endl
+ << "operator<< (" << std_ostream_type << "& o, " <<
+ "const " << name << "&" << (has_body ? " i" : "") << ")"
+ << "{";
+
+ if (c.inherits_p ())
+ {
+ os << "o << static_cast< const ";
+
+ inherits (c, inherits_);
+
+ os << "& > (i);"
+ << endl;
+ }
+
+ {
+ Traversal::Names names_member;
+ Element element (*this, name);
+ Attribute attribute (*this);
+
+ names_member >> element;
+ names_member >> attribute;
+
+ names (c, names_member);
+ }
+
+ os << "return o;"
+ << "}";
+
+ // Register with ostream map.
+ //
+ if (polymorphic && !c.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (c));
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::std_ostream_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_std_ostream_init;"
+ << endl;
+ }
+ }
+
+ private:
+ Traversal::Inherits inherits_;
+ BaseTypeName base_;
+ };
+ }
+
+ Void
+ generate_stream_source (Context& ctx,
+ UnsignedLong first,
+ UnsignedLong last)
+ {
+ String c (ctx.char_type);
+
+ ctx.os << "#include <ostream>" << endl
+ << endl;
+
+ if (ctx.polymorphic)
+ {
+ ctx.os << "#include <xsd/cxx/tree/std-ostream-map.hxx>" << endl
+ << endl;
+
+ Boolean import_maps (ctx.options.value<CLI::import_maps> ());
+ Boolean export_maps (ctx.options.value<CLI::export_maps> ());
+
+ if (import_maps || export_maps)
+ {
+ ctx.os << "#ifdef _MSC_VER" << endl
+ << endl
+ << "namespace xsd"
+ << "{"
+ << "namespace cxx"
+ << "{"
+ << "namespace tree"
+ << "{";
+
+ if (export_maps)
+ ctx.os << "template struct __declspec (dllexport) " <<
+ "std_ostream_plate< 0, " << ctx.char_type << " >;";
+
+ if (import_maps)
+ ctx.os << "template struct __declspec (dllimport) " <<
+ "std_ostream_plate< 0, " << ctx.char_type << " >;";
+
+ ctx.os << "}" // tree
+ << "}" // cxx
+ << "}" // xsd
+ << "#endif // _MSC_VER" << endl
+ << endl;
+ }
+
+ ctx.os << "namespace _xsd"
+ << "{"
+ << "static" << endl
+ << "const ::xsd::cxx::tree::std_ostream_plate< 0, " <<
+ ctx.char_type << " >" << endl
+ << "std_ostream_plate_init;"
+ << "}";
+ }
+
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names names_ns, names;
+
+ Namespace ns (ctx, first, last);
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+
+ schema >> sources >> schema;
+ schema >> names_ns >> ns >> names;
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/tree/stream-source.hxx b/xsd/cxx/tree/stream-source.hxx
new file mode 100644
index 0000000..2b2e436
--- /dev/null
+++ b/xsd/cxx/tree/stream-source.hxx
@@ -0,0 +1,24 @@
+// file : xsd/cxx/tree/stream-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_STREAM_SOURCE_HXX
+#define CXX_TREE_STREAM_SOURCE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ Void
+ generate_stream_source (Context&,
+ UnsignedLong first,
+ UnsignedLong last);
+ }
+}
+
+#endif // CXX_TREE_STREAM_SOURCE_HXX
diff --git a/xsd/cxx/tree/tree-forward.cxx b/xsd/cxx/tree/tree-forward.cxx
new file mode 100644
index 0000000..8ba8bc1
--- /dev/null
+++ b/xsd/cxx/tree/tree-forward.cxx
@@ -0,0 +1,324 @@
+// file : xsd/cxx/tree/tree-forward.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/tree-forward.hxx>
+#include <cxx/tree/fundamental-header.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ struct List : Traversal::List,
+ protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String const& name (ename (l));
+
+ if (String custom = custom_type (l))
+ {
+ String new_name;
+ renamed_type (l, new_name);
+
+ if (new_name)
+ os << "class " << new_name << ";";
+
+ if (custom == name)
+ os << "class " << name << ";";
+ else
+ os << "typedef " << custom << " " << name << ";";
+ }
+ else
+ os << "class " << name << ";";
+ }
+ };
+
+ struct Union : Traversal::Union,
+ protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String const& name (ename (u));
+
+ if (String custom = custom_type (u))
+ {
+ String new_name;
+ renamed_type (u, new_name);
+
+ if (new_name)
+ os << "class " << new_name << ";";
+
+ if (custom == name)
+ os << "class " << name << ";";
+ else
+ os << "typedef " << custom << " " << name << ";";
+ }
+ else
+ os << "class " << name << ";";
+ }
+ };
+
+ struct Enumeration : Traversal::Enumeration,
+ protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String const& name (ename (e));
+
+ if (String custom = custom_type (e))
+ {
+ String new_name;
+ renamed_type (e, new_name);
+
+ if (new_name)
+ os << "class " << new_name << ";";
+
+ if (custom == name)
+ os << "class " << name << ";";
+ else
+ os << "typedef " << custom << " " << name << ";";
+ }
+ else
+ os << "class " << name << ";";
+ }
+ };
+
+ struct Complex : Traversal::Complex,
+ protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String const& name (ename (c));
+
+ if (String custom = custom_type (c))
+ {
+ String new_name;
+ renamed_type (c, new_name);
+
+ if (new_name)
+ os << "class " << new_name << ";";
+
+ if (custom == name)
+ os << "class " << name << ";";
+ else
+ os << "typedef " << custom << " " << name << ";";
+ }
+ else
+ os << "class " << name << ";";
+ }
+ };
+ }
+
+ Void
+ generate_forward (Context& ctx)
+ {
+ NarrowString xml_schema (ctx.options.value<CLI::extern_xml_schema> ());
+
+ // Inlcude or Emit fundamental types.
+ //
+ if (xml_schema)
+ {
+ String name (ctx.hxx_expr->merge (xml_schema));
+
+ ctx.os << "#include " << ctx.process_include_path (name) << endl
+ << endl;
+ }
+ else
+ {
+ ctx.os << "#include <xsd/cxx/tree/exceptions.hxx>" << endl
+ << "#include <xsd/cxx/tree/elements.hxx>" << endl
+ << "#include <xsd/cxx/tree/types.hxx>" << endl
+ << endl;
+
+ if (!ctx.options.value<CLI::suppress_parsing> () ||
+ ctx.options.value<CLI::generate_serialization> ())
+ {
+ ctx.os << "#include <xsd/cxx/xml/error-handler.hxx>" << endl
+ << endl;
+ }
+
+ if (!ctx.options.value<CLI::suppress_parsing> () ||
+ ctx.options.value<CLI::generate_serialization> ())
+ {
+ ctx.os << "#include <xsd/cxx/xml/dom/auto-ptr.hxx>" << endl
+ << endl;
+ }
+
+ Boolean element_map (ctx.options.value<CLI::generate_element_map> ());
+
+ if (element_map)
+ ctx.os << "#include <xsd/cxx/tree/element-map.hxx>" << endl
+ << endl;
+
+ // I need to include all the "optional" headers here (instead of
+ // later in the individual generators for each feature because
+ // those headers provide implementation for the fundamental types.
+ //
+ if (!ctx.options.value<CLI::suppress_parsing> ())
+ {
+ ctx.os << "#include <xsd/cxx/tree/parsing.hxx>" << endl;
+
+ Traversal::Schema schema, xsd;
+ Traversal::Implies implies;
+ Traversal::Names names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ FundIncludes type (ctx, "parsing");
+
+ schema >> implies >> xsd >> names >> ns >> ns_names >> type;
+
+ schema.dispatch (ctx.schema_root);
+
+ if (element_map)
+ ctx.os << "#include <xsd/cxx/tree/parsing/element-map.txx>" <<
+ endl;
+
+ ctx.os << endl;
+ }
+
+ if (ctx.options.value<CLI::generate_serialization> ())
+ {
+ ctx.os << "#include <xsd/cxx/xml/dom/serialization-header.hxx>" << endl
+ << "#include <xsd/cxx/tree/serialization.hxx>" << endl;
+
+ Traversal::Schema schema, xsd;
+ Traversal::Implies implies;
+ Traversal::Names names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ FundIncludes type (ctx, "serialization");
+
+ schema >> implies >> xsd >> names >> ns >> ns_names >> type;
+
+ schema.dispatch (ctx.schema_root);
+
+ if (element_map)
+ ctx.os << "#include <xsd/cxx/tree/serialization/element-map.txx>" <<
+ endl;
+
+ ctx.os << endl;
+ }
+
+ if (ctx.options.value<CLI::generate_ostream> ())
+ {
+ ctx.os << "#include <xsd/cxx/tree/std-ostream-operators.hxx>" << endl
+ << endl;
+ }
+
+ typedef Containers::Vector<NarrowString> Streams;
+
+ Streams const& ist (ctx.options.value<CLI::generate_insertion> ());
+ if (!ist.empty ())
+ {
+ for (Streams::ConstIterator i (ist.begin ()); i != ist.end (); ++i)
+ {
+ if (*i == "ACE_OutputCDR")
+ ctx.os << "#include <xsd/cxx/tree/ace-cdr-stream-insertion.hxx>"
+ << endl;
+ else if (*i == "XDR")
+ ctx.os << "#include <xsd/cxx/tree/xdr-stream-insertion.hxx>"
+ << endl;
+ }
+
+ ctx.os << "#include <xsd/cxx/tree/stream-insertion.hxx>" << endl
+ << endl;
+ }
+
+ Streams const& est (ctx.options.value<CLI::generate_extraction> ());
+ if (!est.empty ())
+ {
+ for (Streams::ConstIterator i (est.begin ()); i != est.end (); ++i)
+ {
+ if (*i == "ACE_InputCDR")
+ ctx.os << "#include <xsd/cxx/tree/ace-cdr-stream-extraction.hxx>"
+ << endl;
+ else if (*i == "XDR")
+ ctx.os << "#include <xsd/cxx/tree/xdr-stream-extraction.hxx>"
+ << endl;
+ }
+
+ ctx.os << "#include <xsd/cxx/tree/stream-extraction.hxx>" << endl
+ << endl;
+ }
+
+
+ Traversal::Schema schema, xsd;
+ Traversal::Implies implies;
+ Traversal::Names names;
+ FundamentalNamespace ns (ctx);
+
+ schema >> implies >> xsd >> names >> ns;
+
+ schema.dispatch (ctx.schema_root);
+ }
+
+ // First emit header includes.
+ //
+ if (ctx.options.value<CLI::generate_forward> ())
+ {
+ Traversal::Schema schema;
+ Includes includes (ctx, Includes::forward);
+
+ schema >> includes;
+
+ schema.dispatch (ctx.schema_root);
+ }
+
+ ctx.os << "// Forward declarations." << endl
+ << "//" << endl;
+
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+ Traversal::Names names_ns, names;
+ Namespace ns (ctx);
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+
+ schema >> sources >> schema;
+ schema >> names_ns >> ns >> names;
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ schema.dispatch (ctx.schema_root);
+
+ ctx.os << endl;
+ }
+ }
+}
diff --git a/xsd/cxx/tree/tree-forward.hxx b/xsd/cxx/tree/tree-forward.hxx
new file mode 100644
index 0000000..140f8ee
--- /dev/null
+++ b/xsd/cxx/tree/tree-forward.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/tree/tree-forward.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_TREE_FORWARD_HXX
+#define CXX_TREE_TREE_FORWARD_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ Void
+ generate_forward (Context&);
+ }
+}
+
+#endif // CXX_TREE_TREE_FORWARD_HXX
diff --git a/xsd/cxx/tree/tree-header.cxx b/xsd/cxx/tree/tree-header.cxx
new file mode 100644
index 0000000..6b1490c
--- /dev/null
+++ b/xsd/cxx/tree/tree-header.cxx
@@ -0,0 +1,3778 @@
+// file : xsd/cxx/tree/tree-header.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/tree-header.hxx>
+#include <cxx/tree/fundamental-header.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ typedef Containers::Vector<NarrowString> Streams;
+
+ // List mapping.
+ //
+ struct List: Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String name (ename (l));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (l, name) && !name)
+ return;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief List class corresponding to the %" <<
+ comment (l.name ()) << endl
+ << " * schema type." << endl
+ << " *" << endl
+ << " * This class has an interface of a standard C++ " <<
+ "sequence (e.g.," << endl
+ << " * std::vector)." << endl;
+
+ if (l.annotated ())
+ {
+ os << " *" << endl;
+ write_annotation (l.annotation ());
+ }
+
+ os << " */" << endl;
+ }
+
+ SemanticGraph::Type& item_type (l.argumented ().type ());
+ String item_name (item_type_name (item_type));
+ String base_type (L"::xsd::cxx::tree::list< " + item_name + L", " +
+ char_type);
+
+ if (item_type.is_a<SemanticGraph::Fundamental::Double> ())
+ base_type += L", ::xsd::cxx::tree::schema_type::double_";
+ else if (item_type.is_a<SemanticGraph::Fundamental::Decimal> ())
+ base_type += L", ::xsd::cxx::tree::schema_type::decimal";
+
+ base_type += L" >";
+
+ os << "class " << type_exp << name <<
+ ": public " << any_simple_type << "," << endl
+ << " public " << base_type
+ << "{"
+ << "public:" << endl;
+
+ // c-tor ()
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Default constructor." << endl
+ << " *" << endl
+ << " * Creates an empty list." << endl
+ << " */" << endl;
+ }
+ os << name << " ();"
+ << endl;
+
+ // c-tor (size_type, const X& x)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create a list with copies of the specified " <<
+ "element." << endl
+ << " *" << endl
+ << " * @param n A number of elements to copy." << endl
+ << " * @param x An element to copy." << endl
+ << " *" << endl
+ << " * This constructor creates a list with @a n copies " <<
+ "of @a x." << endl
+ << " */" << endl;
+ }
+
+ String size_type (name != L"size_type"
+ ? String (L"size_type")
+ : base_type + L"::size_type");
+
+ os << name << " (" << size_type << " n, const " << item_name <<
+ "& x);"
+ << endl;
+
+ // c-tor (const I& begin, const I& end)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create a list from an iterator range." << endl
+ << " *" << endl
+ << " * @param begin An iterator pointing to the first " <<
+ "element." << endl
+ << " * @param end An iterator pointing to the one past " <<
+ "the last element." << endl
+ << " *" << endl
+ << " * This constructor creates a list consisting of " <<
+ "copies of the" << endl
+ << " * elements in the range [begin,end)." << endl
+ << " */" << endl;
+ }
+
+ String iter_type (unclash (name, "I"));
+
+ os << "template < typename " << iter_type << " >" << endl
+ << name << " (const " << iter_type << "& begin, const " <<
+ iter_type << "& end)" << endl
+ << ": " << base_type << " (begin, end)"
+ << "{"
+ << "}";
+
+ // c-tor (istream&)
+ //
+ Streams const& st (options.value<CLI::generate_extraction> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a data " <<
+ "representation" << endl
+ << " * stream." << endl
+ << " *" << endl
+ << " * @param s A stream to extract the data from." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (" << istream_type << "< " << i->c_str () <<
+ " >& s," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+ }
+
+ if (!options.value<CLI::suppress_parsing> ())
+ {
+ // c-tor (xercesc::DOMElement)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a DOM element." << endl
+ << " *" << endl
+ << " * @param e A DOM element to extract the data from." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << xerces_ns << "::DOMElement& e," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+
+ // c-tor (xercesc::DOMAttr)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a DOM attribute." << endl
+ << " *" << endl
+ << " * @param a A DOM attribute to extract the data from." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << xerces_ns << "::DOMAttr& a," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+
+ // c-tor (std::basic_string const&, xercesc::DOMElement)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a string fragment." << endl
+ << " *" << endl
+ << " * @param s A string fragment to extract the data from." << endl
+ << " * @param e A pointer to DOM element containing the " <<
+ "string fragment." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << string_type << "& s," << endl
+ << "const " << xerces_ns << "::DOMElement* e," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+ }
+
+ // copy c-tor ()
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Copy constructor." << endl
+ << " *" << endl
+ << " * @param x An instance to make a copy of." << endl
+ << " * @param f Flags to create the copy with." << endl
+ << " * @param c A pointer to the object that will contain " <<
+ "the copy." << endl
+ << " *" << endl
+ << " * For polymorphic object models use the @c _clone " <<
+ "function instead." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << name << "& x," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+
+ // clone
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Copy the instance polymorphically." << endl
+ << " *" << endl
+ << " * @param f Flags to create the copy with." << endl
+ << " * @param c A pointer to the object that will contain " <<
+ "the copy." << endl
+ << " * @return A pointer to the dynamically allocated copy." << endl
+ << " *" << endl
+ << " * This function ensures that the dynamic type of the " <<
+ "instance is" << endl
+ << " * used for copying and should be used for polymorphic " <<
+ "object" << endl
+ << " * models instead of the copy constructor." << endl
+ << " */" << endl;
+ }
+
+ os << "virtual " << name << "*" << endl
+ << "_clone (" << flags_type << " f = 0," << endl
+ << container << "* c = 0) const;"
+ << endl;
+
+ // d-tor
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Destructor." << endl
+ << " */" << endl;
+ }
+
+ os << "virtual " << endl
+ << "~" << name << " ();";
+
+ os << "};";
+ }
+
+ private:
+ String
+ item_type_name (SemanticGraph::Type& t)
+ {
+ std::wostringstream o;
+
+ MemberTypeName type (*this, o);
+ type.dispatch (t);
+
+ return o.str ();
+ }
+ };
+
+
+ // Union mapping.
+ //
+ struct Union: Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String name (ename (u));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (u, name) && !name)
+ return;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Union class corresponding to the %" <<
+ comment (u.name ()) << endl
+ << " * schema type." << endl
+ << " *" << endl
+ << " * The mapping represents unions as strings." << endl;
+
+ if (u.annotated ())
+ {
+ os << " *" << endl;
+ write_annotation (u.annotation ());
+ }
+
+ os << " */" << endl;
+ }
+
+ os << "class " << type_exp << name <<
+ ": public " << xs_string_type
+ << "{"
+ << "public:" << endl
+ << endl;
+
+ if (options.value<CLI::generate_default_ctor> ())
+ {
+ // c-tor ()
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Default constructor." << endl
+ << " *" << endl
+ << " * Note that this constructor may leave the " <<
+ "instance in an" << endl
+ << " * invalid state." << endl
+ << " */" << endl;
+ }
+
+ os << name << " ();"
+ << endl;
+ }
+
+ // c-tor (const char*)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a C string." << endl
+ << " *" << endl
+ << " * @param v A string value." << endl
+ << " */" << endl;
+ }
+ os << name << " (const " << char_type << "* v);"
+ << endl;
+
+ // c-tor (string const&)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a string." << endl
+ << " *" << endl
+ << " * @param v A string value." << endl
+ << " */" << endl;
+ }
+ os << name << " (const " << string_type << "& v);"
+ << endl;
+
+ // c-tor (istream&)
+ //
+ Streams const& st (options.value<CLI::generate_extraction> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a data " <<
+ "representation" << endl
+ << " * stream." << endl
+ << " *" << endl
+ << " * @param s A stream to extract the data from." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (" << istream_type << "< " << i->c_str () <<
+ " >& s," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+ }
+
+ if (!options.value<CLI::suppress_parsing> ())
+ {
+ // c-tor (xercesc::DOMElement)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a DOM element." << endl
+ << " *" << endl
+ << " * @param e A DOM element to extract the data from." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << xerces_ns << "::DOMElement& e," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+
+ // c-tor (xercesc::DOMAttr)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a DOM attribute." << endl
+ << " *" << endl
+ << " * @param a A DOM attribute to extract the data from." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << xerces_ns << "::DOMAttr& a," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+
+ // c-tor (std::basic_string const&, xercesc::DOMElement)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a string fragment." << endl
+ << " *" << endl
+ << " * @param s A string fragment to extract the data from." << endl
+ << " * @param e A pointer to DOM element containing the " <<
+ "string fragment." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << string_type << "& s," << endl
+ << "const " << xerces_ns << "::DOMElement* e," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+ }
+
+ // copy c-tor ()
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Copy constructor." << endl
+ << " *" << endl
+ << " * @param x An instance to make a copy of." << endl
+ << " * @param f Flags to create the copy with." << endl
+ << " * @param c A pointer to the object that will contain " <<
+ "the copy." << endl
+ << " *" << endl
+ << " * For polymorphic object models use the @c _clone " <<
+ "function instead." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << name << "& x," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+
+ // clone
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Copy the instance polymorphically." << endl
+ << " *" << endl
+ << " * @param f Flags to create the copy with." << endl
+ << " * @param c A pointer to the object that will contain " <<
+ "the copy." << endl
+ << " * @return A pointer to the dynamically allocated copy." << endl
+ << " *" << endl
+ << " * This function ensures that the dynamic type of the " <<
+ "instance is" << endl
+ << " * used for copying and should be used for polymorphic " <<
+ "object" << endl
+ << " * models instead of the copy constructor." << endl
+ << " */" << endl;
+ }
+
+ os << "virtual " << name << "*" << endl
+ << "_clone (" << flags_type << " f = 0," << endl
+ << container << "* c = 0) const;"
+ << endl;
+
+ os << "};";
+ }
+ };
+
+ // Enum mapping.
+ //
+ struct Enumerator: Traversal::Enumerator, protected virtual Context
+ {
+ Enumerator (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (doxygen && e.annotated ())
+ {
+ os << "/**" << endl;
+ write_annotation (e.annotation ());
+ os << " */" << endl;
+ }
+
+ os << ename (e);
+ }
+ };
+
+ struct Enumeration: Traversal::Enumeration, protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c),
+ base_ (c),
+ member_ (c),
+ enumerator_ (c)
+ {
+ inherits_base_ >> base_;
+ inherits_member_ >> member_;
+
+ names_ >> enumerator_;
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String name (ename (e));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (e, name) && !name)
+ return;
+
+ Boolean string_based (false);
+ {
+ IsStringBasedType t (string_based);
+ t.dispatch (e);
+ }
+
+ Boolean enum_based (false);
+ SemanticGraph::Enumeration* base_enum (0);
+
+ if (string_based)
+ {
+ IsEnumBasedType t (base_enum);
+ t.dispatch (e);
+
+ if (base_enum != 0)
+ enum_based = true;
+ }
+
+ String value;
+ if (string_based)
+ value = evalue (e);
+
+ // Get to the ultimate base and see if is a fundamental type.
+ //
+ Boolean fund_based (false);
+ SemanticGraph::Type& ult_base (ultimate_base (e));
+ {
+ IsFundamentalType t (fund_based);
+ t.dispatch (ult_base);
+ }
+
+ // Count enumerators.
+ //
+ UnsignedLong enum_count (0);
+
+ for (Type::NamesIterator i (e.names_begin ()), end (e.names_end ());
+ i != end; ++i)
+ ++enum_count;
+
+ //
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Enumeration class corresponding to the %" <<
+ comment (e.name ()) << endl
+ << " * schema type." << endl;
+
+ if (e.annotated ())
+ {
+ os << " *" << endl;
+ write_annotation (e.annotation ());
+ }
+
+ os << " */" << endl;
+ }
+
+ os << "class " << type_exp << name << ": public ";
+
+ // Enumeration always has a base.
+ //
+ inherits (e, inherits_base_);
+
+ os << "{"
+ << "public:" << endl;
+
+ if (string_based)
+ {
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief Underlying enum type." << endl
+ << " */" << endl;
+ }
+
+ if (enum_based)
+ {
+ os << "typedef ";
+
+ inherits (e, inherits_base_);
+
+ os << "::" << evalue (*base_enum) << " " << value << ";"
+ << endl;
+ }
+ else
+ {
+ os << "enum " << value
+ << "{";
+
+ names<Enumeration> (e, names_, 0, 0, 0, &Enumeration::comma);
+
+ os << "};";
+ }
+ }
+
+ // default c-tor
+ //
+ if (options.value<CLI::generate_default_ctor> ())
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Default constructor." << endl
+ << " *" << endl
+ << " * Note that this constructor may leave the " <<
+ "instance in an" << endl
+ << " * invalid state." << endl
+ << " */" << endl;
+ }
+
+ os << name << " ();"
+ << endl;
+ }
+
+ // c-tor (value)
+ //
+ if (string_based)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from the " <<
+ "underlying enum value." << endl
+ << " *" << endl
+ << " * @param v A enum value." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (" << value << " v);"
+ << endl;
+ }
+
+ // c-tor (const char*)
+ //
+ if (string_based)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a C string." << endl
+ << " *" << endl
+ << " * @param v A string value." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << char_type << "* v);"
+ << endl;
+ }
+
+ // c-tor (const std::string&)
+ //
+ if (string_based)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a string." << endl
+ << " *" << endl
+ << " * @param v A string value." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << string_type << "& v);"
+ << endl;
+ }
+
+ // c-tor (fundamental)
+ //
+ if (fund_based)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a fundamental " <<
+ "type value." << endl
+ << " *" << endl
+ << " * @param v A fundamental type value." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (";
+
+ member_.dispatch (ult_base);
+
+ os << " v);"
+ << endl;
+ }
+
+ // c-tor (base)
+ //
+ // If the ultimate is also our immediate base and it is a
+ // fundamental type then this c-tor clashes with c-tor
+ // (fundamental) above.
+ //
+ if (!fund_based || &ult_base != &e.inherits ().base ())
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from the " <<
+ "base value." << endl
+ << " *" << endl
+ << " * @param v A base value." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const ";
+
+ inherits (e, inherits_member_);
+
+ os << "& v);"
+ << endl;
+ }
+
+
+ // c-tor (istream&)
+ //
+ Streams const& st (options.value<CLI::generate_extraction> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a data " <<
+ "representation" << endl
+ << " * stream." << endl
+ << " *" << endl
+ << " * @param s A stream to extract the data from." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (" << istream_type << "< " << i->c_str () <<
+ " >& s," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+ }
+
+ if (!options.value<CLI::suppress_parsing> ())
+ {
+ // c-tor (xercesc::DOMElement)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a DOM element." << endl
+ << " *" << endl
+ << " * @param e A DOM element to extract the data from." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << xerces_ns << "::DOMElement& e," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+
+ // c-tor (xercesc::DOMAttr)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a DOM attribute." << endl
+ << " *" << endl
+ << " * @param a A DOM attribute to extract the data from." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << xerces_ns << "::DOMAttr& a," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+
+ // c-tor (std::basic_string const&, xercesc::DOMElement)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a string fragment." << endl
+ << " *" << endl
+ << " * @param s A string fragment to extract the data from." << endl
+ << " * @param e A pointer to DOM element containing the " <<
+ "string fragment." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << string_type << "& s," << endl
+ << "const " << xerces_ns << "::DOMElement* e," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+ }
+
+ // copy c-tor
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Copy constructor." << endl
+ << " *" << endl
+ << " * @param x An instance to make a copy of." << endl
+ << " * @param f Flags to create the copy with." << endl
+ << " * @param c A pointer to the object that will contain " <<
+ "the copy." << endl
+ << " *" << endl
+ << " * For polymorphic object models use the @c _clone " <<
+ "function instead." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << name << "& x," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+
+ // clone
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Copy the instance polymorphically." << endl
+ << " *" << endl
+ << " * @param f Flags to create the copy with." << endl
+ << " * @param c A pointer to the object that will contain " <<
+ "the copy." << endl
+ << " * @return A pointer to the dynamically allocated copy." << endl
+ << " *" << endl
+ << " * This function ensures that the dynamic type of the " <<
+ "instance is" << endl
+ << " * used for copying and should be used for polymorphic " <<
+ "object" << endl
+ << " * models instead of the copy constructor." << endl
+ << " */" << endl;
+ }
+
+ os << "virtual " << name << "*" << endl
+ << "_clone (" << flags_type << " f = 0," << endl
+ << container << "* c = 0) const;"
+ << endl;
+
+ // operator= (value)
+ //
+ if (string_based)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Assign the underlying enum value." << endl
+ << " *" << endl
+ << " * @param v A enum value." << endl
+ << " * @return A refernce to the instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << "&" << endl
+ << "operator= (" << value << " v);"
+ << endl;
+ }
+
+ // operator value ()
+ //
+ // Name lookup differences in various compilers make generation
+ // of this operator outside of the class a really hard task. So
+ // we are going to make it "always inline".
+ //
+ if (string_based)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Implicit conversion operator to the " <<
+ "underlying" << endl
+ << " * enum value." << endl
+ << " *" << endl
+ << " * @return A enum value." << endl
+ << " */" << endl;
+ }
+
+ os << "virtual" << endl
+ << "operator " << value << " () const"
+ << "{"
+ << "return _xsd_" << name << "_convert ();"
+ << "}";
+ }
+
+ //
+ //
+ if (string_based)
+ {
+ if (doxygen)
+ os << "//@cond" << endl
+ << endl;
+
+ os << "protected:" << endl
+ << value << endl
+ << "_xsd_" << name << "_convert () const;"
+ << endl;
+
+ os << "public:" << endl;
+
+ if (enum_based)
+ {
+ // We are going to reuse our base's literals.
+ //
+ os << "static const " << char_type << "* const* " <<
+ "_xsd_" << name << "_literals_;";
+ }
+ else
+ {
+ os << "static const " << char_type << "* const " <<
+ "_xsd_" << name << "_literals_[" << enum_count << "];";
+ }
+
+ os << "static const " << value <<
+ " _xsd_" << name << "_indexes_[" << enum_count << "];";
+
+ if (doxygen)
+ os << endl
+ << "//@endcond" << endl
+ << endl;
+ }
+
+ os << "};";
+ }
+
+ virtual Void
+ comma (Type&)
+ {
+ os << "," << endl;
+ }
+
+ private:
+ Traversal::Inherits inherits_base_;
+ BaseTypeName base_;
+
+ Traversal::Inherits inherits_member_;
+ MemberTypeName member_;
+
+ Traversal::Names names_;
+ Enumerator enumerator_;
+ };
+
+
+ //
+ //
+ struct MemberFunction: Traversal::Member, protected virtual Context
+ {
+ MemberFunction (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m))
+ return;
+
+ String const& aname (eaname (m));
+ String const& mname (emname (m));
+ String kind (m.is_a<SemanticGraph::Element> ()
+ ? "element" : "attribute");
+
+ Boolean fund (false);
+ {
+ IsFundamentalType t (fund);
+ t.dispatch (m.type ());
+ }
+
+ Boolean def_attr (m.default_ () &&
+ m.is_a<SemanticGraph::Attribute> () &&
+ !is_qname (m.type ()));
+
+ if (max (m) != 1)
+ {
+ // sequence
+ //
+ String container (econtainer (m));
+
+ // container const&
+ // name () const;
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-only (constant) reference " <<
+ "to the element" << endl
+ << " * sequence." << endl
+ << " *" << endl
+ << " * @return A constant reference to the sequence " <<
+ "container." << endl
+ << " */" << endl;
+ }
+
+ os << "const " << container << "&" << endl
+ << aname << " () const;"
+ << endl;
+
+ // container&
+ // name ();
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-write reference to the " <<
+ "element sequence." << endl
+ << " *" << endl
+ << " * @return A reference to the sequence container." << endl
+ << " */" << endl;
+ }
+
+ os << container << "&" << endl
+ << aname << " ();"
+ << endl;
+
+ // void
+ // name (container const&);
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Copy elements from a given sequence." << endl
+ << " *" << endl
+ << " * @param s A sequence to copy elements from." << endl
+ << " *" << endl
+ << " * For each element in @a s this function " <<
+ "makes a copy and adds it " << endl
+ << " * to the sequence. Note that this operation " <<
+ "completely changes the " << endl
+ << " * sequence and all old elements will be lost." << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (const " << container << "& s);"
+ << endl;
+ }
+ else if (min (m) == 0 && !def_attr)
+ {
+ // optional
+ //
+ String const& type (etype (m));
+ String container (econtainer (m));
+
+ // container const&
+ // name () const;
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-only (constant) reference " <<
+ "to the " << kind << endl
+ << " * container." << endl
+ << " *" << endl
+ << " * @return A constant reference to the optional " <<
+ "container." << endl
+ << " */" << endl;
+ }
+
+ os << "const " << container << "&" << endl
+ << aname << " () const;"
+ << endl;
+
+ // container&
+ // name ();
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-write reference to the " <<
+ kind << " container." << endl
+ << " *" << endl
+ << " * @return A reference to the optional container." << endl
+ << " */" << endl;
+ }
+
+ os << container << "&" << endl
+ << aname << " ();"
+ << endl;
+
+ // void
+ // name (type const&);
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Set the " << kind << " value." << endl
+ << " *" << endl
+ << " * @param x A new value to set." << endl
+ << " *" << endl
+ << " * This function makes a copy of its argument " <<
+ "and sets it as" << endl
+ << " * the new value of the " << kind << "." << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (const " << type << "& x);"
+ << endl;
+
+ // void
+ // name (container const&);
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Set the " << kind << " value." << endl
+ << " *" << endl
+ << " * @param x An optional container with the new value " <<
+ "to set." << endl
+ << " *" << endl
+ << " * If the value is present in @a x then this function " <<
+ "makes a copy " << endl
+ << " * of this value and sets it as the new value of the " <<
+ kind << "." << endl
+ << " * Otherwise the " << kind << " container is set " <<
+ "the 'not present' state." << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (const " << container << "& x);"
+ << endl;
+
+ // void
+ // name (auto_ptr<type>);
+ //
+ if (!fund)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Set the " << kind << " value without " <<
+ "copying." << endl
+ << " *" << endl
+ << " * @param p A new value to use." << endl
+ << " *" << endl
+ << " * This function will try to use the passed value " <<
+ "directly instead" << endl
+ << " * of making a copy." << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (::std::auto_ptr< " << type << " > p);"
+ << endl;
+ }
+ }
+ else
+ {
+ // one
+ //
+ String const& type (etype (m));
+
+ // type const&
+ // name () const;
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-only (constant) reference " <<
+ "to the " << kind << "." << endl
+ << " *" << endl
+ << " * @return A constant reference to the " << kind <<
+ "." << endl
+ << " */" << endl;
+ }
+
+ os << "const " << type << "&" << endl
+ << aname << " () const;"
+ << endl;
+
+ // Do not generate modifiers for fixed attributes.
+ //
+ if (!(def_attr && m.fixed ()))
+ {
+ // type&
+ // name ();
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-write reference to the " <<
+ kind << "." << endl
+ << " *" << endl
+ << " * @return A reference to the " << kind << "." << endl
+ << " */" << endl;
+ }
+
+ os << type << "&" << endl
+ << aname << " ();"
+ << endl;
+
+ // void
+ // name (type const&);
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Set the " << kind << " value." << endl
+ << " *" << endl
+ << " * @param x A new value to set." << endl
+ << " *" << endl
+ << " * This function makes a copy of its argument " <<
+ "and sets it as" << endl
+ << " * the new value of the " << kind << "." << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (const " << type << "& x);"
+ << endl;
+
+ // void
+ // name (auto_ptr<type>);
+ //
+ if (!fund)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Set the " << kind << " value without " <<
+ "copying." << endl
+ << " *" << endl
+ << " * @param p A new value to use." << endl
+ << " *" << endl
+ << " * This function will try to use the passed value " <<
+ "directly instead" << endl
+ << " * of making a copy." << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (::std::auto_ptr< " << type << " > p);"
+ << endl;
+ }
+ }
+ }
+
+ // default_value
+ //
+ if (m.default_ () && !is_qname (m.type ()))
+ {
+ Boolean simple (true);
+
+ if (m.is_a<SemanticGraph::Element> ())
+ {
+ IsSimpleType test (simple);
+ test.dispatch (m.type ());
+ }
+
+ if (simple)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return the default value for the " <<
+ kind << "." << endl
+ << " *" << endl
+ << " * @return A read-only (constant) reference to the "
+ << kind << "'s" << endl
+ << " * default value." << endl
+ << " */" << endl;
+ }
+
+ os << "static const " << etype (m) << "&" << endl
+ << edefault_value (m) << " ();"
+ << endl;
+ }
+ }
+ }
+ };
+
+ struct AnyFunction: Traversal::Any, protected virtual Context
+ {
+ AnyFunction (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ String const& aname (eaname (a));
+ String const& mname (emname (a));
+
+ SemanticGraph::Complex& c (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ()));
+
+ if (max (a) != 1)
+ {
+ // sequence
+ //
+ String container (econtainer (a));
+
+ // container const&
+ // name () const;
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-only (constant) reference " <<
+ "to the wildcard" << endl
+ << " * element sequence." << endl
+ << " *" << endl
+ << " * @return A constant reference to the sequence " <<
+ "container." << endl
+ << " */" << endl;
+ }
+
+ os << "const " << container << "&" << endl
+ << aname << " () const;"
+ << endl;
+
+ // container&
+ // name ();
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-write reference to the " <<
+ "wildcard element" << endl
+ << " * sequence." << endl
+ << " *" << endl
+ << " * @return A reference to the sequence container." << endl
+ << " */" << endl;
+ }
+
+ os << container << "&" << endl
+ << aname << " ();"
+ << endl;
+
+ // void
+ // name (container const&);
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Copy elements from a given sequence." << endl
+ << " *" << endl
+ << " * @param s A sequence to copy elements from." << endl
+ << " *" << endl
+ << " * For each element in @a s this function " <<
+ "makes a copy and adds" << endl
+ << " * it to the wildcard element sequence. Note that " <<
+ "this operation" << endl
+ << " * completely changes the sequence and all old " <<
+ "elements will be" << endl
+ << " * lost." << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (const " << container << "& s);"
+ << endl;
+ }
+ else if (min (a) == 0)
+ {
+ // optional
+ //
+ String container (econtainer (a));
+
+ // container const&
+ // name () const;
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-only (constant) reference " <<
+ "to the wildcard" << endl
+ << " * element container." << endl
+ << " *" << endl
+ << " * @return A constant reference to the optional " <<
+ "container." << endl
+ << " */" << endl;
+ }
+
+ os << "const " << container << "&" << endl
+ << aname << " () const;"
+ << endl;
+
+ // container&
+ // name ();
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-write reference to the " <<
+ "wildcard element" << endl
+ << " * container." << endl
+ << " *" << endl
+ << " * @return A reference to the optional container." << endl
+ << " */" << endl;
+ }
+
+ os << container << "&" << endl
+ << aname << " ();"
+ << endl;
+
+ // void
+ // name (type const&);
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Set the wildcard content." << endl
+ << " *" << endl
+ << " * @param e A new element to set." << endl
+ << " *" << endl
+ << " * This function makes a copy of its argument " <<
+ "and sets it as" << endl
+ << " * the new wildcard content." << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (const " << xerces_ns << "::DOMElement& e);"
+ << endl;
+
+ // void
+ // name (type*);
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Set the wildcard content without copying." << endl
+ << " *" << endl
+ << " * @param p A new element to use." << endl
+ << " *" << endl
+ << " * This function will use the passed element " <<
+ "directly instead" << endl
+ << " * of making a copy. For this to work the element " <<
+ "should belong" << endl
+ << " * to the DOM document associated with this instance." << endl
+ << " *" << endl
+ << " * @see " << edom_document (c) << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (" << xerces_ns << "::DOMElement* p);"
+ << endl;
+
+ // void
+ // name (container const&);
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Set the wildcard content." << endl
+ << " *" << endl
+ << " * @param x An optional container with the new " <<
+ "element to set." << endl
+ << " *" << endl
+ << " * If the element is present in @a x then this function " <<
+ "makes a " << endl
+ << " * copy of this element and sets it as the new wildcard " <<
+ "content." << endl
+ << " * Otherwise the element container is set the 'not " <<
+ "present' state." << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (const " << container << "& x);"
+ << endl;
+ }
+ else
+ {
+ // one
+ //
+
+ // type const&
+ // name () const;
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-only (constant) reference " <<
+ "to the wildcard" << endl
+ << " * element." << endl
+ << " *" << endl
+ << " * @return A constant reference to the DOM element." << endl
+ << " */" << endl;
+ }
+
+ os << "const " << xerces_ns << "::DOMElement&" << endl
+ << aname << " () const;"
+ << endl;
+
+ // type&
+ // name ();
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-write reference to the " <<
+ "wildcard element." << endl
+ << " *" << endl
+ << " * @return A reference to the DOM element." << endl
+ << " */" << endl;
+ }
+
+ os << xerces_ns << "::DOMElement&" << endl
+ << aname << " ();"
+ << endl;
+
+ // void
+ // name (type const&);
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Set the wildcard content." << endl
+ << " *" << endl
+ << " * @param e A new element to set." << endl
+ << " *" << endl
+ << " * This function makes a copy of its argument " <<
+ "and sets it as" << endl
+ << " * the new wildcard content." << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (const " << xerces_ns << "::DOMElement& e);"
+ << endl;
+
+ // void
+ // name (const*);
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Set the wildcard content without copying." << endl
+ << " *" << endl
+ << " * @param p A new element to use." << endl
+ << " *" << endl
+ << " * This function will use the passed element " <<
+ "directly instead" << endl
+ << " * of making a copy. For this to work the element " <<
+ "should belong" << endl
+ << " * to the DOM document associated with this instance." << endl
+ << " *" << endl
+ << " * @see " << edom_document (c) << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (" << xerces_ns << "::DOMElement* p);"
+ << endl;
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute& a)
+ {
+ String const& aname (eaname (a));
+ String const& mname (emname (a));
+
+ String container (econtainer (a));
+
+ // container const&
+ // name () const;
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-only (constant) reference " <<
+ "to the" << endl
+ << " * attribute set." << endl
+ << " *" << endl
+ << " * @return A constant reference to the set " <<
+ "container." << endl
+ << " */" << endl;
+ }
+
+ os << "const " << container << "&" << endl
+ << aname << " () const;"
+ << endl;
+
+ // container&
+ // name ();
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-write reference to the " <<
+ "attribute set." << endl
+ << " *" << endl
+ << " * @return A reference to the set container." << endl
+ << " */" << endl;
+ }
+
+ os << container << "&" << endl
+ << aname << " ();"
+ << endl;
+
+ // void
+ // name (container const&);
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Copy attributes from a given set." << endl
+ << " *" << endl
+ << " * @param s A set to copy elements from." << endl
+ << " *" << endl
+ << " * For each attribute in @a s this function " <<
+ "makes a copy and adds" << endl
+ << " * it to the set. Note that this operation " <<
+ "completely changes the " << endl
+ << " * set and all old attributes will be lost." << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (const " << container << "& s);"
+ << endl;
+ }
+ };
+
+ //
+ //
+ struct Member: Traversal::Member, protected virtual Context
+ {
+ Member (Context& c)
+ : Context (c),
+ type_name_ (c),
+ member_function_ (c)
+ {
+ belongs_ >> type_name_;
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m))
+ return;
+
+ String const& type (etype (m));
+ Boolean el (m.is_a<SemanticGraph::Element> ());
+
+ Boolean def_attr (m.default_ () && !el && !is_qname (m.type ()));
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @name " << comment (m.name ()) << endl
+ << " *" << endl
+ << " * @brief Accessor and modifier functions for the %" <<
+ comment (m.name ()) << endl
+ << " * ";
+
+ if (max (m) != 1)
+ {
+ os << "sequence element." << endl;
+ }
+ else if (min (m) == 0)
+ {
+ if (def_attr)
+ os << "optional attribute with a default value." << endl;
+ else
+ os << "optional " << (el ? "element." : "attribute.") << endl;
+ }
+ else
+ {
+ os << "required " << (el ? "element." : "attribute.") << endl;
+ }
+
+ if (m.annotated ())
+ {
+ os << " *" << endl;
+ write_annotation (m.annotation ());
+ }
+
+ os << " */" << endl
+ << "//@{" << endl;
+ }
+ else
+ {
+ os << "// " << comment (m.name ()) << endl
+ << "// " << endl;
+ }
+
+ // Typedefs.
+ //
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief " << (el ? "Element" : "Attribute") <<
+ " type." << endl
+ << " */" << endl;
+ }
+
+ os << "typedef ";
+
+ belongs (m, belongs_);
+
+ os << " " << type << ";";
+
+ if (max (m) != 1)
+ {
+ String const& container (econtainer (m));
+ Boolean isense (options.value<CLI::generate_intellisense> ());
+
+ // sequence
+ //
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief Element sequence container type." << endl
+ << " */" << endl;
+ }
+
+ os << "typedef ::xsd::cxx::tree::sequence< " << type << " > " <<
+ container << ";";
+
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief Element iterator type." << endl
+ << " */" << endl;
+ }
+
+ // IntelliSense does not not like aliases and fully-qualified
+ // names here.
+ //
+ if (!isense)
+ os << "typedef " << container << "::iterator " <<
+ eiterator (m) << ";";
+ else
+ os << "typedef xsd::cxx::tree::sequence< " << type <<
+ " >::iterator " << eiterator (m) << ";";
+
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief Element constant iterator type." << endl
+ << " */" << endl;
+ }
+
+ if (!isense)
+ os << "typedef " << container << "::const_iterator " <<
+ econst_iterator (m) << ";";
+ else
+ os << "typedef xsd::cxx::tree::sequence< " << type <<
+ " >::const_iterator " << econst_iterator (m) << ";";
+
+ }
+ else if (min (m) == 0 && !def_attr)
+ {
+ // optional
+ //
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief " << (el ? "Element" : "Attribute") <<
+ " optional container type." << endl
+ << " */" << endl;
+ }
+
+ os << "typedef ::xsd::cxx::tree::optional< " << type << " > " <<
+ econtainer (m) << ";";
+ }
+ else
+ {
+ // one
+ //
+ }
+
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief " << (el ? "Element" : "Attribute") <<
+ " traits type." << endl
+ << " */" << endl;
+ }
+ os << "typedef ::xsd::cxx::tree::traits< " << type << ", " <<
+ char_type;
+
+ SemanticGraph::Type& t (m.type ());
+
+ if (t.is_a<SemanticGraph::Fundamental::Double> ())
+ os << ", ::xsd::cxx::tree::schema_type::double_";
+ else if (t.is_a<SemanticGraph::Fundamental::Decimal> ())
+ os << ", ::xsd::cxx::tree::schema_type::decimal";
+
+ os << " > " << etraits (m) << ";"
+ << endl;
+
+ member_function_.traverse (m);
+
+ if (doxygen)
+ {
+ os << "//@}" << endl
+ << endl;
+ }
+ }
+
+ private:
+ MemberTypeName type_name_;
+ Traversal::Belongs belongs_;
+
+ MemberFunction member_function_;
+ };
+
+
+ struct Any: Traversal::Any,
+ Traversal::AnyAttribute,
+ protected virtual Context
+ {
+ Any (Context& c)
+ : Context (c), any_function_ (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @name " << ename (a) << endl
+ << " *" << endl
+ << " * @brief Accessor and modifier functions for the " <<
+ "any wildcard." << endl;
+
+ if (a.annotated ())
+ {
+ os << " *" << endl;
+ write_annotation (a.annotation ());
+ }
+
+ os << " */" << endl
+ << "//@{" << endl;
+ }
+ else
+ {
+ os << "// " << ename (a) << endl
+ << "// " << endl;
+ }
+
+ // Typedefs.
+ //
+ if (max (a) != 1)
+ {
+ String const& container (econtainer (a));
+
+ // sequence
+ //
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief DOM element sequence container type." << endl
+ << " */" << endl;
+ }
+
+ os << "typedef ::xsd::cxx::tree::element_sequence " <<
+ container << ";";
+
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief DOM element iterator type." << endl
+ << " */" << endl;
+ }
+
+ os << "typedef " << container << "::iterator " <<
+ eiterator (a) << ";";
+
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief DOM element constant iterator type." << endl
+ << " */" << endl;
+ }
+
+ os << "typedef " << container << "::const_iterator " <<
+ econst_iterator (a) << ";"
+ << endl;
+
+ }
+ else if (min (a) == 0)
+ {
+ // optional
+ //
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief DOM element optional container type." << endl
+ << " */" << endl;
+ }
+
+ os << "typedef ::xsd::cxx::tree::element_optional " <<
+ econtainer (a) << ";"
+ << endl;
+ }
+ else
+ {
+ // one
+ //
+ if (doxygen)
+ os << endl;
+ }
+
+ any_function_.traverse (a);
+
+ if (doxygen)
+ {
+ os << "//@}" << endl
+ << endl;
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute& a)
+ {
+ String const& container (econtainer (a));
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @name " << ename (a) << endl
+ << " *" << endl
+ << " * @brief Accessor and modifier functions for the " <<
+ "anyAttribute" << endl
+ << " * wildcard." << endl;
+
+ if (a.annotated ())
+ {
+ os << " *" << endl;
+ write_annotation (a.annotation ());
+ }
+
+ os << " */" << endl
+ << "//@{" << endl;
+ }
+ else
+ {
+ os << "// " << ename (a) << endl
+ << "// " << endl;
+ }
+
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief DOM attribute set container type." << endl
+ << " */" << endl;
+ }
+
+ os << "typedef ::xsd::cxx::tree::attribute_set< " << char_type <<
+ " > " << container << ";";
+
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief DOM attribute iterator type." << endl
+ << " */" << endl;
+ }
+
+ os << "typedef " << container << "::iterator " <<
+ eiterator (a) << ";";
+
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief DOM attribute constant iterator type." << endl
+ << " */" << endl;
+ }
+
+ os << "typedef " << container << "::const_iterator " <<
+ econst_iterator (a) << ";"
+ << endl;
+
+ any_function_.traverse (a);
+
+ if (doxygen)
+ {
+ os << "//@}" << endl
+ << endl;
+ }
+ }
+
+ private:
+ AnyFunction any_function_;
+ };
+
+ struct DataMember: Traversal::Member, protected virtual Context
+ {
+ DataMember (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m)) return;
+
+ String const& member (emember (m));
+
+ Boolean def_attr (m.default_ () &&
+ m.is_a<SemanticGraph::Attribute> () &&
+ !is_qname (m.type ()));
+
+ if (max (m) != 1)
+ {
+ // sequence
+ //
+ os << econtainer (m) << " " << member << ";";
+ }
+ else if (min (m) == 0 && !def_attr)
+ {
+ // optional
+ //
+ os << econtainer (m) << " " << member << ";";
+ }
+ else
+ {
+ // one
+ //
+ os << "::xsd::cxx::tree::one< " << etype (m) << " > " <<
+ member << ";";
+ }
+
+ // default_value
+ //
+ if (m.default_ () && !is_qname (m.type ()))
+ {
+ Boolean simple (true);
+
+ if (m.is_a<SemanticGraph::Element> ())
+ {
+ IsSimpleType test (simple);
+ test.dispatch (m.type ());
+ }
+
+ if (simple)
+ {
+ os << "static const " << etype (m) << " " <<
+ edefault_value_member (m) << ";";
+ }
+ }
+ }
+ };
+
+ struct DataAny: Traversal::Any,
+ Traversal::AnyAttribute,
+ protected virtual Context
+ {
+ DataAny (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ String const& member (emember (a));
+
+ if (max (a) != 1)
+ {
+ // sequence
+ //
+ os << econtainer (a) << " " << member << ";";
+ }
+ else if (min (a) == 0)
+ {
+ // optional
+ //
+ os << econtainer (a) << " " << member << ";";
+ }
+ else
+ {
+ // one
+ //
+ os << "::xsd::cxx::tree::element_one " << member << ";";
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute& a)
+ {
+ os << econtainer (a) << " " << emember (a) << ";";
+ }
+ };
+
+
+ struct Complex : Traversal::Complex, protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c),
+ base_name_ (c),
+ member_name_ (c),
+ any_ (c),
+ member_ (c),
+ data_any_ (c),
+ data_member_ (c)
+ {
+ inherits_base_ >> base_name_;
+ inherits_member_ >> member_name_;
+
+ names_ >> member_;
+ if (options.value<CLI::generate_wildcard> ())
+ names_ >> any_;
+
+ names_data_ >> data_member_;
+ if (options.value<CLI::generate_wildcard> ())
+ names_data_ >> data_any_;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String name (ename (c));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (c, name) && !name)
+ return;
+
+ Boolean has_members (has<Traversal::Member> (c));
+
+ Boolean hae (has<Traversal::Any> (c));
+ Boolean haa (has<Traversal::AnyAttribute> (c));
+
+ Boolean gen_wildcard (options.value<CLI::generate_wildcard> ());
+
+ Boolean simple (true);
+ {
+ IsSimpleType t (simple);
+ t.dispatch (c);
+ }
+
+ Boolean string_based (false);
+ {
+ IsStringBasedType t (string_based);
+ t.dispatch (c);
+ }
+
+ SemanticGraph::Enumeration* enum_base (0);
+ {
+ IsEnumBasedType t (enum_base);
+ t.dispatch (c);
+ }
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Class corresponding to the %" <<
+ comment (c.name ()) << " schema type." << endl;
+
+ if (c.annotated ())
+ {
+ os << " *" << endl;
+ write_annotation (c.annotation ());
+ }
+
+ os << " *" << endl
+ << " * @nosubgrouping" << endl
+ << " */" << endl;
+ }
+
+ os << "class " << type_exp << name << ": public ";
+
+ if (c.inherits_p ())
+ inherits (c, inherits_base_);
+ else
+ os << any_type;
+
+ os << "{"
+ << "public:" << endl;
+
+ // Members.
+ //
+ names (c, names_);
+
+ // dom_document accessors.
+ //
+ if (edom_document_member_p (c))
+ {
+
+ if (!doxygen)
+ {
+ os << "// DOMDocument for wildcard content." << endl
+ << "//" << endl;
+ }
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-only (constant) reference " <<
+ "to the DOM" << endl
+ << " * document associated with this instance." << endl
+ << " *" << endl
+ << " * @return A constant reference to the DOM document." << endl
+ << " *" << endl
+ << " * The DOM document returned by this function is " <<
+ "used to store" << endl
+ << " * the raw XML content corresponding to wildcards." << endl
+ << " */" << endl;
+ }
+
+ os << "const " << xerces_ns << "::DOMDocument&" << endl
+ << edom_document (c) << " () const;"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-write reference to the DOM " <<
+ "document" << endl
+ << " * associated with this instance." << endl
+ << " *" << endl
+ << " * @return A reference to the DOM document." << endl
+ << " *" << endl
+ << " * The DOM document returned by this function is " <<
+ "used to store" << endl
+ << " * the raw XML content corresponding to wildcards." << endl
+ << " */" << endl;
+ }
+ os << xerces_ns << "::DOMDocument&" << endl
+ << edom_document (c) << " ();"
+ << endl;
+ }
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @name Constructors" << endl
+ << " */" << endl
+ << "//@{" << endl
+ << endl;
+ }
+ else
+ {
+ os << "// Constructors." << endl
+ << "//" << endl;
+ }
+
+ Boolean generate_no_base_ctor (false);
+ {
+ GenerateWithoutBaseCtor t (generate_no_base_ctor);
+ t.traverse (c);
+ }
+
+ Boolean has_complex_non_op_args (false);
+ Boolean has_non_fund_non_op_args (false);
+ Boolean complex_non_fund_args_clash (true);
+ {
+ HasComplexNonFundNonOptArgs t (*this, true,
+ has_complex_non_op_args,
+ has_non_fund_non_op_args,
+ complex_non_fund_args_clash);
+ t.traverse (c);
+ }
+
+ // default c-tor
+ //
+ if (options.value<CLI::generate_default_ctor> ())
+ {
+ // c-tor (ultimate-base all-non-optional-members) will become
+ // default c-tor if our inheritance hierarchy has no required
+ // members and no simple base. We can also collide with
+ // c-tor (all-non-optional-members) if we have no required
+ // members.
+ //
+ Boolean generate (false);
+ {
+ GenerateDefaultCtor t (*this, generate, generate_no_base_ctor);
+ t.traverse (c);
+ }
+
+ if (generate)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Default constructor." << endl
+ << " *" << endl
+ << " * Note that this constructor leaves required " <<
+ "elements and" << endl
+ << " * attributes uninitialized." << endl
+ << " */" << endl;
+ }
+
+ os << name << " ();"
+ << endl;
+ }
+ }
+
+ // c-tor (base, all-non-optional-members)
+ //
+ if (options.value<CLI::generate_from_base_ctor> ())
+ {
+ // c-tor (ultimate-base, all-non-optional-members) will become
+ // c-tor (base, all-non-optional-members) unless our immediate
+ // base's hierarchy has some non-optional members.
+ //
+ Boolean generate (false);
+ {
+ GenerateFromBaseCtor t (*this, generate);
+ t.traverse (c);
+ }
+
+ if (generate)
+ {
+ Boolean has_complex_non_op_args (false);
+ Boolean has_non_fund_non_op_args (false);
+ Boolean complex_non_fund_args_clash (true);
+ {
+ HasComplexNonFundNonOptArgs t (*this, false,
+ has_complex_non_op_args,
+ has_non_fund_non_op_args,
+ complex_non_fund_args_clash);
+ t.traverse (c);
+ }
+
+ //
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from the immediate "
+ "base and" << endl
+ << " * initializers for required elements and "
+ << "attributes." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const ";
+ inherits (c, inherits_member_);
+ os << "&";
+ {
+ FromBaseCtorArg args (*this, FromBaseCtorArg::arg_type, false);
+ Traversal::Names args_names (args);
+ names (c, args_names);
+ }
+ os << ");"
+ << endl;
+
+ // If we have any complex arguments in the previous c-tor
+ // then also generate the auto_ptr version.
+ //
+ if (has_complex_non_op_args)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from the immediate "
+ "base and" << endl
+ << " * initializers for required elements and "
+ << "attributes" << endl
+ << " * (auto_ptr version)." << endl
+ << " *" << endl
+ << " * This constructor will try to use the passed " <<
+ "values directly" << endl
+ << " * instead of making copies." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const ";
+ inherits (c, inherits_member_);
+ os << "&";
+ {
+ FromBaseCtorArg args (
+ *this, FromBaseCtorArg::arg_complex_auto_ptr, false);
+ Traversal::Names args_names (args);
+ names (c, args_names);
+ }
+ os << ");"
+ << endl;
+ }
+
+ // If we are generating polymorphic code then we also need to
+ // provide auto_ptr version for every non-fundamental type.
+ //
+ if (polymorphic &&
+ has_non_fund_non_op_args && !complex_non_fund_args_clash)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from the immediate "
+ "base and" << endl
+ << " * initializers for required elements and "
+ << "attributes" << endl
+ << " * (auto_ptr version)." << endl
+ << " *" << endl
+ << " * This constructor will try to use the passed " <<
+ "values directly" << endl
+ << " * instead of making copies." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const ";
+ inherits (c, inherits_member_);
+ os << "&";
+ {
+ FromBaseCtorArg args (
+ *this, FromBaseCtorArg::arg_non_fund_auto_ptr, false);
+ Traversal::Names args_names (args);
+ names (c, args_names);
+ }
+ os << ");"
+ << endl;
+ }
+ }
+ }
+
+ // c-tor (all-non-optional-members)
+ //
+ if (generate_no_base_ctor)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from initializers " <<
+ "for required " << endl
+ << " * elements and attributes." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (";
+ {
+ CtorArgsWithoutBase ctor_args (
+ *this, CtorArgsWithoutBase::arg_type, false, true);
+ ctor_args.dispatch (c);
+ }
+ os << ");"
+ << endl;
+
+
+ // If we have any complex arguments in the previous c-tor
+ // then also generate the auto_ptr version. One case where
+ // this c-tor will be generated is restriction of anyType.
+ //
+ if (has_complex_non_op_args)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from initializers " <<
+ "for required " << endl
+ << " * elements and attributes (auto_ptr version)." << endl
+ << " *" << endl
+ << " * This constructor will try to use the passed " <<
+ "values directly" << endl
+ << " * instead of making copies." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (";
+ {
+ CtorArgsWithoutBase ctor_args (
+ *this, CtorArgsWithoutBase::arg_complex_auto_ptr, false, true);
+ ctor_args.dispatch (c);
+ }
+ os << ");"
+ << endl;
+ }
+
+ // If we are generating polymorphic code then we also need to
+ // provide auto_ptr version for every non-fundamental type.
+ //
+ if (polymorphic &&
+ has_non_fund_non_op_args && !complex_non_fund_args_clash)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from initializers " <<
+ "for required " << endl
+ << " * elements and attributes (auto_ptr version)." << endl
+ << " *" << endl
+ << " * This constructor will try to use the passed " <<
+ "values directly" << endl
+ << " * instead of making copies." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (";
+ {
+ CtorArgsWithoutBase ctor_args (
+ *this, CtorArgsWithoutBase::arg_non_fund_auto_ptr, false, true);
+ ctor_args.dispatch (c);
+ }
+ os << ");"
+ << endl;
+ }
+ }
+
+ if (string_based)
+ {
+ if (enum_base != 0)
+ {
+ // c-tor (enum-value, all-non-optional-members)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from the " <<
+ "underlying enum value" << endl
+ << " * and initializers for required elements and " <<
+ "attributes." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (" << fq_name (*enum_base) << "::" <<
+ evalue (*enum_base);
+
+ {
+ CtorArgsWithoutBase ctor_args (
+ *this, CtorArgsWithoutBase::arg_type, false, false);
+ ctor_args.dispatch (c);
+ }
+
+ os << ");"
+ << endl;
+ }
+
+ // c-tor (const char*, all-non-optional-members)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a C string and " <<
+ "initializers" << endl
+ << " * for required elements and attributes." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << char_type << "*";
+
+ {
+ CtorArgsWithoutBase ctor_args (
+ *this, CtorArgsWithoutBase::arg_type, false, false);
+ ctor_args.dispatch (c);
+ }
+
+ os << ");"
+ << endl;
+
+ // c-tor (const std::string&, all-non-optional-members)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a string and" <<
+ "initializers" << endl
+ << " * for required elements and attributes." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << string_type << "&";
+
+ {
+ CtorArgsWithoutBase ctor_args (
+ *this, CtorArgsWithoutBase::arg_type, false, false);
+ ctor_args.dispatch (c);
+ }
+
+ os << ");"
+ << endl;
+ }
+
+ // c-tor (ultimate-base, all-non-optional-members)
+ //
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from the ultimate "
+ "base and" << endl
+ << " * initializers for required elements and " <<
+ "attributes." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (";
+
+ {
+ CtorArgs ctor_args (*this, CtorArgs::arg_type);
+ ctor_args.dispatch (c);
+ }
+
+ os << ");"
+ << endl;
+
+ // If we have any complex arguments in the previous c-tor
+ // then also generate the auto_ptr version.
+ //
+ if (has_complex_non_op_args)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from the ultimate "
+ "base and" << endl
+ << " * initializers for required elements and " <<
+ "attributes" << endl
+ << " * (auto_ptr version)." << endl
+ << " *" << endl
+ << " * This constructor will try to use the passed " <<
+ "values directly" << endl
+ << " * instead of making copies." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (";
+
+ {
+ CtorArgs ctor_args (*this, CtorArgs::arg_complex_auto_ptr);
+ ctor_args.dispatch (c);
+ }
+
+ os << ");"
+ << endl;
+ }
+
+ // If we are generating polymorphic code then we also need to
+ // provide auto_ptr version for every non-fundamental type.
+ //
+ if (polymorphic &&
+ has_non_fund_non_op_args && !complex_non_fund_args_clash)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from the ultimate "
+ "base and" << endl
+ << " * initializers for required elements and " <<
+ "attributes" << endl
+ << " * (auto_ptr version)." << endl
+ << " *" << endl
+ << " * This constructor will try to use the passed " <<
+ "values directly" << endl
+ << " * instead of making copies." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (";
+
+ {
+ CtorArgs ctor_args (*this, CtorArgs::arg_non_fund_auto_ptr);
+ ctor_args.dispatch (c);
+ }
+
+ os << ");"
+ << endl;
+ }
+
+ // c-tor (istream&)
+ //
+ Streams const& st (options.value<CLI::generate_extraction> ());
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a data " <<
+ "representation" << endl
+ << " * stream." << endl
+ << " *" << endl
+ << " * @param s A stream to extract the data from." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (" << istream_type << "< " << i->c_str () <<
+ " >& s," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+ }
+
+
+ if (!options.value<CLI::suppress_parsing> ())
+ {
+ // c-tor (xercesc::DOMElement)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a DOM element." << endl
+ << " *" << endl
+ << " * @param e A DOM element to extract the data from." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << xerces_ns << "::DOMElement& e," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+
+
+ if (simple)
+ {
+ // c-tor (xercesc::DOMAttr)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a DOM attribute." << endl
+ << " *" << endl
+ << " * @param a A DOM attribute to extract the data from." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << xerces_ns << "::DOMAttr& a," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+
+ // c-tor (std::basic_string const&, xercesc::DOMElement)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a string fragment." << endl
+ << " *" << endl
+ << " * @param s A string fragment to extract the data from." << endl
+ << " * @param e A pointer to DOM element containing the " <<
+ "string fragment." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " * @param c A pointer to the object that will " <<
+ "contain the new" << endl
+ << " * instance." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << string_type << "& s," << endl
+ << "const " << xerces_ns << "::DOMElement* e," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+ }
+ }
+
+ // copy c-tor
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Copy constructor." << endl
+ << " *" << endl
+ << " * @param x An instance to make a copy of." << endl
+ << " * @param f Flags to create the copy with." << endl
+ << " * @param c A pointer to the object that will contain " <<
+ "the copy." << endl
+ << " *" << endl
+ << " * For polymorphic object models use the @c _clone " <<
+ "function instead." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << name << "& x," << endl
+ << flags_type << " f = 0," << endl
+ << container << "* c = 0);"
+ << endl;
+
+ // clone
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Copy the instance polymorphically." << endl
+ << " *" << endl
+ << " * @param f Flags to create the copy with." << endl
+ << " * @param c A pointer to the object that will contain " <<
+ "the copy." << endl
+ << " * @return A pointer to the dynamically allocated copy." << endl
+ << " *" << endl
+ << " * This function ensures that the dynamic type of the " <<
+ "instance is" << endl
+ << " * used for copying and should be used for polymorphic " <<
+ "object" << endl
+ << " * models instead of the copy constructor." << endl
+ << " */" << endl;
+ }
+
+ os << "virtual " << name << "*" << endl
+ << "_clone (" << flags_type << " f = 0," << endl
+ << container << "* c = 0) const;"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "//@}" << endl
+ << endl;
+ }
+
+ // d-tor
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Destructor." << endl
+ << " */" << endl;
+ }
+
+ os << "virtual " << endl
+ << "~" << name << " ();"
+ << endl;
+
+ // Data members and implementation functions.
+ //
+ if (has_members || hae || (haa && gen_wildcard))
+ {
+ os << "// Implementation." << endl
+ << "//" << endl;
+
+ if (doxygen)
+ os << endl
+ << "//@cond" << endl
+ << endl;
+
+ if (!options.value<CLI::suppress_parsing> ())
+ {
+ // parse (xercesc::DOMElement)
+ //
+ os << "protected:" << endl
+ << "void" << endl
+ << unclash (name, "parse") << " (" <<
+ parser_type << "&," << endl
+ << flags_type << ");"
+ << endl;
+ }
+
+ os << "protected:"
+ << endl;
+
+ // parse (istream)
+ //
+ if (has_members)
+ {
+ for (Streams::ConstIterator i (st.begin ()); i != st.end (); ++i)
+ {
+ os << "void" << endl
+ << unclash (name, "parse") << " (" <<
+ istream_type << "< " << i->c_str () << " >&," << endl
+ << flags_type << ");"
+ << endl;
+ }
+ }
+
+ //
+ //
+ if (edom_document_member_p (c))
+ {
+ os << dom_auto_ptr << "< " << xerces_ns <<
+ "::DOMDocument > " << edom_document_member (c) << ";"
+ << endl;
+ }
+
+ //
+ //
+ names (c, names_data_);
+
+ if (doxygen)
+ os << endl
+ << "//@endcond" << endl;
+ }
+
+ os << "};";
+
+ // Comparison operators.
+ //
+ if (options.value<CLI::generate_comparison> () &&
+ (has_members || !c.inherits_p () ||
+ ((hae || haa) && gen_wildcard)))
+ {
+ os << inst_exp
+ << "bool" << endl
+ << "operator== (const " << name << "&, const " << name << "&);"
+ << endl;
+
+ os << inst_exp
+ << "bool" << endl
+ << "operator!= (const " << name << "&, const " << name << "&);"
+ << endl
+ << endl;
+ }
+ }
+
+ private:
+ Traversal::Inherits inherits_base_;
+ BaseTypeName base_name_;
+
+ Traversal::Inherits inherits_member_;
+ MemberTypeName member_name_;
+
+ Traversal::Names names_;
+ Any any_;
+ Member member_;
+
+ Traversal::Names names_data_;
+ DataAny data_any_;
+ DataMember data_member_;
+ };
+
+
+ struct GlobalElement : Traversal::Element,
+ GlobalElementBase,
+ protected virtual Context
+ {
+ GlobalElement (Context& c)
+ : Context (c), GlobalElementBase (c), type_name_ (c)
+ {
+ belongs_ >> type_name_;
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (!doc_root_p (e))
+ return;
+
+ SemanticGraph::Type& t (e.type ());
+
+ Boolean fund (false);
+ {
+ IsFundamentalType test (fund);
+ test.dispatch (t);
+ }
+
+ Boolean simple (true);
+ if (!fund)
+ {
+ IsSimpleType test (simple);
+ test.dispatch (t);
+ }
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Class corresponding to the %" <<
+ comment (e.name ()) << " root element." << endl;
+
+ if (e.annotated ())
+ {
+ os << " *" << endl;
+ write_annotation (e.annotation ());
+ }
+
+ os << " *" << endl
+ << " * @nosubgrouping" << endl
+ << " */" << endl;
+ }
+
+ String const& name (ename (e));
+
+ os << "class " << type_exp << name << ": public " << element_type
+ << "{"
+ << "public:" << endl
+ << endl;
+
+ String const& type (etype (e));
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @name Element value" << endl
+ << " *" << endl
+ << " * @brief Accessor and modifier functions for the " <<
+ "element value." << endl
+ << " */" << endl
+ << "//@{" << endl
+ << endl;
+ }
+ else
+ {
+ os << "// Element value." << endl
+ << "//" << endl;
+ }
+
+ // Typedefs.
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Element value type." << endl
+ << " */" << endl;
+ }
+
+ os << "typedef ";
+
+ belongs (e, belongs_);
+
+ os << " " << type << ";";
+
+ if (doxygen)
+ {
+ os << endl
+ << "/**" << endl
+ << " * @brief Element value traits type." << endl
+ << " */" << endl;
+ }
+
+ os << "typedef ::xsd::cxx::tree::traits< " << type << ", " <<
+ char_type;
+
+ if (t.is_a<SemanticGraph::Fundamental::Double> ())
+ os << ", ::xsd::cxx::tree::schema_type::double_";
+ else if (t.is_a<SemanticGraph::Fundamental::Decimal> ())
+ os << ", ::xsd::cxx::tree::schema_type::decimal";
+
+ os << " > " << etraits (e) << ";"
+ << endl;
+
+ // Accessors/modifiers.
+ //
+ String const& aname (eaname (e));
+ String const& mname (emname (e));
+
+ // type const&
+ // name () const;
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-only (constant) reference " <<
+ "to the element" << endl
+ << " * value." << endl
+ << " *" << endl
+ << " * @return A constant reference to the element value." <<
+ endl
+ << " */" << endl;
+ }
+
+ os << "const " << type << "&" << endl
+ << aname << " () const;"
+ << endl;
+
+ // type&
+ // name ();
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-write reference to the " <<
+ "element value." << endl
+ << " *" << endl
+ << " * @return A reference to the element value." << endl
+ << " */" << endl;
+ }
+
+ os << type << "&" << endl
+ << aname << " ();"
+ << endl;
+
+ // void
+ // name (type const&);
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Set the element value." << endl
+ << " *" << endl
+ << " * @param x A new value to set." << endl
+ << " *" << endl
+ << " * This function makes a copy of its argument " <<
+ "and sets it as" << endl
+ << " * the new value of the element." << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (const " << type << "& x);"
+ << endl;
+
+ // void
+ // name (auto_ptr<type>);
+ //
+ if (!fund)
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Set the element value without " <<
+ "copying." << endl
+ << " *" << endl
+ << " * @param p A new value to use." << endl
+ << " *" << endl
+ << " * This function will try to use the passed value " <<
+ "directly" << endl
+ << " * instead of making a copy." << endl
+ << " */" << endl;
+ }
+
+ os << "void" << endl
+ << mname << " (::std::auto_ptr< " << type << " > p);"
+ << endl;
+ }
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a read-only (constant) pointer " <<
+ "to the element" << endl
+ << " * value." << endl
+ << " *" << endl
+ << " * @return A constant pointer to the element value " <<
+ "or 0 if this" << endl
+ << " * element is of a fundamental type." << endl
+ << " */" << endl;
+ }
+
+ os << "virtual const " << any_type << "*" << endl
+ << "_value () const;"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return a pointer to the element value." << endl
+ << " *" << endl
+ << " * @return A pointer to the element value or 0 if this " <<
+ "element is" << endl
+ << " * of a fundamental type." << endl
+ << " */" << endl;
+ }
+ os << "virtual " << any_type << "*" << endl
+ << "_value ();"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "//@}" << endl
+ << endl;
+ }
+
+ // Constructor.
+ //
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @name Constructors" << endl
+ << " */" << endl
+ << "//@{" << endl
+ << endl;
+ }
+ else
+ {
+ os << "// Constructors." << endl
+ << "//" << endl;
+ }
+
+ // default c-tor
+ //
+ if (options.value<CLI::generate_default_ctor> ())
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Default constructor." << endl
+ << " *" << endl
+ << " * Note that this constructor leaves the element " <<
+ "value" << endl
+ << " * uninitialized." << endl
+ << " */" << endl;
+ }
+
+ os << name << " ();"
+ << endl;
+ }
+
+ // c-tor (value)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from an initializer " <<
+ "for the element" << endl
+ << " * value." << endl
+ << " *" << endl
+ << " * @param x Element value." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << type << "& x);"
+ << endl;
+
+
+ // If the element value is a complex type (has elements,
+ // attributes, or wildcards) then also generate the auto_ptr
+ // version. If we are generating polymorphic code then we
+ // also need to provide auto_ptr version for simple, non-
+ // fundamental values.
+ //
+ //
+ if (!simple || (polymorphic && !fund))
+ {
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from an initializer " <<
+ "for" << endl
+ << " * the element value (auto_ptr version)." << endl
+ << " *" << endl
+ << " * @param p Element value to use." << endl
+ << " *" << endl
+ << " * This constructor will try to use the passed " <<
+ "value directly" << endl
+ << " * instead of making a copy." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (::std::auto_ptr< " << type << " > p);"
+ << endl;
+ }
+
+ if (!options.value<CLI::suppress_parsing> ())
+ {
+ // c-tor (xercesc::DOMElement)
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Create an instance from a DOM element." << endl
+ << " *" << endl
+ << " * @param e A DOM element to extract the data from." << endl
+ << " * @param f Flags to create the new instance with." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << xerces_ns << "::DOMElement& e, " <<
+ flags_type << " f = 0);"
+ << endl;
+ }
+
+ // copy c-tor
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Copy constructor." << endl
+ << " *" << endl
+ << " * @param x An instance to make a copy of." << endl
+ << " * @param f Flags to create the copy with." << endl
+ << " *" << endl
+ << " * For polymorphic object models use the @c _clone " <<
+ "function instead." << endl
+ << " */" << endl;
+ }
+
+ os << name << " (const " << name << "& x, " <<
+ flags_type << " f = 0);"
+ << endl;
+
+ // _clone
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Copy the instance polymorphically." << endl
+ << " *" << endl
+ << " * @param f Flags to create the copy with." << endl
+ << " * @return A pointer to the dynamically allocated copy." << endl
+ << " *" << endl
+ << " * This function ensures that the dynamic type of the " <<
+ "instance is" << endl
+ << " * used for copying and should be used for polymorphic " <<
+ "object" << endl
+ << " * models instead of the copy constructor." << endl
+ << " */" << endl;
+ }
+
+ os << "virtual " << name << "*" << endl
+ << "_clone (" << flags_type << " f = 0) const;"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "//@}" << endl
+ << endl;
+ }
+
+ // Element name and namespace accessors.
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @name Element name and namespace" << endl
+ << " *" << endl
+ << " * @brief Accessor functions for the element name " <<
+ "and namespace." << endl
+ << " */" << endl
+ << "//@{" << endl
+ << endl;
+ }
+ else
+ {
+ os << "// Element name and namespace." << endl
+ << "//" << endl;
+ }
+
+ SemanticGraph::Context& ec (e.context ());
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return the element name (static function)." << endl
+ << " *" << endl
+ << " * @return A read-only string reference containing " <<
+ "the element" << endl
+ << " * name." << endl
+ << " */" << endl;
+ }
+ os << "static const " << string_type << "&" << endl
+ << ec.get<String> ("element-name") << " ();"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return the element namespace (static " <<
+ "function)." << endl
+ << " *" << endl
+ << " * @return A read-only string reference containing " <<
+ "the element" << endl
+ << " * namespace." << endl
+ << " */" << endl;
+ }
+ os << "static const " << string_type << "&" << endl
+ << ec.get<String> ("element-ns") << " ();"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return the element name." << endl
+ << " *" << endl
+ << " * @return A read-only string reference containing " <<
+ "the element" << endl
+ << " * name." << endl
+ << " */" << endl;
+ }
+ os << "virtual const " << string_type << "&" << endl
+ << "_name () const;"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Return the element namespace." << endl
+ << " *" << endl
+ << " * @return A read-only string reference containing " <<
+ "the element" << endl
+ << " * namespace." << endl
+ << " */" << endl;
+ }
+ os << "virtual const " << string_type << "&" << endl
+ << "_namespace () const;"
+ << endl;
+
+ if (doxygen)
+ {
+ os << "//@}" << endl
+ << endl;
+ }
+
+ // d-tor
+ //
+ if (doxygen)
+ {
+ os << "/**" << endl
+ << " * @brief Destructor." << endl
+ << " */" << endl;
+ }
+
+ os << "virtual " << endl
+ << "~" << name << " ();"
+ << endl;
+
+ // Data member.
+ //
+
+ if (doxygen)
+ os << "//@cond" << endl
+ << endl;
+
+ os << "protected:" << endl
+ << "::xsd::cxx::tree::one< " << type << " > " <<
+ emember (e) << ";"
+ << "static const " << string_type << " " <<
+ ec.get<String> ("element-name-member") << ";"
+ << "static const " << string_type << " " <<
+ ec.get<String> ("element-ns-member") << ";";
+
+ if (doxygen)
+ os << endl
+ << "//@endcond" << endl;
+
+ os << "};";
+ }
+
+ private:
+ Traversal::Belongs belongs_;
+ MemberTypeName type_name_;
+ };
+ }
+
+ Void
+ generate_tree_header (Context& ctx)
+ {
+ if (ctx.generate_xml_schema)
+ {
+ ctx.os << "#include <xsd/cxx/tree/exceptions.hxx>" << endl
+ << "#include <xsd/cxx/tree/elements.hxx>" << endl
+ << "#include <xsd/cxx/tree/types.hxx>" << endl
+ << endl;
+
+ if (!ctx.options.value<CLI::suppress_parsing> () ||
+ ctx.options.value<CLI::generate_serialization> ())
+ {
+ ctx.os << "#include <xsd/cxx/xml/error-handler.hxx>" << endl
+ << endl;
+ }
+
+ if (!ctx.options.value<CLI::suppress_parsing> () ||
+ ctx.options.value<CLI::generate_serialization> ())
+ {
+ ctx.os << "#include <xsd/cxx/xml/dom/auto-ptr.hxx>" << endl
+ << endl;
+ }
+
+ Boolean element_map (ctx.options.value<CLI::generate_element_map> ());
+
+ if (element_map)
+ ctx.os << "#include <xsd/cxx/tree/element-map.hxx>" << endl
+ << endl;
+
+ // I need to include all the "optional" headers here (instead of
+ // later in the individual generators for each feature because
+ // those headers provide implementation for the fundamental types.
+ //
+ if (!ctx.options.value<CLI::suppress_parsing> ())
+ {
+ ctx.os << "#include <xsd/cxx/tree/parsing.hxx>" << endl;
+
+ Traversal::Schema schema;
+ Traversal::Names names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ FundIncludes type (ctx, "parsing");
+
+ schema >> names >> ns >> ns_names >> type;
+
+ schema.dispatch (ctx.schema_root);
+
+ if (element_map)
+ ctx.os << "#include <xsd/cxx/tree/parsing/element-map.txx>" <<
+ endl;
+
+ ctx.os << endl;
+ }
+
+ if (ctx.options.value<CLI::generate_serialization> ())
+ {
+ ctx.os << "#include <xsd/cxx/xml/dom/serialization-header.hxx>" << endl
+ << "#include <xsd/cxx/tree/serialization.hxx>" << endl;
+
+ Traversal::Schema schema;
+ Traversal::Names names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+ FundIncludes type (ctx, "serialization");
+
+ schema >> names >> ns >> ns_names >> type;
+
+ schema.dispatch (ctx.schema_root);
+
+ if (element_map)
+ ctx.os << "#include <xsd/cxx/tree/serialization/element-map.txx>" <<
+ endl;
+
+ ctx.os << endl;
+ }
+
+ if (ctx.options.value<CLI::generate_ostream> ())
+ {
+ ctx.os << "#include <xsd/cxx/tree/std-ostream-operators.hxx>" << endl
+ << endl;
+ }
+
+ Streams const& ist (ctx.options.value<CLI::generate_insertion> ());
+ if (!ist.empty ())
+ {
+ for (Streams::ConstIterator i (ist.begin ()); i != ist.end (); ++i)
+ {
+ if (*i == "ACE_OutputCDR")
+ ctx.os << "#include <xsd/cxx/tree/ace-cdr-stream-insertion.hxx>"
+ << endl;
+ else if (*i == "XDR")
+ ctx.os << "#include <xsd/cxx/tree/xdr-stream-insertion.hxx>"
+ << endl;
+ }
+
+ ctx.os << "#include <xsd/cxx/tree/stream-insertion.hxx>" << endl
+ << endl;
+ }
+
+ Streams const& est (ctx.options.value<CLI::generate_extraction> ());
+ if (!est.empty ())
+ {
+ for (Streams::ConstIterator i (est.begin ()); i != est.end (); ++i)
+ {
+ if (*i == "ACE_InputCDR")
+ ctx.os << "#include <xsd/cxx/tree/ace-cdr-stream-extraction.hxx>"
+ << endl;
+ else if (*i == "XDR")
+ ctx.os << "#include <xsd/cxx/tree/xdr-stream-extraction.hxx>"
+ << endl;
+ }
+
+ ctx.os << "#include <xsd/cxx/tree/stream-extraction.hxx>" << endl
+ << endl;
+ }
+
+ // Emit fundamental types.
+ //
+ {
+ Traversal::Schema schema;
+ Traversal::Names names;
+ FundamentalNamespace ns (ctx);
+
+ schema >> names >> ns;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+ else
+ {
+ Boolean inline_ (ctx.options.value<CLI::generate_inline> ());
+
+ ctx.os << "#include <memory> // std::auto_ptr" << endl
+ << "#include <algorithm> // std::binary_search" << endl
+ << endl;
+
+ ctx.os << "#include <xsd/cxx/tree/exceptions.hxx>" << endl
+ << "#include <xsd/cxx/tree/elements.hxx>" << endl
+ << "#include <xsd/cxx/tree/containers.hxx>" << endl
+ << "#include <xsd/cxx/tree/list.hxx>" << endl
+ << endl;
+
+ if (!ctx.options.value<CLI::suppress_parsing> ())
+ {
+ ctx.os << "#include <xsd/cxx/xml/dom/parsing-header.hxx>" << endl
+ << endl;
+ }
+
+ if (ctx.options.value<CLI::generate_wildcard> ())
+ {
+ if (ctx.options.value<CLI::suppress_parsing> () ||
+ !ctx.options.value<CLI::generate_serialization> ())
+ ctx.os << "#include <xsd/cxx/xml/dom/auto-ptr.hxx>" << endl;
+
+ ctx.os << "#include <xsd/cxx/tree/containers-wildcard.hxx>" << endl
+ << endl;
+ }
+
+ if (!ctx.options.value<CLI::generate_extraction> ().empty ())
+ ctx.os << "#include <xsd/cxx/tree/istream-fwd.hxx>" << endl
+ << endl;
+
+ // Emit header includes.
+ //
+ {
+ if (inline_)
+ {
+ ctx.os << "#ifndef XSD_DONT_INCLUDE_INLINE" << endl
+ << "#define XSD_DONT_INCLUDE_INLINE" << endl
+ << endl;
+ }
+
+ Traversal::Schema schema;
+ Includes includes (ctx, Includes::header);
+
+ schema >> includes;
+
+ schema.dispatch (ctx.schema_root);
+
+ if (inline_)
+ {
+ ctx.os << "#undef XSD_DONT_INCLUDE_INLINE" << endl
+ << "#else" << endl
+ << endl;
+
+ schema.dispatch (ctx.schema_root);
+
+ ctx.os << "#endif // XSD_DONT_INCLUDE_INLINE" << endl
+ << endl;
+ }
+ }
+
+
+ {
+ Traversal::Schema schema;
+
+ Traversal::Sources sources;
+ Traversal::Names names_ns, names;
+
+ DocumentedNamespace ns (ctx);
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+ GlobalElement element (ctx);
+
+ schema >> sources >> schema;
+ schema >> names_ns >> ns >> names;
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ if (ctx.options.value<CLI::generate_element_type> ())
+ names >> element;
+
+ schema.dispatch (ctx.schema_root);
+ }
+
+ // Emit inline includes.
+ //
+ if (inline_)
+ {
+ ctx.os << "#ifndef XSD_DONT_INCLUDE_INLINE" << endl
+ << endl;
+
+ Traversal::Schema schema;
+ Includes ixx_includes (ctx, Includes::inline_);
+ schema >> ixx_includes;
+
+ schema.dispatch (ctx.schema_root);
+
+ ctx.os << "#endif // XSD_DONT_INCLUDE_INLINE" << endl
+ << endl;
+ }
+ }
+ }
+ }
+}
diff --git a/xsd/cxx/tree/tree-header.hxx b/xsd/cxx/tree/tree-header.hxx
new file mode 100644
index 0000000..0aadeaf
--- /dev/null
+++ b/xsd/cxx/tree/tree-header.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/tree/tree-header.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_TREE_HEADER_HXX
+#define CXX_TREE_TREE_HEADER_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ Void
+ generate_tree_header (Context&);
+ }
+}
+
+#endif // CXX_TREE_TREE_HEADER_HXX
diff --git a/xsd/cxx/tree/tree-inline.cxx b/xsd/cxx/tree/tree-inline.cxx
new file mode 100644
index 0000000..5bec713
--- /dev/null
+++ b/xsd/cxx/tree/tree-inline.cxx
@@ -0,0 +1,1025 @@
+// file : xsd/cxx/tree/tree-inline.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/tree-inline.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ struct List : Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String name (ename (l));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (l, name) && !name)
+ return;
+
+ SemanticGraph::Type& item_type (l.argumented ().type ());
+ String item_name (item_type_name (item_type));
+ String base_type (L"::xsd::cxx::tree::list< " + item_name +
+ L", " + char_type);
+
+ if (item_type.is_a<SemanticGraph::Fundamental::Double> ())
+ base_type += L", ::xsd::cxx::tree::schema_type::double_";
+ else if (item_type.is_a<SemanticGraph::Fundamental::Decimal> ())
+ base_type += L", ::xsd::cxx::tree::schema_type::decimal";
+
+ base_type += L" >";
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ // c-tor ()
+ //
+ os << inl
+ << name << "::" << endl
+ << name << " ()"
+ << "{"
+ << "}";
+
+ // c-tor (size_type, const X& x)
+ //
+ String size_type (name != L"size_type"
+ ? String (L"size_type")
+ : base_type + L"::size_type");
+
+ os << inl
+ << name << "::" << endl
+ << name << " (" << size_type << " n, const " << item_name <<
+ "& x)" << endl
+ << ": " << base_type << " (n, x)"
+ << "{"
+ << "}";
+
+ // copy c-tor ()
+ //
+ os << inl
+ << name << "::" << endl
+ << name << " (const " << name << "& o," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << any_simple_type << " (o, f, c)," << endl
+ << " " << base_type << " (o, f, c)"
+ << "{"
+ << "}";
+ }
+
+ private:
+ String
+ item_type_name (SemanticGraph::Type& t)
+ {
+ std::wostringstream o;
+
+ MemberTypeName type (*this, o);
+ type.dispatch (t);
+
+ return o.str ();
+ }
+ };
+
+
+ struct Union : Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String name (ename (u));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (u, name) && !name)
+ return;
+
+ String const& base (xs_string_type);
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ if (options.value<CLI::generate_default_ctor> ())
+ {
+ // c-tor ()
+ //
+ os << inl
+ << name << "::" << endl
+ << name << " ()" << endl
+ << ": " << base << " ()"
+ << "{"
+ << "}";
+ }
+
+ // c-tor (const char*)
+ //
+ os << inl
+ << name << "::" << endl
+ << name << " (const " << char_type << "* s)" << endl
+ << ": " << base << " (s)"
+ << "{"
+ << "}";
+
+ // c-tor (string const&)
+ //
+ os << inl
+ << name << "::" << endl
+ << name << " (const " << string_type << "& s)" << endl
+ << ": " << base << " (s)"
+ << "{"
+ << "}";
+
+ // copy c-tor ()
+ //
+ os << inl
+ << name << "::" << endl
+ << name << " (const " << name << "& o," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << base << " (o, f, c)"
+ << "{"
+ << "}";
+ }
+ };
+
+ // Enumeration
+ //
+
+ // Generate a sequence of explicit c-tor calls until we reach
+ // one of the fundamental string types that can be constructed
+ // from char literals.
+ //
+ struct CtorCallSequence: Traversal::Complex,
+ Traversal::Fundamental::Type,
+ protected virtual Context
+ {
+ CtorCallSequence (Context& c, String const& arg)
+ : Context (c), arg_ (arg), base_type_name_ (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ // This type should be ultimately string based.
+ //
+ assert (c.inherits_p ());
+
+ os << ename (c) << " (" << endl;
+
+ dispatch (c.inherits ().base ());
+
+ os << ")";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Type& t)
+ {
+ base_type_name_.dispatch (t);
+
+ os << " (" << arg_ << ")";
+ }
+
+ private:
+ String arg_;
+ BaseTypeName base_type_name_;
+ };
+
+ struct Enumeration : Traversal::Enumeration,
+ protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c), member_ (c)
+ {
+ inherits_member_ >> member_;
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String name (ename (e));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (e, name) && !name)
+ return;
+
+ Boolean string_based (false);
+ {
+ IsStringBasedType t (string_based);
+ t.dispatch (e);
+ }
+
+ Boolean enum_based (false);
+ if (string_based)
+ {
+ SemanticGraph::Enumeration* be (0);
+ IsEnumBasedType t (be);
+ t.dispatch (e);
+
+ enum_based = (be != 0);
+ }
+
+ String value;
+ if (string_based)
+ value = evalue (e);
+
+ // Get to the ultimate base and see if is a fundamental type.
+ //
+ Boolean fund_based (false);
+ SemanticGraph::Type& ult_base (ultimate_base (e));
+ {
+ IsFundamentalType t (fund_based);
+ t.dispatch (ult_base);
+ }
+
+ //
+ //
+ String base; // base type name
+ {
+ std::wostringstream o;
+
+ BaseTypeName base_type (*this, o);
+ Traversal::Inherits inherits_type (base_type);
+
+ inherits (e, inherits_type);
+ base = o.str ();
+ }
+
+ os << "// " << name << endl
+ << "// " << endl
+ << endl;
+
+ // default c-tor
+ //
+ if (options.value<CLI::generate_default_ctor> ())
+ {
+ os << inl
+ << name << "::" << endl
+ << name << " ()" << endl
+ << ": " << base << " ()"
+ << "{"
+ << "}";
+ }
+
+ // c-tor (value)
+ //
+ if (string_based)
+ {
+ os << inl
+ << name << "::" << endl
+ << name << " (" << value << " v)" << endl
+ << ": ";
+
+ // If we are enum-based then we can just use the corresponding
+ // base c-tor directly. Otherwise we will use the from-string
+ // c-tor.
+ //
+ if (enum_based)
+ os << base << " (v)";
+ else
+ {
+ CtorCallSequence t (*this, L"_xsd_" + name + L"_literals_[v]");
+ t.dispatch (e.inherits ().base ());
+ }
+
+ os << "{"
+ << "}";
+ }
+
+ // c-tor (const char*)
+ //
+ if (string_based)
+ {
+ os << inl
+ << name << "::" << endl
+ << name << " (const " << char_type << "* v)" << endl
+ << ": " << base << " (v)"
+ << "{"
+ << "}";
+ }
+
+ // c-tor (const std::string&)
+ //
+ if (string_based)
+ {
+ os << inl
+ << name << "::" << endl
+ << name << " (const " << string_type << "& v)" << endl
+ << ": " << base << " (v)"
+ << "{"
+ << "}";
+ }
+
+ // c-tor (fundamental)
+ //
+ if (fund_based)
+ {
+ os << inl
+ << name << "::" << endl
+ << name << " (";
+
+ member_.dispatch (ult_base);
+
+ os << " v)"
+ << ": " << base << " (v)"
+ << "{"
+ << "}";
+ }
+
+ // c-tor (base)
+ //
+ // If the ultimate is also our immediate base and it is a
+ // fundamental type then this c-tor clashes with c-tor
+ // (fundamental) above.
+ //
+ if (!fund_based || &ult_base != &e.inherits ().base ())
+ {
+ os << inl
+ << name << "::" << endl
+ << name << " (const ";
+
+ inherits (e, inherits_member_);
+
+ os << "& v)" << endl
+ << ": " << base << " (v)"
+ << "{"
+ << "}";
+ }
+
+ // copy c-tor
+ //
+ os << inl
+ << name << "::" << endl
+ << name << " (const " << name << "& v," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << base << " (v, f, c)"
+ << "{"
+ << "}";
+
+ // operato= (value)
+ //
+ if (string_based)
+ {
+ os << inl
+ << name << "& " << name << "::" << endl
+ << "operator= (" << value << " v)"
+ << "{"
+ << "static_cast< " << base << "& > (*this) = ";
+
+ // If we are enum-based then we can just use the corresponding
+ // base assignment directly. Otherwise we will use the from-
+ // base assignment and a from-string base c-tor.
+ //
+ if (enum_based)
+ os << "v";
+ else
+ {
+ os << endl;
+
+ CtorCallSequence t (*this, L"_xsd_" + name + L"_literals_[v]");
+ t.dispatch (e.inherits ().base ());
+ }
+
+ os << ";"
+ << endl
+ << "return *this;"
+ << "}";
+ }
+
+ os << endl;
+ }
+
+ private:
+ Traversal::Inherits inherits_member_;
+ MemberTypeName member_;
+ };
+
+ struct Member: Traversal::Member, protected virtual Context
+ {
+ Member (Context& c, String const& scope)
+ : Context (c), scope_ (scope)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m))
+ return;
+
+ String const& aname (eaname (m));
+ String const& mname (emname (m));
+ String const& member (emember (m));
+
+ Boolean fund (false);
+ {
+ IsFundamentalType t (fund);
+ t.dispatch (m.type ());
+ }
+
+ Boolean def_attr (m.default_ () &&
+ m.is_a<SemanticGraph::Attribute> () &&
+ !is_qname (m.type ()));
+
+ if (max (m) != 1)
+ {
+ // sequence
+ //
+ String container (econtainer (m));
+ String q_container (scope_ + L"::" + container);
+
+ // container const&
+ // name () const;
+ //
+ os << inl
+ << "const " << q_container << "& " << scope_ << "::" << endl
+ << aname << " () const"
+ << "{"
+ << "return this->" << member << ";"
+ << "}";
+
+ // container&
+ // name ();
+ //
+ os << inl
+ << q_container << "& " << scope_ << "::" << endl
+ << aname << " ()"
+ << "{"
+ << "return this->" << member << ";"
+ << "}";
+
+ // void
+ // name (container const&);
+ //
+ os << inl
+ << "void " << scope_ << "::" << endl
+ << mname << " (const " << container << "& s)"
+ << "{"
+ << "this->" << member << " = s;"
+ << "}";
+ }
+ else if (min (m) == 0 && !def_attr)
+ {
+ // optional
+ //
+ String type (etype (m));
+ String container (econtainer (m));
+ String q_container (scope_ + L"::" + container);
+
+ // container const&
+ // name () const;
+ //
+ os << inl
+ << "const " << q_container << "& " << scope_ << "::" << endl
+ << aname << " () const"
+ << "{"
+ << "return this->" << member << ";"
+ << "}";
+
+ // container&
+ // name ();
+ //
+ os << inl
+ << q_container << "& " << scope_ << "::" << endl
+ << aname << " ()"
+ << "{"
+ << "return this->" << member << ";"
+ << "}";
+
+ // void
+ // name (type const&);
+ //
+ os << inl
+ << "void " << scope_ << "::" << endl
+ << mname << " (const " << type << "& x)"
+ << "{"
+ << "this->" << member << ".set (x);"
+ << "}";
+
+ // void
+ // name (container const&);
+ //
+ os << inl
+ << "void " << scope_ << "::" << endl
+ << mname << " (const " << container << "& x)"
+ << "{"
+ << "this->" << member << " = x;"
+ << "}";
+
+ // void
+ // name (auto_ptr<type>);
+ //
+ if (!fund)
+ os << inl
+ << "void " << scope_ << "::" << endl
+ << mname << " (::std::auto_ptr< " << type << " > x)"
+ << "{"
+ << "this->" << member << ".set (x);"
+ << "}";
+ }
+ else
+ {
+ // one
+ //
+ String type (etype (m));
+ String q_type (scope_ + L"::" + type);
+
+ // type const&
+ // name () const;
+ //
+ os << inl
+ << "const " << q_type << "& " << scope_ << "::" << endl
+ << aname << " () const"
+ << "{"
+ << "return this->" << member << ".get ();"
+ << "}";
+
+ // Do not generate modifiers for fixed attributes.
+ //
+ if (!(def_attr && m.fixed ()))
+ {
+ // type&
+ // name ();
+ //
+ os << inl
+ << q_type << "& " << scope_ << "::" << endl
+ << aname << " ()"
+ << "{"
+ << "return this->" << member << ".get ();"
+ << "}";
+
+ // void
+ // name (type const&);
+ //
+ os << inl
+ << "void " << scope_ << "::" << endl
+ << mname << " (const " << type << "& x)"
+ << "{"
+ << "this->" << member << ".set (x);"
+ << "}";
+
+ // void
+ // name (auto_ptr<type>);
+ //
+ if (!fund)
+ os << inl
+ << "void " << scope_ << "::" << endl
+ << mname << " (::std::auto_ptr< " << type << " > x)"
+ << "{"
+ << "this->" << member << ".set (x);"
+ << "}";
+ }
+ }
+
+
+ // default_value
+ //
+ if (m.default_ () && !is_qname (m.type ()))
+ {
+ Boolean simple (true);
+
+ if (m.is_a<SemanticGraph::Element> ())
+ {
+ IsSimpleType test (simple);
+ test.dispatch (m.type ());
+ }
+
+ if (simple)
+ {
+ os << inl
+ << "const " << scope_ << "::" << etype (m) << "& " <<
+ scope_ << "::" << endl
+ << edefault_value (m) << " ()"
+ << "{"
+ << "return " << edefault_value_member (m) << ";"
+ << "}";
+ }
+ }
+ }
+
+ private:
+ String scope_;
+ };
+
+ struct Any: Traversal::Any,
+ Traversal::AnyAttribute,
+ protected virtual Context
+ {
+ Any (Context& c, String const& scope)
+ : Context (c), scope_ (scope)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ String const& aname (eaname (a));
+ String const& mname (emname (a));
+
+ String const& member (emember (a));
+
+ if (max (a) != 1)
+ {
+ // sequence
+ //
+ String container (econtainer (a));
+ String q_container (scope_ + L"::" + container);
+
+ // container const&
+ // name () const;
+ //
+ os << inl
+ << "const " << q_container << "& " << scope_ << "::" << endl
+ << aname << " () const"
+ << "{"
+ << "return this->" << member << ";"
+ << "}";
+
+ // container&
+ // name ();
+ //
+ os << inl
+ << q_container << "& " << scope_ << "::" << endl
+ << aname << " ()"
+ << "{"
+ << "return this->" << member << ";"
+ << "}";
+
+ // void
+ // name (container const&);
+ //
+ os << inl
+ << "void " << scope_ << "::" << endl
+ << mname << " (const " << container << "& s)"
+ << "{"
+ << "this->" << member << " = s;"
+ << "}";
+ }
+ else if (min (a) == 0)
+ {
+ // optional
+ //
+ String container (econtainer (a));
+ String q_container (scope_ + L"::" + container);
+
+ // container const&
+ // name () const;
+ //
+ os << inl
+ << "const " << q_container << "& " << scope_ << "::" << endl
+ << aname << " () const"
+ << "{"
+ << "return this->" << member << ";"
+ << "}";
+
+ // container&
+ // name ();
+ //
+ os << inl
+ << q_container << "& " << scope_ << "::" << endl
+ << aname << " ()"
+ << "{"
+ << "return this->" << member << ";"
+ << "}";
+
+ // void
+ // name (type const&);
+ //
+ os << inl
+ << "void " << scope_ << "::" << endl
+ << mname << " (const " << xerces_ns << "::DOMElement& e)"
+ << "{"
+ << "this->" << member << ".set (e);"
+ << "}";
+
+ // void
+ // name (type*);
+ //
+ os << inl
+ << "void " << scope_ << "::" << endl
+ << mname << " (" << xerces_ns << "::DOMElement* e)"
+ << "{"
+ << "this->" << member << ".set (e);"
+ << "}";
+
+ // void
+ // name (container const&);
+ //
+ os << inl
+ << "void " << scope_ << "::" << endl
+ << mname << " (const " << container << "& x)"
+ << "{"
+ << "this->" << member << " = x;"
+ << "}";
+ }
+ else
+ {
+ // one
+ //
+
+ // type const&
+ // name () const;
+ //
+ os << inl
+ << "const " << xerces_ns << "::DOMElement& " <<
+ scope_ << "::" << endl
+ << aname << " () const"
+ << "{"
+ << "return this->" << member << ".get ();"
+ << "}";
+
+ // type&
+ // name ();
+ //
+ os << inl
+ << xerces_ns << "::DOMElement& " << scope_ << "::" << endl
+ << aname << " ()"
+ << "{"
+ << "return this->" << member << ".get ();"
+ << "}";
+
+ // void
+ // name (type const&);
+ //
+ os << inl
+ << "void " << scope_ << "::" << endl
+ << mname << " (const " << xerces_ns << "::DOMElement& e)"
+ << "{"
+ << "this->" << member << ".set (e);"
+ << "}";
+
+ // void
+ // name (type*);
+ //
+ os << inl
+ << "void " << scope_ << "::" << endl
+ << mname << " (" << xerces_ns << "::DOMElement* e)"
+ << "{"
+ << "this->" << member << ".set (e);"
+ << "}";
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute& a)
+ {
+ String const& aname (eaname (a));
+ String const& mname (emname (a));
+
+ String const& member (emember (a));
+ String container (econtainer (a));
+ String q_container (scope_ + L"::" + container);
+
+ // container const&
+ // name () const;
+ //
+ os << inl
+ << "const " << q_container << "& " << scope_ << "::" << endl
+ << aname << " () const"
+ << "{"
+ << "return this->" << member << ";"
+ << "}";
+
+ // container&
+ // name ();
+ //
+ os << inl
+ << q_container << "& " << scope_ << "::" << endl
+ << aname << " ()"
+ << "{"
+ << "return this->" << member << ";"
+ << "}";
+
+ // void
+ // name (container const&);
+ //
+ os << inl
+ << "void " << scope_ << "::" << endl
+ << mname << " (const " << container << "& s)"
+ << "{"
+ << "this->" << member << " = s;"
+ << "}";
+ }
+
+ private:
+ String scope_;
+ };
+
+ struct Complex : Traversal::Complex, protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String name (ename (c));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (c, name) && !name)
+ return;
+
+ os << "// " << name << endl
+ << "// " << endl
+ << endl;
+
+ // Generate accessors and modifiers.
+ //
+ Any any (*this, name);
+ Member member (*this, name);
+ Traversal::Names names;
+
+ if (options.value<CLI::generate_wildcard> ())
+ names >> any;
+
+ names >> member;
+
+ Complex::names (c, names);
+
+ // dom_document accessors.
+ //
+ if (edom_document_member_p (c))
+ {
+ os << inl
+ << "const " << xerces_ns << "::DOMDocument& " <<
+ name << "::" << endl
+ << edom_document (c) << " () const"
+ << "{"
+ << "return *" << edom_document_member (c) << ";"
+ << "}";
+
+ os << inl
+ << xerces_ns << "::DOMDocument& " << name << "::" << endl
+ << edom_document (c) << " ()"
+ << "{"
+ << "return *" << edom_document_member (c) << ";"
+ << "}";
+ }
+
+ os << endl;
+ }
+ };
+
+
+ struct GlobalElement : Traversal::Element,
+ GlobalElementBase,
+ protected virtual Context
+ {
+ GlobalElement (Context& c)
+ : Context (c), GlobalElementBase (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (!doc_root_p (e))
+ return;
+
+ Boolean fund (false);
+ {
+ IsFundamentalType test (fund);
+ test.dispatch (e.type ());
+ }
+
+ String const& name (ename (e));
+
+ os << "// " << name << endl
+ << "// " << endl
+ << endl;
+
+ // Accessors/modifiers.
+ //
+ String const& type (etype (e));
+ String const& aname (eaname (e));
+ String const& mname (emname (e));
+ String const& member (emember (e));
+
+ // type const&
+ // name () const;
+ //
+ os << inl
+ << "const " << name << "::" << type << "& " << name << "::" << endl
+ << aname << " () const"
+ << "{"
+ << "return this->" << member << ".get ();"
+ << "}";
+
+ // type&
+ // name ();
+ //
+ os << inl
+ << name << "::" << type << "& " << name << "::" << endl
+ << aname << " ()"
+ << "{"
+ << "return this->" << member << ".get ();"
+ << "}";
+
+ // void
+ // name (type const&);
+ //
+ os << inl
+ << "void " << name << "::" << endl
+ << mname << " (const " << type << "& x)"
+ << "{"
+ << "return this->" << member << ".set (x);"
+ << "}";
+
+ // void
+ // name (auto_ptr<type>);
+ //
+ if (!fund)
+ {
+ os << inl
+ << "void " << name << "::" << endl
+ << mname << " (::std::auto_ptr< " << type << " > p)"
+ << "{"
+ << "return this->" << member << ".set (p);"
+ << "}";
+ }
+ }
+ };
+ }
+
+ Void
+ generate_tree_inline (Context& ctx, UnsignedLong first, UnsignedLong last)
+ {
+ // Generate includes.
+ //
+ if (ctx.options.value<CLI::generate_inline> ())
+ {
+ Traversal::Schema schema;
+ Includes includes (ctx, Includes::inline_);
+
+ schema >> includes;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ else
+ {
+ // Emit "weak" header includes that are used in the file-per-type
+ // compilation model.
+ //
+ Traversal::Schema schema;
+ Includes includes (ctx, Includes::source);
+
+ schema >> includes;
+
+ schema.dispatch (ctx.schema_root);
+ }
+
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+ Traversal::Names names_ns, names;
+ Namespace ns (ctx, first, last);
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+ GlobalElement element (ctx);
+
+ schema >> sources >> schema;
+ schema >> names_ns >> ns >> names;
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+
+ if (ctx.options.value<CLI::generate_element_type> ())
+ names >> element;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/tree/tree-inline.hxx b/xsd/cxx/tree/tree-inline.hxx
new file mode 100644
index 0000000..14cb11c
--- /dev/null
+++ b/xsd/cxx/tree/tree-inline.hxx
@@ -0,0 +1,22 @@
+// file : xsd/cxx/tree/tree-inline.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_TREE_INLINE_HXX
+#define CXX_TREE_TREE_INLINE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ Void
+ generate_tree_inline (Context&, UnsignedLong first, UnsignedLong last);
+ }
+}
+
+#endif // CXX_TREE_TREE_INLINE_HXX
diff --git a/xsd/cxx/tree/tree-source.cxx b/xsd/cxx/tree/tree-source.cxx
new file mode 100644
index 0000000..7952e38
--- /dev/null
+++ b/xsd/cxx/tree/tree-source.cxx
@@ -0,0 +1,3461 @@
+// file : xsd/cxx/tree/tree-source.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/tree-source.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cult/containers/list.hxx>
+
+#include <iostream>
+
+using std::wcerr;
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ struct List: Traversal::List, protected virtual Context
+ {
+ List (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& l)
+ {
+ String name (ename (l));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (l, name) && !name)
+ return;
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ if (!options.value<CLI::suppress_parsing> ())
+ {
+ SemanticGraph::Type& item_type (l.argumented ().type ());
+ String base (L"::xsd::cxx::tree::list< " +
+ item_type_name (item_type) + L", " + char_type);
+
+ if (item_type.is_a<SemanticGraph::Fundamental::Double> ())
+ base += L", ::xsd::cxx::tree::schema_type::double_";
+ else if (item_type.is_a<SemanticGraph::Fundamental::Decimal> ())
+ base += L", ::xsd::cxx::tree::schema_type::decimal";
+
+ base += L" >";
+
+ // c-tor (xercesc::DOMElement)
+ //
+ os << name << "::" << endl
+ << name << " (const " << xerces_ns << "::DOMElement& e," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << any_simple_type << " (e, f, c)," << endl
+ << " " << base << " (e, f, c)"
+ << "{"
+ << "}";
+
+ // c-tor (xercesc::DOMAttr)
+ //
+ os << name << "::" << endl
+ << name << " (const " << xerces_ns << "::DOMAttr& a," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << any_simple_type << " (a, f, c)," << endl
+ << " " << base << " (a, f, c)"
+ << "{"
+ << "}";
+
+ // c-tor (string const&, xercesc::DOMElement)
+ //
+ os << name << "::" << endl
+ << name << " (const " << string_type << "& s," << endl
+ << "const " << xerces_ns << "::DOMElement* e," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << any_simple_type << " (s, e, f, c)," << endl
+ << " " << base << " (s, e, f, c)"
+ << "{"
+ << "}";
+ }
+
+ // _clone
+ //
+ os << name << "* " << name << "::" << endl
+ << "_clone (" << flags_type << " f," << endl
+ << container << "* c) const"
+ << "{"
+ << "return new class " << name << " (*this, f, c);"
+ << "}";
+
+ // d-tor
+ //
+ os << name << "::" << endl
+ << "~" << name << " ()"
+ << "{"
+ << "}";
+
+ // Register with type factory map.
+ //
+ if (polymorphic && !l.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (l));
+
+ if (!options.value<CLI::suppress_parsing> ())
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::type_factory_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_type_factory_init (" << endl
+ << L << strlit (l.name ()) << "," << endl
+ << L << strlit (xml_ns_name (l)) << ");"
+ << endl;
+
+ if (options.value<CLI::generate_comparison> ())
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::comparison_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_comparison_init;"
+ << endl;
+ }
+ }
+
+ private:
+ String
+ item_type_name (SemanticGraph::Type& t)
+ {
+ std::wostringstream o;
+
+ MemberTypeName type (*this, o);
+ type.dispatch (t);
+
+ return o.str ();
+ }
+ };
+
+
+ struct Union: Traversal::Union, protected virtual Context
+ {
+ Union (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& u)
+ {
+ String name (ename (u));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (u, name) && !name)
+ return;
+
+ String const& base (xs_string_type);
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ if (!options.value<CLI::suppress_parsing> ())
+ {
+ // c-tor (xercesc::DOMElement)
+ //
+ os << name << "::" << endl
+ << name << " (const " << xerces_ns << "::DOMElement& e," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << base << " (e, f, c)"
+ << "{"
+ << "}";
+
+ // c-tor (xercesc::DOMAttr)
+ //
+ os << name << "::" << endl
+ << name << " (const " << xerces_ns << "::DOMAttr& a," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << base << " (a, f, c)"
+ << "{"
+ << "}";
+
+ // c-tor (string const&, xercesc::DOMElement)
+ //
+ os << name << "::" << endl
+ << name << " (const " << string_type << "& s," << endl
+ << "const " << xerces_ns << "::DOMElement* e," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << base << " (s, e, f, c)"
+ << "{"
+ << "}";
+ }
+
+ // _clone
+ //
+ os << name << "* " << name << "::" << endl
+ << "_clone (" << flags_type << " f," << endl
+ << container << "* c) const"
+ << "{"
+ << "return new class " << name << " (*this, f, c);"
+ << "}";
+
+ // Register with type factory map.
+ //
+ if (polymorphic && !u.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (u));
+
+ if (!options.value<CLI::suppress_parsing> ())
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::type_factory_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_type_factory_init (" << endl
+ << L << strlit (u.name ()) << "," << endl
+ << L << strlit (xml_ns_name (u)) << ");"
+ << endl;
+
+ if (options.value<CLI::generate_comparison> ())
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::comparison_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_comparison_init;"
+ << endl;
+ }
+ }
+ };
+
+
+ // Enumeration mapping.
+ //
+
+ struct EnumeratorLiteral: Traversal::Enumerator,
+ protected virtual Context
+ {
+ EnumeratorLiteral (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ os << L << strlit (e.name ());
+ }
+ };
+
+
+ //
+ //
+ struct LiteralInfo
+ {
+ LiteralInfo (String const& value, String const& name)
+ : value_ (value), name_ (name)
+ {
+ }
+
+ String value_;
+ String name_;
+ };
+
+ Boolean
+ operator< (LiteralInfo const& x, LiteralInfo const& y)
+ {
+ return x.value_ < y.value_;
+ }
+
+ typedef Cult::Containers::List<LiteralInfo> LiteralInfoList;
+
+
+ // Populate LiteralInfoList
+ //
+ struct EnumeratorLiteralInfo: Traversal::Enumerator,
+ protected virtual Context
+
+ {
+ EnumeratorLiteralInfo (Context& c, LiteralInfoList& list)
+ : Context (c), list_ (list)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ list_.push_back (LiteralInfo (e.name (), ename (e)));
+ }
+
+ private:
+ LiteralInfoList& list_;
+ };
+
+
+ struct Enumeration: Traversal::Enumeration, protected virtual Context
+ {
+ Enumeration (Context& c)
+ : Context (c), enumerator_literal_ (c)
+ {
+ names_enumerator_literal_ >> enumerator_literal_;
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ String name (ename (e));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (e, name) && !name)
+ return;
+
+ Boolean string_based (false);
+ {
+ IsStringBasedType t (string_based);
+ t.dispatch (e);
+ }
+
+ SemanticGraph::Enumeration* be (0);
+ Boolean enum_based (false);
+ if (string_based)
+ {
+ IsEnumBasedType t (be);
+ t.dispatch (e);
+
+ enum_based = (be != 0);
+ }
+
+ String value;
+ if (string_based)
+ value = evalue (e);
+
+ UnsignedLong enum_count (0);
+
+ for (Type::NamesIterator i (e.names_begin ()), end (e.names_end ());
+ i != end; ++i)
+ ++enum_count;
+
+ String base; // base type name
+ {
+ std::wostringstream o;
+
+ BaseTypeName base_type (*this, o);
+ Traversal::Inherits inherits_type (base_type);
+
+ inherits (e, inherits_type);
+ base = o.str ();
+ }
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ if (!options.value<CLI::suppress_parsing> ())
+ {
+ // c-tor (xercesc::DOMElement)
+ //
+ os << name << "::" << endl
+ << name << " (const " << xerces_ns << "::DOMElement& e," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << base << " (e, f, c)"
+ << "{";
+
+ if (string_based)
+ os << "_xsd_" << name << "_convert ();";
+
+ os << "}";
+
+
+ // c-tor (xercesc::DOMAttr)
+ //
+ os << name << "::" << endl
+ << name << " (const " << xerces_ns << "::DOMAttr& a," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << base << " (a, f, c)"
+ << "{";
+
+ if (string_based)
+ {
+ os << "_xsd_" << name << "_convert ();";
+ }
+
+ os << "}";
+
+
+ // c-tor (string const&, xercesc::DOMElement)
+ //
+ os << name << "::" << endl
+ << name << " (const " << string_type << "& s," << endl
+ << "const " << xerces_ns << "::DOMElement* e," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << base << " (s, e, f, c)"
+ << "{";
+
+ if (string_based)
+ {
+ os << "_xsd_" << name << "_convert ();";
+ }
+
+ os << "}";
+ }
+
+ // _clone
+ //
+ os << name << "* " << name << "::" << endl
+ << "_clone (" << flags_type << " f," << endl
+ << container << "* c) const"
+ << "{"
+ << "return new class " << name << " (*this, f, c);"
+ << "}";
+
+ // convert
+ //
+ // @@ TODO: expected list
+ //
+ if (string_based)
+ {
+ String i_name (L"_xsd_" + name + L"_indexes_");
+
+ os << name << "::" << value << " " <<
+ name << "::" << endl
+ << "_xsd_" << name << "_convert () const"
+ << "{"
+ << "::xsd::cxx::tree::enum_comparator< " << char_type <<
+ " > c (_xsd_" << name << "_literals_);"
+ << "const " << value << "* i (::std::lower_bound (" << endl
+ << i_name << "," << endl
+ << i_name << " + " << enum_count << "," << endl
+ << "*this," << endl
+ << "c));"
+ << endl
+ << "if (i == " << i_name << " + " << enum_count << " || " <<
+ "_xsd_" << name << "_literals_[*i] != *this)"
+ << "{"
+ << "throw ::xsd::cxx::tree::unexpected_enumerator < " <<
+ char_type << " > (*this);"
+ << "}"
+ << "return *i;"
+ << "}";
+ }
+
+ // literals and indexes
+ //
+ if (string_based)
+ {
+ if (enum_based)
+ {
+ os << "const " << char_type << "* const* " << name << "::" << endl
+ << "_xsd_" << name << "_literals_ = " <<
+ fq_name (*be) << "::_xsd_" << ename (*be) << "_literals_;"
+ << endl;
+ }
+ else
+ {
+ os << "const " << char_type << "* const " << name << "::" << endl
+ << "_xsd_" << name << "_literals_[" << enum_count << "] ="
+ << "{";
+
+ names<Enumeration> (
+ e, names_enumerator_literal_, 0, 0, 0, &Enumeration::comma);
+
+ os << "};";
+ }
+
+
+ LiteralInfoList l;
+ {
+ EnumeratorLiteralInfo enumerator (*this, l);
+ Traversal::Names names_enumerator (enumerator);
+ names (e, names_enumerator);
+ }
+
+ l.sort ();
+
+ os << "const " << name << "::" << value << " " <<
+ name << "::" << endl
+ << "_xsd_" << name << "_indexes_[" << enum_count << "] ="
+ << "{";
+
+ String fq_name (ns_scope + L"::" + name);
+
+ for (LiteralInfoList::Iterator
+ b (l.begin ()), i (b), end (l.end ()); i != end; ++i)
+ {
+ if (i != b)
+ os << "," << endl;
+
+ os << fq_name << "::" << i->name_;
+ }
+
+ os << "};";
+ }
+
+ // Register with type factory map.
+ //
+ if (polymorphic && !e.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (e));
+
+ if (!options.value<CLI::suppress_parsing> ())
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::type_factory_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_type_factory_init (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (xml_ns_name (e)) << ");"
+ << endl;
+
+ if (options.value<CLI::generate_comparison> ())
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::comparison_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_comparison_init;"
+ << endl;
+ }
+ }
+
+ virtual Void
+ comma (Type&)
+ {
+ os << "," << endl;
+ }
+
+ private:
+ Traversal::Names names_enumerator_literal_;
+ EnumeratorLiteral enumerator_literal_;
+
+ };
+
+ //
+ //
+ struct Member: Traversal::Member, protected virtual Context
+ {
+ Member (Context& c, String const& scope)
+ : Context (c), scope_ (scope)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m))
+ return;
+
+ // default_value
+ //
+ if (m.default_ () && !is_qname (m.type ()))
+ {
+ SemanticGraph::Type& t (m.type ());
+ Boolean simple (true);
+
+ if (m.is_a<SemanticGraph::Element> ())
+ {
+ IsSimpleType test (simple);
+ test.dispatch (t);
+ }
+
+ if (simple)
+ {
+ Boolean fund (false);
+ {
+ IsFundamentalType test (fund);
+ test.dispatch (t);
+ }
+
+ String type (etype (m));
+ String q_type (scope_ + L"::" + type);
+
+ if (fund)
+ {
+ String ftype;
+ {
+ std::wostringstream o;
+ MemberTypeName test (*this, o);
+ test.dispatch (t);
+ ftype = o.str ();
+ }
+
+ os << "const " << q_type << " " << scope_ << "::" <<
+ edefault_value_member (m) << " (" << endl
+ << "::xsd::cxx::tree::traits< " << ftype << ", " <<
+ char_type;
+
+ if (t.is_a<SemanticGraph::Fundamental::Double> ())
+ os << ", ::xsd::cxx::tree::schema_type::double_";
+ else if (t.is_a<SemanticGraph::Fundamental::Decimal> ())
+ os << ", ::xsd::cxx::tree::schema_type::decimal";
+
+ os << " >::create (" << endl
+ << string_type << " (" << L << strlit (m.value ()) <<
+ "), 0, 0, 0));"
+ << endl;
+ }
+ else
+ {
+ os << "const " << q_type << " " << scope_ << "::" <<
+ edefault_value_member (m) << " (" << endl
+ << string_type << " (" << L << strlit (m.value ()) <<
+ "), 0, 0, 0);"
+ << endl;
+ }
+ }
+ }
+ }
+
+ private:
+ String scope_;
+ };
+
+
+ struct Element: Traversal::Element, protected virtual Context
+ {
+ Element (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (skip (e))
+ return;
+
+ String const& member (emember (e));
+
+ String tr (etraits (e)); // traits type name
+ String type (etype (e));
+
+ // Check if we need to handle xsi:type and substitution groups.
+ // If this element's type is anonymous or mapped to a fundamental
+ // C++ type then we don't need to do anything. Note that if the
+ // type is anonymous then it can't be derived from which makes it
+ // impossible to substitute or dynamically-type with xsi:type.
+ //
+ SemanticGraph::Type& t (e.type ());
+
+
+ Boolean fund (false);
+ {
+ IsFundamentalType traverser (fund);
+ traverser.dispatch (t);
+ }
+
+ Boolean poly (
+ !fund && polymorphic && !t.context ().count ("anonymous"));
+
+ os << "// " << comment (e.name ()) << endl
+ << "//" << endl;
+
+ if (poly)
+ {
+ // aCC cannot handle an inline call to type_factory_map_instance.
+ //
+ os << "{"
+ << "::xsd::cxx::tree::type_factory_map< " << char_type <<
+ " >& tfm (" << endl
+ << "::xsd::cxx::tree::type_factory_map_instance< 0, " <<
+ char_type << " > ());"
+ << endl
+ << "::std::auto_ptr< ::xsd::cxx::tree::type > tmp (" << endl
+ << "tfm.create (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << (
+ e.qualified ()
+ ? strlit (e.namespace_ ().name ())
+ : String ("\"\"")) <<
+ "," << endl
+ << "&::xsd::cxx::tree::factory_impl< " << type << " >," << endl
+ << (e.global () ? "true" : "false") << ", " <<
+ (e.qualified () ? "true" : "false") << ", " <<
+ "i, n, f, this));"
+ << endl
+ << "if (tmp.get () != 0)"
+ << "{";
+ }
+ else
+ {
+ if (e.qualified () && e.namespace_ ().name ())
+ {
+ os << "if (n.name () == " << L << strlit (e.name ()) << " && " <<
+ "n.namespace_ () == " << L <<
+ strlit (e.namespace_ ().name ()) << ")"
+ << "{";
+ }
+ else
+ {
+ os << "if (n.name () == " << L << strlit (e.name ()) << " && " <<
+ "n.namespace_ ().empty ())"
+ << "{";
+ }
+
+ if (!fund)
+ {
+ os << "::std::auto_ptr< " << type << " > r (" << endl
+ << tr << "::create (i, f, this));"
+ << endl;
+ }
+ }
+
+
+ // Checks. Disabled at the moment since they make it impossible to
+ // parse valid instances where the same element is used in both
+ // base and derived types. See the cxx/tree/name-clash/inheritance
+ // test for details.
+ //
+ //
+ if (max (e) != 1)
+ {
+ // sequence
+ //
+ }
+ else if (min (e) == 0)
+ {
+ // optional
+ //
+ os << "if (!this->" << member << ")"
+ << "{";
+ }
+ else
+ {
+ // one
+ //
+ os << "if (!" << member << ".present ())"
+ << "{";
+ }
+
+
+ if (poly || !fund)
+ {
+ if (poly)
+ {
+ // Cast to static type.
+ //
+ os << "::std::auto_ptr< " << type << " > r (" << endl
+ << "dynamic_cast< " << type << "* > (tmp.get ()));"
+ << endl
+ << "if (r.get ())" << endl
+ << "tmp.release ();"
+ << "else" << endl
+ << "throw ::xsd::cxx::tree::not_derived< " << char_type <<
+ " > ();"
+ << endl;
+ }
+
+ if (max (e) != 1)
+ {
+ // sequence
+ //
+ os << "this->" << member << ".push_back (r);";
+ }
+ else if (min (e) == 0)
+ {
+ // optional
+ //
+ os << "this->" << member << ".set (r);";
+ }
+ else
+ {
+ // one
+ //
+ os << "this->" << member << ".set (r);";
+ }
+ }
+ else
+ {
+ if (max (e) != 1)
+ {
+ // sequence
+ //
+ os << "this->" << member << ".push_back (" << tr <<
+ "::create (i, f, this));";
+ }
+ else if (min (e) == 0)
+ {
+ // optional
+ //
+ os << "this->" << member << ".set (" << tr <<
+ "::create (i, f, this));";
+ }
+ else
+ {
+ // one
+ //
+ os << "this->" << member << ".set (" << tr <<
+ "::create (i, f, this));";
+ }
+ }
+
+ os << "continue;";
+
+ // End of check block.
+ //
+ if (max (e) != 1)
+ {
+ // sequence
+ //
+ }
+ else if (min (e) == 0)
+ {
+ // optional
+ //
+ os << "}";
+ }
+ else
+ {
+ // one
+ //
+ os << "}";
+ }
+
+ os << "}"; // if block
+
+ if (poly)
+ os << "}";
+ }
+ };
+
+ struct ElementTest : Traversal::Element, protected virtual Context
+ {
+ ElementTest (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (skip (e))
+ return;
+
+ if (max (e) == 1 && min (e) == 1)
+ {
+ // one
+ //
+ os << "if (!" << emember (e) << ".present ())"
+ << "{"
+ << "throw ::xsd::cxx::tree::expected_element< " <<
+ char_type << " > (" << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << (e.qualified ()
+ ? strlit (e.namespace_ ().name ())
+ : String ("\"\"")) << ");"
+ << "}";
+ }
+ }
+ };
+
+ struct Any: Traversal::Any, protected virtual Context
+ {
+ Any (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ String const& member (emember (a));
+
+ String const& ns (a.definition_namespace ().name ());
+ String const& dom_doc (
+ edom_document (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ())));
+
+ os << "// " << ename (a) << endl
+ << "//" << endl
+ << "if (";
+
+ for (SemanticGraph::Any::NamespaceIterator i (a.namespace_begin ()),
+ e (a.namespace_end ()); i != e;)
+ {
+ if (*i == L"##any")
+ {
+ os << "true";
+ }
+ else if (*i == L"##other")
+ {
+ if (ns)
+ {
+ // Note that here I assume that ##other does not include
+ // unqualified names in a schema with target namespace.
+ // This is not what the spec says but that seems to be
+ // the consensus.
+ //
+ os << "(!n.namespace_ ().empty () && " <<
+ "n.namespace_ () != " << L << strlit (ns) << ")";
+ }
+ else
+ os << "!n.namespace_ ().empty ()";
+ }
+ else if (*i == L"##local")
+ {
+ os << "n.namespace_ ().empty ()";
+ }
+ else if (*i == L"##targetNamespace")
+ {
+ os << "n.namespace_ () == " << L << strlit (ns);
+ }
+ else
+ {
+ os << "n.namespace_ () == " << L << strlit (*i);
+ }
+
+ if (++i != e)
+ os << " ||" << endl;
+ }
+
+ os << ")"
+ << "{";
+
+
+ // Checks.
+ //
+ //
+ if (max (a) != 1)
+ {
+ // sequence
+ //
+ }
+ else if (min (a) == 0)
+ {
+ // optional
+ //
+ os << "if (!this->" << member << ")"
+ << "{";
+ }
+ else
+ {
+ // one
+ //
+ os << "if (!" << member << ".present ())"
+ << "{";
+ }
+
+ os << xerces_ns << "::DOMElement* r (" << endl
+ << "static_cast< " << xerces_ns << "::DOMElement* > (" << endl
+ << "this->" << dom_doc << " ().importNode (" << endl
+ << "const_cast< " << xerces_ns << "::DOMElement* > (&i), true)));";
+
+ if (max (a) != 1)
+ {
+ // sequence
+ //
+ os << "this->" << member << " .push_back (r);";
+ }
+ else if (min (a) == 0)
+ {
+ // optional
+ //
+ os << "this->" << member << ".set (r);";
+ }
+ else
+ {
+ // one
+ //
+ os << "this->" << member << ".set (r);";
+ }
+
+ os << "continue;";
+
+ // End of check block.
+ //
+ if (max (a) != 1)
+ {
+ // sequence
+ //
+ }
+ else if (min (a) == 0)
+ {
+ // optional
+ //
+ os << "}";
+ }
+ else
+ {
+ // one
+ //
+ os << "}";
+ }
+
+ os << "}"; // if block
+ }
+ };
+
+ struct AnyTest : Traversal::Any, protected virtual Context
+ {
+ AnyTest (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ if (max (a) == 1 && min (a) == 1)
+ {
+ // one
+ //
+ os << "if (!" << emember (a) << ".present ())"
+ << "{"
+ << "throw ::xsd::cxx::tree::expected_element< " <<
+ char_type << " > (" << endl
+ << L << "\"*\"," << endl
+ << L << strlit (*a.namespace_begin ()) << ");"
+ << "}";
+ }
+ }
+ };
+
+ struct Attribute : Traversal::Attribute, protected virtual Context
+ {
+ Attribute (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ String const& member (emember (a));
+
+ String const& tr (etraits (a)); // traits type name
+
+ if (a.qualified () && a.namespace_ ().name ())
+ {
+ os << "if (n.name () == " << L << strlit (a.name ()) << " && " <<
+ "n.namespace_ () == " << L <<
+ strlit (a.namespace_ ().name ()) << ")"
+ << "{";
+ }
+ else
+ {
+ os << "if (n.name () == " << L << strlit (a.name ()) << " && " <<
+ "n.namespace_ ().empty ())"
+ << "{";
+ }
+
+ Boolean fund (false);
+ {
+ IsFundamentalType traverser (fund);
+ traverser.dispatch (a.type ());
+ }
+
+ if (fund)
+ {
+ os << "this->" << member << ".set (" << tr <<
+ "::create (i, f, this));";
+ }
+ else
+ {
+ String type (etype (a));
+
+ os << "::std::auto_ptr< " << type << " > r (" << endl
+ << tr << "::create (i, f, this));"
+ << endl
+ << "this->" << member << ".set (r);";
+ }
+
+ os << "continue;"
+ << "}";
+
+ }
+ };
+
+ struct AnyAttribute: Traversal::AnyAttribute, protected virtual Context
+ {
+ AnyAttribute (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ String const& member (emember (a));
+
+ String const& ns (a.definition_namespace ().name ());
+ String const& dom_doc (
+ edom_document (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ())));
+
+ os << "// " << ename (a) << endl
+ << "//" << endl
+ << "if (";
+
+ // Note that we need to filter out namespaces for xmlns and
+ // xsi.
+ //
+ for (SemanticGraph::Any::NamespaceIterator i (a.namespace_begin ()),
+ e (a.namespace_end ()); i != e;)
+ {
+ if (*i == L"##any")
+ {
+ os << "(n.namespace_ () != " <<
+ "::xsd::cxx::xml::bits::xmlns_namespace< " << char_type <<
+ " > () &&" << endl
+ << "n.namespace_ () != " <<
+ "::xsd::cxx::xml::bits::xsi_namespace< " << char_type <<
+ " > ())";
+ }
+ else if (*i == L"##other")
+ {
+ if (ns)
+ {
+ // Note that here I assume that ##other does not include
+ // unqualified names in a schema with target namespace.
+ // This is not what the spec says but that seems to be
+ // the consensus.
+ //
+ os << "(!n.namespace_ ().empty () &&" << endl
+ << "n.namespace_ () != " << L << strlit (ns) << " &&" <<endl
+ << "n.namespace_ () != " <<
+ "::xsd::cxx::xml::bits::xmlns_namespace< " << char_type <<
+ " > () &&" << endl
+ << "n.namespace_ () != " <<
+ "::xsd::cxx::xml::bits::xsi_namespace< " << char_type <<
+ " > ())";
+ }
+ else
+ os << "(!n.namespace_ ().empty () &&" << endl
+ << "n.namespace_ () != " <<
+ "::xsd::cxx::xml::bits::xmlns_namespace< " << char_type <<
+ " > () &&" << endl
+ << "n.namespace_ () != " <<
+ "::xsd::cxx::xml::bits::xsi_namespace< " << char_type <<
+ " > ())";
+ }
+ else if (*i == L"##local")
+ {
+ os << "n.namespace_ ().empty ()";
+ }
+ else if (*i == L"##targetNamespace")
+ {
+ os << "n.namespace_ () == " << L << strlit (ns);
+ }
+ else
+ {
+ os << "n.namespace_ () == " << L << strlit (*i);
+ }
+
+ if (++i != e)
+ os << " ||" << endl;
+ }
+
+ os << ")"
+ << "{"
+ << xerces_ns << "::DOMAttr* r (" << endl
+ << "static_cast< " << xerces_ns << "::DOMAttr* > (" << endl
+ << "this->" << dom_doc << " ().importNode (" << endl
+ << "const_cast< " << xerces_ns << "::DOMAttr* > (&i), true)));"
+ << "this->" << member << " .insert (r);"
+ << "continue;"
+ << "}";
+ }
+ };
+
+
+ struct AttributeTest : Traversal::Attribute, protected virtual Context
+ {
+ AttributeTest (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& a)
+ {
+ String const& member (emember (a));
+
+ if (!a.optional () || a.default_ ())
+ {
+ os << "if (!" << member << ".present ())"
+ << "{";
+
+ if (a.default_ ())
+ {
+ Boolean fund (false);
+ {
+ IsFundamentalType traverser (fund);
+ traverser.dispatch (a.type ());
+ }
+
+ String const& tr (etraits (a)); // traits type name
+
+ if (fund || !is_qname (a.type ()))
+ {
+ os << "this->" << member << ".set (" <<
+ edefault_value (a) << " ());";
+ }
+ else
+ {
+ // Parse the default value in the context of the element.
+ //
+ os << "::std::auto_ptr< " << etype (a) << " > r (" << endl
+ << tr << "::create (" << endl
+ << string_type << " (" << L << strlit (a.value ()) <<
+ ")," << endl
+ << "&p.element (), f, this));"
+ << endl
+ << "this->" << member << ".set (r);";
+ }
+ }
+ else
+ os << "throw ::xsd::cxx::tree::expected_attribute< " <<
+ char_type << " > (" << endl
+ << L << strlit (a.name ()) << "," << endl
+ << L <<(a.qualified ()
+ ? strlit (a.namespace_ ().name ())
+ : String ("\"\"")) << ");";
+
+ os << "}";
+ }
+ }
+ };
+
+
+ //
+ //
+ struct CtorBase : Traversal::Complex,
+ Traversal::Enumeration,
+ Traversal::Type,
+ protected virtual Context
+ {
+ // If base_arg is empty then no base argument is
+ // generated.
+ //
+ CtorBase (Context& c, String const& base_arg)
+ : Context (c), base_arg_ (base_arg)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type&)
+ {
+ if (base_arg_)
+ os << base_arg_;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Enumeration&)
+ {
+ if (base_arg_)
+ os << base_arg_;
+ }
+
+ Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ Args args (*this, base_arg_);
+ args.traverse (c);
+ }
+
+ private:
+ // No need to traverse AnyAttribute since it is always mapped
+ // to a sequence.
+ //
+ struct Args : Traversal::Complex,
+ Traversal::Enumeration,
+ Traversal::Type,
+ Traversal::Any,
+ Traversal::Element,
+ Traversal::Attribute,
+ protected virtual Context
+ {
+ Args (Context& c, String const& base_arg)
+ : Context (c), base_arg_ (base_arg), first_ (true)
+ {
+ *this >> inherits_ >> *this;
+ *this >> names_ >> *this;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type&)
+ {
+ if (base_arg_)
+ os << comma () << base_arg_;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Enumeration&)
+ {
+ if (base_arg_)
+ os << comma () << base_arg_;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ if (!options.value<CLI::generate_wildcard> ())
+ return;
+
+ if (min (a) == 1 && max (a) == 1)
+ {
+ // one
+ //
+ os << comma () << ename (a);
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ if (!skip (e) && min (e) == 1 && max (e) == 1)
+ {
+ // one
+ //
+ os << comma () << ename (e);
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Attribute& a)
+ {
+ // Note that we are not including attributes with default
+ // or required fixed values here.
+ //
+ if (min (a) == 1 && !(a.fixed () && !is_qname (a.type ())))
+ {
+ // one
+ //
+ os << comma () << ename (a);
+ }
+ }
+
+ using Complex::traverse;
+
+ private:
+ String
+ comma ()
+ {
+ Boolean tmp (first_);
+ first_ = false;
+ return tmp ? "" : ",\n";
+ }
+
+ private:
+ String base_arg_;
+ Boolean first_;
+
+ Traversal::Inherits inherits_;
+ Traversal::Names names_;
+ };
+
+ String base_arg_;
+ };
+
+
+ struct CtorMember : Traversal::Element,
+ Traversal::Attribute,
+ protected virtual Context
+ {
+ CtorMember (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ if (skip (e))
+ return;
+
+ String const& member (emember (e));
+
+ if (max (e) != 1)
+ {
+ // sequence
+ //
+ os << "," << endl
+ << " " << member << " (" << flags_type << " (), this)";
+ }
+ else if (min (e) == 0)
+ {
+ // optional
+ //
+ os << "," << endl
+ << " " << member << " (" << flags_type << " (), this)";
+ }
+ else
+ {
+ // one
+ //
+ os << "," << endl
+ << " " << member << " (" << ename (e) << ", " <<
+ flags_type << " (), this)";
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Attribute& a)
+ {
+ String const& member (emember (a));
+
+ Boolean def (a.default_ () && !is_qname (a.type ()));
+
+ if (min (a) == 0 && !def)
+ {
+ // optional
+ //
+ os << "," << endl
+ << " " << member << " (" << flags_type << " (), this)";
+ }
+ else
+ {
+ // one
+ //
+
+ if (def)
+ {
+ // This is an attribute with default or fixed value. We are
+ // going to initialize it to its default value.
+ //
+ os << "," << endl
+ << " " << member << " (" <<
+ edefault_value (a) << " (), " << flags_type << " (), this)";
+ }
+ else
+ {
+ os << "," << endl
+ << " " << member << " (" << ename (a) << ", " <<
+ flags_type << " (), this)";
+ }
+ }
+ }
+ };
+
+ struct CtorAny : Traversal::Any,
+ Traversal::AnyAttribute,
+ protected virtual Context
+ {
+ CtorAny (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ String const& member (emember (a));
+ String const& dom_doc (
+ edom_document (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ())));
+
+ if (max (a) != 1)
+ {
+ // sequence
+ //
+ os << "," << endl
+ << " " << member << " (this->" << dom_doc << " ())";
+ }
+ else if (min (a) == 0)
+ {
+ // optional
+ //
+ os << "," << endl
+ << " " << member << " (this->" << dom_doc << " ())";
+ }
+ else
+ {
+ // one
+ //
+ os << "," << endl
+ << " " << member << " (" << ename (a) << ", this->" <<
+ dom_doc << " ())";
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute& a)
+ {
+ String const& dom_doc (
+ edom_document (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ())));
+
+ os << "," << endl
+ << " " << emember (a) << " (this->" << dom_doc << " ())";
+ }
+ };
+
+
+ struct CopyMember : Traversal::Member,
+ protected virtual Context
+
+ {
+ CopyMember (Context& c, String const& arg_name_)
+ : Context (c), arg_name (arg_name_)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Member& m)
+ {
+ if (skip (m))
+ return;
+
+ String const& member (emember (m));
+
+ os << "," << endl
+ << " " << member << " (" <<
+ arg_name << "." << member << ", f, this)";
+ }
+
+ private:
+ String arg_name;
+ };
+
+ struct CopyAny : Traversal::Any,
+ Traversal::AnyAttribute,
+ protected virtual Context
+
+ {
+ CopyAny (Context& c, String const& arg_name_)
+ : Context (c), arg_name (arg_name_)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ String const& member (emember (a));
+ String const& dom_doc (
+ edom_document (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ())));
+
+ os << "," << endl
+ << " " << member << " (" <<
+ arg_name << "." << member << ", this->" << dom_doc << " ())";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute& a)
+ {
+ String const& member (emember (a));
+ String const& dom_doc (
+ edom_document (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ())));
+
+ os << "," << endl
+ << " " << member << " (" <<
+ arg_name << "." << member << ", this->" << dom_doc << " ())";
+ }
+
+ private:
+ String arg_name;
+ };
+
+
+ // Element parsing c-tor initializers.
+ //
+ struct ElementCtorMember : Traversal::Member,
+ protected virtual Context
+ {
+ ElementCtorMember (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& m)
+ {
+ if (skip (m))
+ return;
+
+ String const& member (emember (m));
+
+ os << "," << endl
+ << " " << member << " (f, this)";
+ }
+ };
+
+ struct ElementCtorAny : Traversal::Any,
+ Traversal::AnyAttribute,
+ protected virtual Context
+ {
+ ElementCtorAny (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ String const& member (emember (a));
+ String const& dom_doc (
+ edom_document (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ())));
+
+ os << "," << endl
+ << " " << member << " (this->" << dom_doc << " ())";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute& a)
+ {
+ String const& member (emember (a));
+ String const& dom_doc (
+ edom_document (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ())));
+
+ os << "," << endl
+ << " " << member << " (this->" << dom_doc << " ())";
+ }
+ };
+
+
+ // Default c-tor member initializer.
+ //
+ struct DefaultCtorMemberInit : Traversal::Element,
+ Traversal::Attribute,
+ protected virtual Context
+ {
+ DefaultCtorMemberInit (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ if (skip (e))
+ return;
+
+ String const& member (emember (e));
+
+ os << "," << endl
+ << " " << member << " (" << flags_type << " (), this)";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Attribute& a)
+ {
+ String const& member (emember (a));
+
+ if (a.default_ () && !is_qname (a.type ()))
+ {
+ // This is an attribute with default or fixed value. We are
+ // going to initialize it to its default value.
+ //
+ os << "," << endl
+ << " " << member << " (" <<
+ edefault_value (a) << " (), " << flags_type << " (), this)";
+ }
+ else
+ os << "," << endl
+ << " " << member << " (" << flags_type << " (), this)";
+ }
+ };
+
+ struct DefaultCtorAnyInit : Traversal::Any,
+ Traversal::AnyAttribute,
+ protected virtual Context
+ {
+ DefaultCtorAnyInit (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ String const& member (emember (a));
+ String const& dom_doc (
+ edom_document (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ())));
+
+ os << "," << endl
+ << " " << member << " (this->" << dom_doc << " ())";
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute& a)
+ {
+ String const& member (emember (a));
+ String const& dom_doc (
+ edom_document (
+ dynamic_cast<SemanticGraph::Complex&> (a.scope ())));
+
+ os << "," << endl
+ << " " << member << " (this->" << dom_doc << " ())";
+ }
+ };
+
+ // Test whether the base has comparison operators.
+ //
+ struct HasComparisonOperator: Traversal::Fundamental::Type,
+ Traversal::List,
+ Traversal::Union,
+ Traversal::Complex,
+ Traversal::Enumeration,
+ Traversal::Member,
+ Traversal::Any,
+ Traversal::AnyAttribute,
+ protected virtual Context
+ {
+ // generate should initially be false.
+ //
+ HasComparisonOperator (Context& c, Boolean& generate)
+ : Context (c), generate_ (generate)
+ {
+ *this >> inherits_ >> *this;
+ *this >> names_ >> *this;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Fundamental::Type&)
+ {
+ // All built-in types are comparable.
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::List&)
+ {
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Union&)
+ {
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Enumeration& e)
+ {
+ Traversal::Enumeration::inherits (e);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ Complex::names (c);
+
+ if (!generate_)
+ Complex::inherits (c);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Member& m)
+ {
+ if (!skip (m))
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any&)
+ {
+ if (options.value<CLI::generate_wildcard> ())
+ generate_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute&)
+ {
+ if (options.value<CLI::generate_wildcard> ())
+ generate_ = true;
+ }
+
+ private:
+ Boolean& generate_;
+
+ Traversal::Inherits inherits_;
+ Traversal::Names names_;
+ };
+
+ //
+ //
+ struct MemberComparison : Traversal::Element,
+ Traversal::Attribute,
+ protected virtual Context
+ {
+ MemberComparison (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ if (skip (e))
+ return;
+
+ String const& aname (eaname (e));
+
+ // Check if we need to handle xsi:type and substitution groups.
+ // If this element's type is anonymous or mapped to a fundamental
+ // C++ type then we don't need to do anything. Note that if the
+ // type is anonymous then it can't be derived from which makes it
+ // impossible to substitute or dynamically-type with xsi:type.
+ //
+ SemanticGraph::Type& t (e.type ());
+ Boolean poly (polymorphic && !t.context ().count ("anonymous"));
+
+ if (poly)
+ {
+ Boolean fund (false);
+ IsFundamentalType traverser (fund);
+ traverser.dispatch (t);
+ poly = !fund;
+ }
+
+ if (!poly)
+ {
+ os << "if (!(x." << aname << " () == y." << aname << " ()))" << endl
+ << "return false;"
+ << endl;
+ }
+ else
+ {
+ // aCC cannot handle an inline call to comparison_map_instance.
+ //
+ os << "{"
+ << "::xsd::cxx::tree::comparison_map< " << char_type
+ << " >& cm (" << endl
+ << "::xsd::cxx::tree::comparison_map_instance< 0, " <<
+ char_type << " > ());"
+ << endl;
+
+ if (max (e) != 1)
+ {
+ // sequence
+ //
+ String const& scope (ename (e.scope ()));
+
+ os << scope << "::" << econtainer (e) <<
+ " a (x." << aname << " ()), b (y." << aname << " ());"
+ << endl;
+
+ os << "if (a.size () != b.size ())" << endl
+ << "return false;"
+ << endl;
+
+ os << "for (" << scope << "::" << econst_iterator (e) << endl
+ << "ai (a.begin ()), bi (b.begin ()), " <<
+ "ae (a.end ()), be (b.end ());" << endl
+ << "ai != ae; ++ai, ++bi)"
+ << "{"
+ << "if (!cm.compare (*ai, *bi))" << endl
+ << "return false;"
+ << "}";
+ }
+ else if (min (e) == 0)
+ {
+ // optional
+ //
+ String const& scope (ename (e.scope ()));
+
+ os << scope << "::" << econtainer (e) <<
+ " a (x." << aname << " ()), b (y." << aname << " ());"
+ << endl;
+
+ os << "if (!a || !b)"
+ << "{"
+ << "if (a.present () != b.present ())" << endl
+ << "return false;"
+ << "}"
+ << "else"
+ << "{"
+ << "if (!cm.compare (*a, *b))" << endl
+ << "return false;"
+ << "}";
+ }
+ else
+ {
+ // one
+ //
+ os << "if (!cm.compare (x." << aname << " (), y." <<
+ aname << " ()))" << endl
+ << "return false;";
+ }
+
+ os << "}";
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Attribute& a)
+ {
+ String const& aname (eaname (a));
+
+ os << "if (!(x." << aname << " () == y." << aname << " ()))" << endl
+ << "return false;"
+ << endl;
+ }
+ };
+
+ struct AnyComparison : Traversal::Any,
+ Traversal::AnyAttribute,
+ protected virtual Context
+ {
+ AnyComparison (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ String const& aname (eaname (a));
+
+ if (max (a) == 1 && min (a) == 1)
+ os << "if (!x." << aname << " ().isEqualNode (&y." <<
+ aname << " ()))";
+ else
+ os << "if (!(x." << aname << " () == y." << aname << " ()))";
+
+ os << endl
+ << "return false;"
+ << endl;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute& a)
+ {
+ String const& aname (eaname (a));
+
+ os << "if (!(x." << aname << " () == y." << aname << " ()))" << endl
+ << "return false;"
+ << endl;
+ }
+ };
+
+ // Check whether a type has a parse() function (i.e., has any
+ // members, recursively).
+ //
+ struct HasParseFunction: Traversal::Complex,
+ Traversal::Element,
+ Traversal::Any,
+ Traversal::Attribute,
+ Traversal::AnyAttribute,
+ protected virtual Context
+ {
+ HasParseFunction (Context& c, Boolean& has_el, Boolean& has_at)
+ : Context (c), has_el_ (has_el), has_at_ (has_at)
+ {
+ *this >> names_ >> *this;
+ *this >> inherits_ >> *this;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ names (c);
+
+ if (!(has_el_ && has_at_))
+ inherits (c);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element&)
+ {
+ has_el_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any&)
+ {
+ has_el_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Attribute&)
+ {
+ has_at_ = true;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::AnyAttribute&)
+ {
+ if (options.value<CLI::generate_wildcard> ())
+ has_at_ = true;
+ }
+
+ private:
+ Boolean& has_el_;
+ Boolean& has_at_;
+
+ Traversal::Names names_;
+ Traversal::Inherits inherits_;
+ };
+
+ //
+ //
+ struct FacetArray: Traversal::Complex, protected virtual Context
+ {
+ FacetArray (Context& c)
+ : Context (c)
+ {
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ Facets f;
+ FacetCollector col (f);
+ col.traverse (c);
+
+ for (Facets::ConstIterator i (f.begin ()); i != f.end (); ++i)
+ {
+ if (i->first == L"fractionDigits")
+ os << "{::xsd::cxx::tree::facet::fraction_digits, " <<
+ i->second << "UL}," << endl;
+ else if (i->first == L"totalDigits")
+ os << "{::xsd::cxx::tree::facet::total_digits, " <<
+ i->second << "UL}," << endl;
+ }
+ }
+
+ private:
+ typedef Cult::Containers::Map<String, String> Facets;
+
+ struct FacetCollector: Traversal::Complex
+ {
+ FacetCollector (Facets& facets)
+ : facets_ (facets)
+ {
+ *this >> inherits_ >> *this;
+ }
+
+ virtual Void
+ traverse (Type& c)
+ {
+ if (c.inherits_p ())
+ {
+ // First collect our base so that we can override its
+ // facets.
+ //
+ inherits (c);
+
+ using SemanticGraph::Restricts;
+
+ if (Restricts* r = dynamic_cast<Restricts*> (&c.inherits ()))
+ {
+ if (!r->facet_empty ())
+ {
+ Restricts::FacetIterator i (r->facet_find ("totalDigits"));
+
+ if (i != r->facet_end ())
+ facets_[i->first] = i->second;
+
+ i = r->facet_find ("fractionDigits");
+
+ if (i != r->facet_end ())
+ facets_[i->first] = i->second;
+ }
+ }
+ }
+ }
+
+ private:
+ Traversal::Inherits inherits_;
+ Facets& facets_;
+ };
+ };
+
+ //
+ //
+ struct Complex: Traversal::Complex, protected virtual Context
+ {
+ Complex (Context& c)
+ : Context (c),
+ member_name_ (c),
+ any_ (c),
+ element_ (c),
+ any_test_ (c),
+ element_test_ (c),
+ attribute_ (c),
+ attribute_test_ (c),
+ any_attribute_ (c),
+ default_ctor_any_init_ (c),
+ default_ctor_member_init_ (c),
+ ctor_any_ (c),
+ ctor_member_ (c),
+ element_ctor_any_ (c),
+ element_ctor_member_ (c),
+ comparison_any_ (c),
+ comparison_member_ (c),
+ facet_array_ (c)
+ {
+ inherits_member_ >> member_name_;
+
+ names_element_ >> element_;
+ if (options.value<CLI::generate_wildcard> ())
+ names_element_ >> any_;
+
+ names_element_test_ >> element_test_;
+ if (options.value<CLI::generate_wildcard> ())
+ names_element_test_ >> any_test_;
+
+ names_attribute_ >> attribute_;
+ names_attribute_test_ >> attribute_test_;
+ names_any_attribute_ >> any_attribute_;
+
+ default_ctor_init_names_ >> default_ctor_member_init_;
+ if (options.value<CLI::generate_wildcard> ())
+ default_ctor_init_names_ >> default_ctor_any_init_;
+
+ ctor_names_ >> ctor_member_;
+ if (options.value<CLI::generate_wildcard> ())
+ ctor_names_ >> ctor_any_;
+
+ element_ctor_names_ >> element_ctor_member_;
+ if (options.value<CLI::generate_wildcard> ())
+ element_ctor_names_ >> element_ctor_any_;
+
+ comparison_names_ >> comparison_member_;
+ if (options.value<CLI::generate_wildcard> ())
+ comparison_names_ >> comparison_any_;
+ }
+
+
+ virtual Void
+ traverse (Type& c)
+ {
+ String name (ename (c));
+
+ // If renamed name is empty then we do not need to generate
+ // anything for this type.
+ //
+ if (renamed_type (c, name) && !name)
+ return;
+
+ Boolean string_based (false);
+ {
+ IsStringBasedType t (string_based);
+ t.dispatch (c);
+ }
+
+ SemanticGraph::Enumeration* enum_base (0);
+ {
+ IsEnumBasedType t (enum_base);
+ t.dispatch (c);
+ }
+
+ Boolean facets (false);
+ String base; // base type name
+ if (c.inherits_p ())
+ {
+ // Get base name.
+ //
+ std::wostringstream o;
+
+ BaseTypeName base_type (*this, o);
+ Traversal::Inherits inherits_type (base_type);
+
+ // Cannot use inherits_none here because need the
+ // result in a string.
+ //
+ inherits (c, inherits_type);
+
+ base = o.str ();
+
+ // See if we have any facets that we need to handle.
+ //
+ using SemanticGraph::Restricts;
+ using SemanticGraph::Fundamental::Decimal;
+
+ if (Restricts* r = dynamic_cast<Restricts*> (&c.inherits ()))
+ {
+ if (!r->facet_empty () &&
+ (r->facet_find ("fractionDigits") != r->facet_end () ||
+ r->facet_find ("totalDigits") != r->facet_end ()) &&
+ ultimate_base (c).is_a<Decimal> ())
+ facets = true;
+ }
+ }
+ else
+ base = any_type;
+
+ os << "// " << name << endl
+ << "//" << endl
+ << endl;
+
+ //
+ //
+ {
+ Member member (*this, name);
+ Traversal::Names names_member (member);
+ names (c, names_member);
+ }
+
+ // facets
+ //
+ if (facets)
+ {
+ os << "static const ::xsd::cxx::tree::facet _xsd_" << name <<
+ "_facet_table[] = "
+ << "{";
+
+ facet_array_.traverse (c);
+
+ os << "{::xsd::cxx::tree::facet::none, 0UL}"
+ << "};";
+ }
+
+ // c-tors
+ //
+ Boolean generate_no_base_ctor (false);
+ {
+ GenerateWithoutBaseCtor t (generate_no_base_ctor);
+ t.traverse (c);
+ }
+
+ Boolean has_complex_non_op_args (false);
+ Boolean has_non_fund_non_op_args (false);
+ Boolean complex_non_fund_args_clash (true);
+ {
+ HasComplexNonFundNonOptArgs t (*this, true,
+ has_complex_non_op_args,
+ has_non_fund_non_op_args,
+ complex_non_fund_args_clash);
+ t.traverse (c);
+ }
+
+ // default c-tor
+ //
+ if (options.value<CLI::generate_default_ctor> ())
+ {
+ Boolean generate (false);
+ {
+ GenerateDefaultCtor t (*this, generate, generate_no_base_ctor);
+ t.traverse (c);
+ }
+
+ if (generate)
+ {
+ os << name << "::" << endl
+ << name << " ()" << endl
+ << ": " << base << " ()";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, default_ctor_init_names_);
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+ }
+ }
+
+ // c-tor (base, all-non-optional-members)
+ //
+ if (options.value<CLI::generate_from_base_ctor> ())
+ {
+ Boolean generate (false);
+ {
+ GenerateFromBaseCtor t (*this, generate);
+ t.traverse (c);
+ }
+
+ if (generate)
+ {
+ Boolean has_complex_non_op_args (false);
+ Boolean has_non_fund_non_op_args (false);
+ Boolean complex_non_fund_args_clash (true);
+ {
+ HasComplexNonFundNonOptArgs t (*this, false,
+ has_complex_non_op_args,
+ has_non_fund_non_op_args,
+ complex_non_fund_args_clash);
+ t.traverse (c);
+ }
+
+ String base_arg (
+ L"_xsd_" + ename (c.inherits ().base ()) + L"_base");
+
+ os << name << "::" << endl
+ << name << " (const ";
+ inherits (c, inherits_member_);
+ os << "& " << base_arg;
+ {
+ FromBaseCtorArg args (*this, FromBaseCtorArg::arg_type, true);
+ Traversal::Names args_names (args);
+ names (c, args_names);
+ }
+ os << ")" << endl
+ << ": " << base << " (" << base_arg << ")";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, ctor_names_);
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+
+ // If we have any complex arguments in the previous c-tor
+ // then also generate the auto_ptr version.
+ //
+ if (has_complex_non_op_args)
+ {
+ os << name << "::" << endl
+ << name << " (const ";
+ inherits (c, inherits_member_);
+ os << "& " << base_arg;
+ {
+ FromBaseCtorArg args (
+ *this, FromBaseCtorArg::arg_complex_auto_ptr, true);
+ Traversal::Names args_names (args);
+ names (c, args_names);
+ }
+ os << ")" << endl
+ << ": " << base << " (" << base_arg << ")";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, ctor_names_);
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+ }
+
+ // If we are generating polymorphic code then we also need to
+ // provide auto_ptr version for every non-fundamental type.
+ //
+ if (has_non_fund_non_op_args &&
+ !complex_non_fund_args_clash &&
+ polymorphic)
+ {
+ os << name << "::" << endl
+ << name << " (const ";
+ inherits (c, inherits_member_);
+ os << "& " << base_arg;
+ {
+ FromBaseCtorArg args (
+ *this, FromBaseCtorArg::arg_non_fund_auto_ptr, true);
+ Traversal::Names args_names (args);
+ names (c, args_names);
+ }
+ os << ")" << endl
+ << ": " << base << " (" << base_arg << ")";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, ctor_names_);
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+ }
+ }
+ }
+
+ // c-tor (all-non-optional-members)
+ //
+ if (generate_no_base_ctor)
+ {
+ os << name << "::" << endl
+ << name << " (";
+ {
+ CtorArgsWithoutBase ctor_args (
+ *this, CtorArgsWithoutBase::arg_type, true, true);
+ ctor_args.dispatch (c);
+ }
+ os << ")" << endl
+ << ": " << base << " (";
+ {
+ CtorBase base (*this, "");
+ Traversal::Inherits inherits_base (base);
+
+ inherits (c, inherits_base);
+ }
+ os << ")";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, ctor_names_);
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+
+ // If we have any complex arguments in the previous c-tor
+ // then also generate the auto_ptr version. One case where
+ // this c-tor will be generated is restriction of anyType.
+ //
+ if (has_complex_non_op_args)
+ {
+ os << name << "::" << endl
+ << name << " (";
+ {
+ CtorArgsWithoutBase ctor_args (
+ *this, CtorArgsWithoutBase::arg_complex_auto_ptr, true, true);
+ ctor_args.dispatch (c);
+ }
+ os << ")" << endl
+ << ": " << base << " (";
+ {
+ CtorBase base (*this, "");
+ Traversal::Inherits inherits_base (base);
+
+ inherits (c, inherits_base);
+ }
+ os << ")";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, ctor_names_);
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+ }
+
+ // If we are generating polymorphic code then we also need to
+ // provide auto_ptr version for every non-fundamental type.
+ //
+ if (has_non_fund_non_op_args &&
+ !complex_non_fund_args_clash &&
+ polymorphic)
+ {
+ os << name << "::" << endl
+ << name << " (";
+ {
+ CtorArgsWithoutBase ctor_args (
+ *this, CtorArgsWithoutBase::arg_non_fund_auto_ptr, true, true);
+ ctor_args.dispatch (c);
+ }
+ os << ")" << endl
+ << ": " << base << " (";
+ {
+ CtorBase base (*this, "");
+ Traversal::Inherits inherits_base (base);
+
+ inherits (c, inherits_base);
+ }
+ os << ")";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, ctor_names_);
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+ }
+ }
+
+ if (string_based)
+ {
+ if (enum_base != 0)
+ {
+ // c-tor (enum-value, all-non-optional-members)
+ //
+ String base_arg (L"_xsd_" + ename (*enum_base) + L"_base");
+
+ os << name << "::" << endl
+ << name << " (" << fq_name (*enum_base) << "::" <<
+ evalue (*enum_base) << " " << base_arg;
+
+ {
+ CtorArgsWithoutBase ctor_args (
+ *this, CtorArgsWithoutBase::arg_type, true, false);
+ ctor_args.dispatch (c);
+ }
+
+ os << ")" << endl
+ << ": " << base << " (";
+
+ {
+ CtorBase base (*this, base_arg);
+ Traversal::Inherits inherits_base (base);
+
+ inherits (c, inherits_base);
+ }
+
+ os << ")";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, ctor_names_);
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+ }
+
+ String base_arg (L"_xsd_" + ename (ultimate_base (c)) + L"_base");
+
+ // c-tor (const char*, all-non-optional-members)
+ //
+ os << name << "::" << endl
+ << name << " (const " << char_type << "* " << base_arg;
+
+ {
+ CtorArgsWithoutBase ctor_args (
+ *this, CtorArgsWithoutBase::arg_type, true, false);
+ ctor_args.dispatch (c);
+ }
+
+ os << ")" << endl
+ << ": " << base << " (";
+
+ {
+ CtorBase base (*this, base_arg);
+ Traversal::Inherits inherits_base (base);
+
+ inherits (c, inherits_base);
+ }
+
+ os << ")";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, ctor_names_);
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+
+
+ // c-tor (const std::string&, all-non-optional-members)
+ //
+ os << name << "::" << endl
+ << name << " (const " << string_type << "& " << base_arg;
+
+ {
+ CtorArgsWithoutBase ctor_args (
+ *this, CtorArgsWithoutBase::arg_type, true, false);
+ ctor_args.dispatch (c);
+ }
+
+ os << ")" << endl
+ << ": " << base << " (";
+
+ {
+ CtorBase base (*this, base_arg);
+ Traversal::Inherits inherits_base (base);
+
+ inherits (c, inherits_base);
+ }
+
+ os << ")";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, ctor_names_);
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+ }
+
+ // c-tor (ultimate-base, all-non-optional-members)
+ //
+
+ os << name << "::" << endl
+ << name << " (";
+
+ String base_arg;
+
+ {
+ CtorArgs ctor_args (*this, CtorArgs::arg_type, base_arg);
+ ctor_args.dispatch (c);
+ }
+
+ os << ")" << endl
+ << ": " << base << " (";
+
+ {
+ CtorBase base (*this, base_arg);
+ Traversal::Inherits inherits_base (base);
+
+ inherits (c, inherits_base);
+ }
+
+ os << ")";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, ctor_names_);
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+
+ // If we have any complex arguments in the previous c-tor
+ // then also generate the auto_ptr version.
+ //
+ if (has_complex_non_op_args)
+ {
+ os << name << "::" << endl
+ << name << " (";
+
+ String base_arg;
+
+ {
+ CtorArgs ctor_args (
+ *this, CtorArgs::arg_complex_auto_ptr, base_arg);
+ ctor_args.dispatch (c);
+ }
+
+ os << ")" << endl
+ << ": " << base << " (";
+
+ {
+ CtorBase base (*this, base_arg);
+ Traversal::Inherits inherits_base (base);
+
+ inherits (c, inherits_base);
+ }
+
+ os << ")";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, ctor_names_);
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+ }
+
+ // If we are generating polymorphic code then we also need to
+ // provide auto_ptr version for every non-fundamental type.
+ //
+ if (has_non_fund_non_op_args &&
+ !complex_non_fund_args_clash &&
+ polymorphic)
+ {
+ os << name << "::" << endl
+ << name << " (";
+
+ String base_arg;
+
+ {
+ CtorArgs ctor_args (
+ *this, CtorArgs::arg_non_fund_auto_ptr, base_arg);
+ ctor_args.dispatch (c);
+ }
+
+ os << ")" << endl
+ << ": " << base << " (";
+
+ {
+ CtorBase base (*this, base_arg);
+ Traversal::Inherits inherits_base (base);
+
+ inherits (c, inherits_base);
+ }
+
+ os << ")";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, ctor_names_);
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+ }
+
+
+ // copy c-tor
+ //
+
+ os << name << "::" << endl
+ << name << " (const " << name << "& x," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << base << " (x, f, c)";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ {
+ CopyAny copy_any (*this, "x");
+ CopyMember copy_member (*this, "x");
+ Traversal::Names names;
+
+ names >> copy_member;
+
+ if (options.value<CLI::generate_wildcard> ())
+ names >> copy_any;
+
+ Complex::names (c, names);
+ }
+
+ os << "{";
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+ os << "}";
+
+ //
+ //
+ Boolean he (has<Traversal::Element> (c));
+ Boolean hae (has<Traversal::Any> (c));
+
+ Boolean ha (has<Traversal::Attribute> (c));
+ Boolean haa (has<Traversal::AnyAttribute> (c));
+
+ Boolean gen_wildcard (options.value<CLI::generate_wildcard> ());
+
+ //
+ //
+ if (!options.value<CLI::suppress_parsing> ())
+ {
+ // c-tor (xercesc::DOMElement)
+ //
+ os << name << "::" << endl
+ << name << " (const " << xerces_ns << "::DOMElement& e," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << base << " (e, f";
+
+ if (he || ha || hae || (haa && gen_wildcard))
+ os << " | " << flags_type << "::base";
+
+ os << ", c)";
+
+ if (edom_document_member_p (c))
+ {
+ os << "," << endl
+ << " " << edom_document_member (c) << " (" <<
+ "::xsd::cxx::xml::dom::create_document< " << char_type <<
+ " > ())";
+ }
+
+ names (c, element_ctor_names_);
+
+ os << "{";
+
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);"
+ << endl;
+
+ Boolean base_has_el (false), base_has_at (false);
+
+ // We are only interested in this information if we are
+ // generating out own parse().
+ //
+ if (he || ha || hae || (haa && gen_wildcard))
+ {
+ if (c.inherits_p ())
+ {
+ HasParseFunction test (*this, base_has_el, base_has_at);
+ test.dispatch (c.inherits ().base ());
+ }
+ }
+
+ //@@ throw if p is no exhausted at the end.
+ //
+ if (he || ha || hae || (haa && gen_wildcard))
+ os << "if ((f & " << flags_type << "::base) == 0)"
+ << "{"
+ << parser_type << " p (e, " <<
+ (he || hae || base_has_el ? "true, " : "false, ") <<
+ (ha || (haa && gen_wildcard) || base_has_at ? "true" : "false")
+ << ");"
+ << "this->" << unclash (name, "parse") << " (p, f);"
+ << "}";
+
+ os << "}";
+
+ Boolean simple (true);
+ {
+ IsSimpleType t (simple);
+ t.dispatch (c);
+ }
+
+ if (simple)
+ {
+ // c-tor (xercesc::DOMAttr)
+ //
+ os << name << "::" << endl
+ << name << " (const " << xerces_ns << "::DOMAttr& a," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << base << " (a, f, c)"
+ << "{";
+
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+
+ os << "}";
+
+ // c-tor (string const&, xercesc::DOMElement)
+ //
+ os << name << "::" << endl
+ << name << " (const " << string_type << "& s," << endl
+ << "const " << xerces_ns << "::DOMElement* e," << endl
+ << flags_type << " f," << endl
+ << container << "* c)" << endl
+ << ": " << base << " (s, e, f, c)"
+ << "{";
+
+ if (facets)
+ os << "this->_facet_table (_xsd_" << name << "_facet_table);";
+
+ os << "}";
+ }
+
+ if (he || ha || hae || (haa && gen_wildcard))
+ {
+ os << "void " << name << "::" << endl
+ << unclash (name, "parse") << " (" <<
+ parser_type << "& p," << endl
+ << flags_type <<
+ (he || ha || base_has_el || base_has_at ? " f" : "") << ")"
+ << "{";
+
+ // Allow the base to parse its part.
+ //
+ if (base_has_el || base_has_at)
+ os << "this->" << base << "::parse (p, f);"
+ << endl;
+
+ if (he || hae)
+ {
+ os << "for (; p.more_elements (); p.next_element ())"
+ << "{"
+ << "const " << xerces_ns << "::DOMElement& i (" <<
+ "p.cur_element ());"
+ << "const " << qname_type << " n (" << endl
+ << "::xsd::cxx::xml::dom::name< " << char_type << " > (i));"
+ << endl;
+
+ names (c, names_element_);
+
+ os << "break;"
+ << "}";
+
+ // Make sure all non-optional elements are set.
+ //
+ names (c, names_element_test_);
+ }
+
+ if (ha || (haa && gen_wildcard))
+ {
+ if (base_has_at)
+ os << "p.reset_attributes ();"
+ << endl;
+
+ os << "while (p.more_attributes ())"
+ << "{"
+ << "const " << xerces_ns << "::DOMAttr& i (" <<
+ "p.next_attribute ());"
+ << "const " << qname_type << " n (" << endl
+ << "::xsd::cxx::xml::dom::name< " << char_type << " > (i));"
+ << endl;
+
+ names (c, names_attribute_);
+
+ // Generate anyAttribute code after all the attributes.
+ //
+ if (gen_wildcard)
+ names (c, names_any_attribute_);
+
+
+ // os << "{" // else block
+ // @@
+ // This doesn't play well with inheritance because we
+ // don't expect base's attributes. Also there are other
+ // "special" attributes such as xmlns, etc.
+ //
+ // << "throw ::xsd::cxx::tree::unexpected_attribute ... "
+ // << "}";
+
+ os << "}"; // while loop
+
+ // Make sure all non-optional attributes are set.
+ //
+ names (c, names_attribute_test_);
+ }
+
+ os << "}";
+ }
+ }
+
+ // _clone
+ //
+ os << name << "* " << name << "::" << endl
+ << "_clone (" << flags_type << " f," << endl
+ << container << "* c) const"
+ << "{"
+ << "return new class " << name << " (*this, f, c);"
+ << "}";
+
+ // d-tor
+ //
+ os << name << "::" << endl
+ << "~" << name << " ()"
+ << "{"
+ << "}";
+
+ // Register with type factory map.
+ //
+ if (polymorphic && !c.context ().count ("anonymous"))
+ {
+ // Note that we are using the original type name.
+ //
+ String const& name (ename (c));
+
+ if (!options.value<CLI::suppress_parsing> ())
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::type_factory_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_type_factory_init (" << endl
+ << L << strlit (c.name ()) << "," << endl
+ << L << strlit (xml_ns_name (c)) << ");"
+ << endl;
+
+ if (options.value<CLI::generate_comparison> ())
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::comparison_initializer< 0, " <<
+ char_type << ", " << name << " >" << endl
+ << "_xsd_" << name << "_comparison_init;"
+ << endl;
+ }
+
+ // Comparison operators.
+ //
+ if (options.value<CLI::generate_comparison> () &&
+ (he || ha || !c.inherits_p () ||
+ ((hae || haa) && gen_wildcard)))
+ {
+ Boolean base_comp (false);
+
+ if (c.inherits_p ())
+ {
+ HasComparisonOperator test (*this, base_comp);
+ test.dispatch (c.inherits ().base ());
+ }
+
+ Boolean has_body (he || ha || base_comp ||
+ ((hae || haa) && gen_wildcard));
+
+ os << "bool" << endl
+ << "operator== (const " << name << "&" <<
+ (has_body ? " x" : "") << ", " <<
+ "const " << name << "&" << (has_body ? " y" : "") << ")"
+ << "{";
+
+ if (base_comp)
+ os << "if (!(static_cast< const " << base << "& > (x) ==" << endl
+ << "static_cast< const " << base << "& > (y)))" << endl
+ << "return false;"
+ << endl;
+
+ {
+ Complex::names (c, comparison_names_);
+ }
+
+ os << "return true;"
+ << "}";
+
+ os << "bool" << endl
+ << "operator!= (const " << name << "& x, " <<
+ "const " << name << "& y)"
+ << "{"
+ << "return !(x == y);"
+ << "}";
+ }
+ }
+
+ private:
+ Traversal::Inherits inherits_member_;
+ MemberTypeName member_name_;
+
+ Traversal::Names names_element_;
+ Traversal::Names names_element_test_;
+
+ Traversal::Names names_attribute_;
+ Traversal::Names names_any_attribute_;
+ Traversal::Names names_attribute_test_;
+
+ Any any_;
+ Element element_;
+
+ AnyTest any_test_;
+ ElementTest element_test_;
+
+ Attribute attribute_;
+ AttributeTest attribute_test_;
+
+ AnyAttribute any_attribute_;
+
+ DefaultCtorAnyInit default_ctor_any_init_;
+ DefaultCtorMemberInit default_ctor_member_init_;
+ Traversal::Names default_ctor_init_names_;
+
+ CtorAny ctor_any_;
+ CtorMember ctor_member_;
+ Traversal::Names ctor_names_;
+
+ ElementCtorAny element_ctor_any_;
+ ElementCtorMember element_ctor_member_;
+ Traversal::Names element_ctor_names_;
+
+ AnyComparison comparison_any_;
+ MemberComparison comparison_member_;
+ Traversal::Names comparison_names_;
+
+ FacetArray facet_array_;
+ };
+
+
+ // Generate element types and substitution group map entries.
+ //
+ struct GlobalElement : Traversal::Element,
+ GlobalElementBase,
+ protected virtual Context
+ {
+ GlobalElement (Context& c)
+ : Context (c),
+ GlobalElementBase (c),
+ element_type_ (c.options.value<CLI::generate_element_type> ()),
+ element_map_ (c.options.value<CLI::generate_element_map> ()),
+ type_name_ (c)
+ {
+ belongs_ >> type_name_;
+ }
+
+ virtual Void
+ traverse (Type& e)
+ {
+ if (element_type_ && doc_root_p (e))
+ {
+ SemanticGraph::Type& t (e.type ());
+
+ Boolean fund (false);
+ {
+ IsFundamentalType test (fund);
+ test.dispatch (t);
+ }
+
+ Boolean simple (true);
+ if (!fund)
+ {
+ IsSimpleType test (simple);
+ test.dispatch (t);
+ }
+
+ String const& name (ename (e));
+ String const& type (etype (e));
+ String const& member (emember (e));
+
+ os << "// " << name << endl
+ << "// " << endl
+ << endl;
+
+ // Virtual accessors.
+ //
+ os << "const " << any_type << "* " << name << "::" << endl
+ << "_value () const"
+ << "{";
+
+ if (fund)
+ os << "return 0;";
+ else
+ os << "return &this->" << member << ".get ();";
+
+ os << "}";
+
+ os << any_type << "* " << name << "::" << endl
+ << "_value ()"
+ << "{";
+
+ if (fund)
+ os << "return 0;";
+ else
+ os << "return &this->" << member << ".get ();";
+
+ os << "}";
+
+ // default c-tor
+ //
+ if (options.value<CLI::generate_default_ctor> ())
+ {
+ os << name << "::" << endl
+ << name << " ()" << endl
+ << ": " << member << " (0, 0)"
+ << "{"
+ << "}";
+ }
+
+ // c-tor (value)
+ //
+ os << name << "::" << endl
+ << name << " (const " << type << "& x)" << endl
+ << ": " << member << " (x, 0, 0)"
+ << "{"
+ << "}";
+
+
+ // c-tor (auto_ptr<value>)
+ //
+ if (!simple || (polymorphic && !fund))
+ {
+ os << name << "::" << endl
+ << name << " (::std::auto_ptr< " << type << " > p)" << endl
+ << ": " << member << " (p, 0, 0)"
+ << "{"
+ << "}";
+ }
+
+ // c-tor (xercesc::DOMElement)
+ //
+ SemanticGraph::Context& ec (e.context ());
+ String const& name_member (ec.get<String> ("element-name-member"));
+ String const& ns_member (ec.get<String> ("element-ns-member"));
+
+ Boolean parsing (!options.value<CLI::suppress_parsing> ());
+ if (parsing)
+ {
+ String const& tr (etraits (e));
+
+ os << name << "::" << endl
+ << name << " (const " << xerces_ns << "::DOMElement& e, " <<
+ flags_type << " f)" << endl
+ << ": " << member << " (f, 0)"
+ << "{"
+ << "const " << qname_type << " n (" << endl
+ << "::xsd::cxx::xml::dom::name< " << char_type << " > (e));"
+ << endl
+ << "if (n.name () == " << name_member << " && " <<
+ "n.namespace_ () == " << ns_member << ")" << endl
+ << "this->" << member << ".set (" << tr <<
+ "::create (e, f, 0));"
+ << "else" << endl
+ << "throw ::xsd::cxx::tree::unexpected_element < " <<
+ char_type << " > (" << endl
+ << "n.name (), n.namespace_ ()," << endl
+ << name_member << ", " << ns_member << ");"
+ << "}";
+ }
+
+ // copy c-tor
+ //
+ os << name << "::" << endl
+ << name << " (const " << name << "& x, " <<
+ flags_type << " f)" << endl
+ << ": " << element_type << " ()," << endl
+ << " " << member << " (x." << member << ", f, 0)"
+ << "{"
+ << "}";
+
+ // _clone
+ //
+ os << name << "* " << name << "::" << endl
+ << "_clone (" << flags_type << " f) const"
+ << "{"
+ << "return new class " << name << " (*this, f);"
+ << "}";
+
+ // Element name and namespace accessors.
+ //
+ String const& aname (ec.get<String> ("element-name"));
+ String const& ans (ec.get<String> ("element-ns"));
+
+ os << "const " << string_type << "& " << name << "::" << endl
+ << aname << " ()"
+ << "{"
+ << "return " << name_member << ";"
+ << "}";
+
+ os << "const " << string_type << "& " << name << "::" << endl
+ << ans << " ()"
+ << "{"
+ << "return " << ns_member << ";"
+ << "}";
+
+ os << "const " << string_type << "& " << name << "::" << endl
+ << "_name () const"
+ << "{"
+ << "return " << name_member << ";"
+ << "}";
+
+ os << "const " << string_type << "& " << name << "::" << endl
+ << "_namespace () const"
+ << "{"
+ << "return " << ns_member << ";"
+ << "}";
+
+ os << "const " << string_type << " " << name << "::" << endl
+ << name_member << " (" << L << strlit (e.name ()) << ");"
+ << endl
+ << "const " << string_type << " " << name << "::" << endl
+ << ns_member << " (" << L <<
+ strlit (e.namespace_ ().name ()) << ");"
+ << endl;
+
+ // d-tor
+ //
+ os << name << "::" << endl
+ << "~" << name << " ()"
+ << "{"
+ << "}";
+
+ // Element map registration.
+ //
+ if (element_map_ && parsing)
+ {
+ os << "static " << endl
+ << "const ::xsd::cxx::tree::parser_init< " << name << ", " <<
+ char_type << ", " << any_type << " >" << endl
+ << "_xsd_" << name << "_parser_init (" <<
+ name << "::" << aname << " (), " <<
+ name << "::" << ans << " ());"
+ << endl;
+ }
+ }
+
+ if (polymorphic && e.substitutes_p () &&
+ !options.value<CLI::suppress_parsing> ())
+ {
+ String const& name (ename (e));
+ Type& r (e.substitutes ().root ());
+
+ os << "static" << endl
+ << "const ::xsd::cxx::tree::type_factory_initializer< 0, " <<
+ char_type << ", ";
+
+ belongs (e, belongs_);
+
+ os << " >" << endl
+ << "_xsd_" << name << "_element_factory_init (" << endl
+ << L << strlit (r.name ()) << "," << endl
+ << L << strlit (r.namespace_ ().name ()) << "," << endl
+ << L << strlit (e.name ()) << "," << endl
+ << L << strlit (e.namespace_ ().name ()) << ");"
+ << endl
+ << endl;
+ }
+ }
+
+ private:
+ Boolean element_type_;
+ Boolean element_map_;
+ Traversal::Belongs belongs_;
+ MemberTypeName type_name_;
+ };
+ }
+
+ Void
+ generate_tree_source (Context& ctx,
+ UnsignedLong first,
+ UnsignedLong last)
+ {
+ if (ctx.options.value<CLI::generate_wildcard> ())
+ {
+ ctx.os << "#include <xsd/cxx/xml/dom/wildcard-source.hxx>" << endl
+ << endl;
+ }
+
+ if (!ctx.options.value<CLI::suppress_parsing> ())
+ ctx.os << "#include <xsd/cxx/xml/dom/parsing-source.hxx>" << endl
+ << endl;
+
+ if (ctx.polymorphic)
+ {
+ Boolean parsing (!ctx.options.value<CLI::suppress_parsing> ());
+ Boolean comparison (ctx.options.value<CLI::generate_comparison> ());
+
+ if (parsing)
+ ctx.os << "#include <xsd/cxx/tree/type-factory-map.hxx>" << endl
+ << endl;
+
+ if (comparison)
+ ctx.os << "#include <xsd/cxx/tree/comparison-map.hxx>" << endl
+ << endl;
+
+ if (parsing || comparison)
+ {
+ Boolean import_maps (ctx.options.value<CLI::import_maps> ());
+ Boolean export_maps (ctx.options.value<CLI::export_maps> ());
+
+ if (import_maps || export_maps)
+ {
+ ctx.os << "#ifdef _MSC_VER" << endl
+ << endl
+ << "namespace xsd"
+ << "{"
+ << "namespace cxx"
+ << "{"
+ << "namespace tree"
+ << "{";
+
+ if (parsing && export_maps)
+ ctx.os << "template struct __declspec (dllexport) " <<
+ "type_factory_plate< 0, " << ctx.char_type << " >;";
+
+ if (parsing && import_maps)
+ ctx.os << "template struct __declspec (dllimport) " <<
+ "type_factory_plate< 0, " << ctx.char_type << " >;";
+
+ if (comparison && export_maps)
+ ctx.os << "template struct __declspec (dllexport) " <<
+ "comparison_plate< 0, " << ctx.char_type << " >;";
+
+ if (comparison && import_maps)
+ ctx.os << "template struct __declspec (dllimport) " <<
+ "comparison_plate< 0, " << ctx.char_type << " >;";
+
+ ctx.os << "}" // tree
+ << "}" // cxx
+ << "}" // xsd
+ << "#endif // _MSC_VER" << endl
+ << endl;
+ }
+
+ ctx.os << "namespace _xsd"
+ << "{";
+
+ if (parsing)
+ ctx.os << "static" << endl
+ << "const ::xsd::cxx::tree::type_factory_plate< 0, " <<
+ ctx.char_type << " >" << endl
+ << "type_factory_plate_init;"
+ << endl;
+
+ if (comparison)
+ ctx.os << "static" << endl
+ << "const ::xsd::cxx::tree::comparison_plate< 0, " <<
+ ctx.char_type << " >" << endl
+ << "comparison_plate_init;"
+ << endl;
+
+ ctx.os << "}";
+ }
+ }
+
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+ Traversal::Names names_ns, names;
+ Namespace ns (ctx, first, last);
+
+ List list (ctx);
+ Union union_ (ctx);
+ Complex complex (ctx);
+ Enumeration enumeration (ctx);
+ GlobalElement element (ctx);
+
+ schema >> sources >> schema;
+ schema >> names_ns >> ns >> names;
+
+ names >> list;
+ names >> union_;
+ names >> complex;
+ names >> enumeration;
+ names >> element;
+
+ schema.dispatch (ctx.schema_root);
+ }
+ }
+}
diff --git a/xsd/cxx/tree/tree-source.hxx b/xsd/cxx/tree/tree-source.hxx
new file mode 100644
index 0000000..a9a0521
--- /dev/null
+++ b/xsd/cxx/tree/tree-source.hxx
@@ -0,0 +1,24 @@
+// file : xsd/cxx/tree/tree-source.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_TREE_SOURCE_HXX
+#define CXX_TREE_TREE_SOURCE_HXX
+
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ Void
+ generate_tree_source (Context&,
+ UnsignedLong first,
+ UnsignedLong last);
+ }
+}
+
+#endif // CXX_TREE_TREE_SOURCE_HXX
diff --git a/xsd/cxx/tree/validator.cxx b/xsd/cxx/tree/validator.cxx
new file mode 100644
index 0000000..8027df7
--- /dev/null
+++ b/xsd/cxx/tree/validator.cxx
@@ -0,0 +1,675 @@
+// file : xsd/cxx/tree/validator.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cxx/tree/validator.hxx>
+
+#include <cult/containers/set.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cxx/tree/elements.hxx>
+
+#include <iostream>
+
+using std::wcerr;
+
+namespace CXX
+{
+ namespace Tree
+ {
+ namespace
+ {
+ class ValidationContext: public Context
+ {
+ public:
+ ValidationContext (SemanticGraph::Schema& root,
+ CLI::Options const& options,
+ const WarningSet& disabled_warnings,
+ Counts const& counts,
+ Boolean generate_xml_schema,
+ Boolean& valid_)
+ : Context (std::wcerr,
+ root,
+ options,
+ counts,
+ generate_xml_schema,
+ 0,
+ 0,
+ 0),
+ disabled_warnings_ (disabled_warnings),
+ disabled_warnings_all_ (false),
+ valid (valid_),
+ subst_group_warning_issued (subst_group_warning_issued_),
+ subst_group_warning_issued_ (false)
+ {
+ if (disabled_warnings_.find ("all") != disabled_warnings_.end ())
+ disabled_warnings_all_ = true;
+ }
+
+ public:
+ Boolean
+ is_disabled (Char const* w)
+ {
+ return disabled_warnings_all_ ||
+ disabled_warnings_.find (w) != disabled_warnings_.end ();
+ }
+
+ public:
+ String
+ xpath (SemanticGraph::Nameable& n)
+ {
+ if (n.is_a<SemanticGraph::Namespace> ())
+ return L"<namespace-level>"; // There is a bug if you see this.
+
+ if (n.named ())
+ {
+ SemanticGraph::Scope& scope (n.scope ());
+
+ if (scope.is_a<SemanticGraph::Namespace> ())
+ return n.name ();
+
+ return xpath (scope) + L"/" + n.name ();
+ }
+ else
+ {
+ return L"(anonymous type for " +
+ n.context ().get<String> ("instance-name") + L")";
+ }
+ }
+
+ protected:
+ ValidationContext (ValidationContext& c)
+ : Context (c),
+ disabled_warnings_ (c.disabled_warnings_),
+ disabled_warnings_all_ (c.disabled_warnings_all_),
+ valid (c.valid),
+ subst_group_warning_issued (c.subst_group_warning_issued)
+ {
+ }
+
+ protected:
+ const WarningSet& disabled_warnings_;
+ Boolean disabled_warnings_all_;
+
+ Boolean& valid;
+
+ Boolean& subst_group_warning_issued;
+ Boolean subst_group_warning_issued_;
+ };
+
+
+ //
+ //
+ struct Any : Traversal::Any, protected virtual ValidationContext
+ {
+ Any (ValidationContext& c)
+ : ValidationContext (c)
+ {
+ }
+
+ struct Element: Traversal::Element,
+ protected virtual ValidationContext
+ {
+ Element (ValidationContext& c, SemanticGraph::Any& any)
+ : ValidationContext (c),
+ any_ (any),
+ ns_ (any.definition_namespace ().name ())
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ if (skip (e))
+ return;
+
+ using SemanticGraph::Any;
+
+ Boolean q (e.qualified ());
+ String ns (q ? e.namespace_ ().name () : "");
+
+ for (Any::NamespaceIterator i (any_.namespace_begin ());
+ i != any_.namespace_end (); ++i)
+ {
+ Boolean failed (false);
+
+ if (*i == L"##any")
+ {
+ failed = true;
+ }
+ else if (*i == L"##other")
+ {
+ if (ns_)
+ {
+ // Note that here I assume that ##other does not
+ // include names without target namespace. This
+ // is not what the spec says but that seems to be
+ // the consensus.
+ //
+ failed = q && ns != ns_;
+ }
+ else
+ {
+ // No target namespace.
+ //
+ failed = q && ns != L"";
+ }
+ }
+ else if (*i == L"##local")
+ {
+ failed = !q || ns == L"";
+ }
+ else if (*i == L"##targetNamespace")
+ {
+ failed = (q && ns_ == ns) || (!q && ns_ == L"");
+ }
+ else
+ {
+ failed = q && *i == ns;
+ }
+
+ if (failed)
+ {
+ Any& a (any_);
+
+ os << a.file () << ":" << a.line () << ":" << a.column ()
+ << ": warning T001: namespace '" << *i << "' allows for "
+ << "element '" << e.name () << "'" << endl;
+
+ os << a.file () << ":" << a.line () << ":" << a.column ()
+ << ": warning T001: generated code may not associate element '"
+ << e.name () << "' correctly if it appears in place of "
+ << "this wildcard" << endl;
+
+ os << e.file () << ":" << e.line () << ":" << e.column ()
+ << ": info: element '" << e.name () << "' is defined "
+ << "here" << endl;
+ }
+ }
+ }
+
+ private:
+ SemanticGraph::Any& any_;
+ String ns_;
+ };
+
+ struct Complex: Traversal::Complex
+ {
+ Complex ()
+ : up_ (true), down_ (true)
+ {
+ }
+
+ virtual Void
+ post (Type& c)
+ {
+ // Go down the inheritance hierarchy.
+ //
+ if (down_)
+ {
+ Boolean up = up_;
+ up_ = false;
+
+ if (c.inherits_p ())
+ dispatch (c.inherits ().base ());
+
+ up_ = up;
+ }
+
+ // Go up the inheritance hierarchy.
+ //
+ if (up_)
+ {
+ Boolean down = down_;
+ down_ = false;
+
+ for (Type::BegetsIterator i (c.begets_begin ());
+ i != c.begets_end (); ++i)
+ {
+ dispatch (i->derived ());
+ }
+
+ down_ = down;
+ }
+ }
+
+ private:
+ Boolean up_, down_;
+ };
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ using SemanticGraph::Compositor;
+
+ // Find our complex type.
+ //
+ Compositor* c (&a.contained_particle ().compositor ());
+
+ while(!c->contained_compositor_p ())
+ c = &c->contained_particle ().compositor ();
+
+ SemanticGraph::Complex& type (
+ dynamic_cast<SemanticGraph::Complex&> (
+ c->contained_compositor ().container ()));
+
+ Complex complex;
+ Traversal::Names names;
+ Element element (*this, a);
+
+ complex >> names >> element;
+
+ complex.dispatch (type);
+ }
+ };
+
+
+ //
+ //
+ struct Traverser : Traversal::Schema,
+ Traversal::Complex,
+ Traversal::Type,
+ Traversal::Element,
+ protected virtual ValidationContext
+ {
+ Traverser (ValidationContext& c)
+ : ValidationContext (c), any_ (c)
+ {
+ *this >> sources_ >> *this;
+ *this >> schema_names_ >> ns_ >> names_;
+
+ names_ >> *this >> names_;
+
+ // Any
+ //
+ if (!is_disabled ("T001"))
+ {
+ *this >> contains_compositor_ >> compositor_ >> contains_particle_;
+ contains_particle_ >> compositor_;
+ contains_particle_ >> any_;
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ using SemanticGraph::Schema;
+
+ traverse (static_cast<SemanticGraph::Type&> (c));
+
+ if (c.inherits_p ())
+ {
+ SemanticGraph::Type& t (c.inherits ().base ());
+
+ if (t.named () &&
+ types_.find (
+ t.scope ().name () + L"#" + t.name ()) == types_.end ())
+ {
+ // Don't worry about types that are in included/imported
+ // schemas.
+ //
+ Schema& s (dynamic_cast<Schema&> (t.scope ().scope ()));
+
+ if (&s == &schema_root || sources_p (schema_root, s))
+ {
+ valid = false;
+
+ os << c.file () << ":" << c.line () << ":" << c.column ()
+ << ": error: type '" << xpath (c) << "' inherits from "
+ << "yet undefined type '" << xpath (t) << "'" << endl;
+
+ os << t.file () << ":" << t.line () << ":" << t.column ()
+ << ": info: '" << xpath (t) << "' is defined here"
+ << endl;
+
+ os << c.file () << ":" << c.line () << ":" << c.column ()
+ << ": info: inheritance from a yet-undefined type is "
+ << "not supported" << endl;
+
+ os << c.file () << ":" << c.line () << ":" << c.column ()
+ << ": info: re-arrange your schema and try again"
+ << endl;
+ }
+ }
+ }
+
+ Complex::traverse (c);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type& t)
+ {
+ // This is also used to traverse Complex.
+ //
+ if (t.named ())
+ {
+ types_.insert (t.scope ().name () + L"#" + t.name ());
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ if (is_disabled ("T002"))
+ return;
+
+ // Note that there is no test for generate_p since we want
+ // to catch cases when things are not being generated but
+ // most likely should have been.
+ //
+ if (e.substitutes_p () && !polymorphic &&
+ !subst_group_warning_issued)
+ {
+ subst_group_warning_issued = true;
+
+ os << e.file () << ":" << e.line () << ":" << e.column ()
+ << ": warning T002: substitution groups are used but "
+ << "--generate-polymorphic was not specified" << endl;
+
+ os << e.file () << ":" << e.line () << ":" << e.column ()
+ << ": info: generated code may not be able to handle "
+ << "some conforming instances" << endl;
+ }
+ }
+
+ // Return true if root sources s.
+ //
+ Boolean
+ sources_p (SemanticGraph::Schema& root, SemanticGraph::Schema& s)
+ {
+ using SemanticGraph::Schema;
+ using SemanticGraph::Sources;
+
+ for (Schema::UsesIterator i (root.uses_begin ());
+ i != root.uses_end (); ++i)
+ {
+ if (i->is_a<Sources> ())
+ {
+ if (&i->schema () == &s || sources_p (i->schema (), s))
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private:
+ Containers::Set<String> types_;
+
+ Traversal::Sources sources_;
+
+ Traversal::Names schema_names_;
+ Traversal::Namespace ns_;
+
+ Traversal::Names names_;
+
+ // Any.
+ //
+ Any any_;
+ Traversal::Compositor compositor_;
+ Traversal::ContainsParticle contains_particle_;
+ Traversal::ContainsCompositor contains_compositor_;
+ };
+
+
+ struct AnonymousType : Traversal::Schema,
+ Traversal::Complex,
+ Traversal::Element,
+ Traversal::Attribute,
+ protected virtual ValidationContext
+ {
+ AnonymousType (ValidationContext& c)
+ : ValidationContext (c),
+ anonymous_error_issued_ (false)
+ {
+ *this >> sources_ >> *this;
+ *this >> schema_names_ >> ns_ >> names_ >> *this;
+ *this >> names_;
+ }
+
+ Boolean
+ traverse_common (SemanticGraph::Member& m)
+ {
+ SemanticGraph::Type& t (m.type ());
+
+ if (!t.named ()
+ && !t.is_a<SemanticGraph::Fundamental::IdRef> ()
+ && !t.is_a<SemanticGraph::Fundamental::IdRefs> ())
+ {
+ if (!anonymous_error_issued_)
+ {
+ valid = false;
+ anonymous_error_issued_ = true;
+
+ wcerr << t.file ()
+ << ": error: anonymous types detected"
+ << endl;
+
+ wcerr << t.file ()
+ << ": info: "
+ << "anonymous types are not supported in this mapping"
+ << endl;
+
+ wcerr << t.file ()
+ << ": info: consider explicitly naming these types or "
+ << "remove the --preserve-anonymous option to "
+ << "automatically name them"
+ << endl;
+
+ if (!options.value<CLI::show_anonymous> ())
+ wcerr << t.file ()
+ << ": info: use --show-anonymous option to see these "
+ << "types" << endl;
+ }
+
+ return true;
+ }
+
+ return false;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ if (skip (e)) return;
+
+ if (traverse_common (e))
+ {
+ if (options.value<CLI::show_anonymous> ())
+ {
+ wcerr << e.file () << ":" << e.line () << ":" << e.column ()
+ << ": error: element '" << xpath (e) << "' "
+ << "is of anonymous type" << endl;
+ }
+ }
+ else
+ Traversal::Element::traverse (e);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Attribute& a)
+ {
+ if (traverse_common (a))
+ {
+ if (options.value<CLI::show_anonymous> ())
+ {
+ wcerr << a.file () << ":" << a.line () << ":" << a.column ()
+ << ": error: attribute '" << xpath (a) << "' "
+ << "is of anonymous type" << endl;
+ }
+ }
+ else
+ Traversal::Attribute::traverse (a);
+ }
+
+ private:
+ Boolean anonymous_error_issued_;
+
+ Containers::Set<String> types_;
+
+ Traversal::Sources sources_;
+
+ Traversal::Names schema_names_;
+ Traversal::Namespace ns_;
+
+ Traversal::Names names_;
+ };
+ }
+
+ Validator::
+ Validator ()
+ {
+ // Dummy ctor, helps with long symbols on HP-UX.
+ }
+
+ Boolean Validator::
+ validate (CLI::Options const& options,
+ SemanticGraph::Schema& schema,
+ SemanticGraph::Path const&,
+ const WarningSet& disabled_warnings,
+ Counts const& counts)
+ {
+ Boolean valid (true);
+ ValidationContext ctx (
+ schema, options, disabled_warnings, counts, false, valid);
+
+ //
+ //
+ Boolean import_maps (options.value<CLI::import_maps> ());
+ Boolean export_maps (options.value<CLI::export_maps> ());
+
+ if (import_maps && export_maps)
+ {
+ wcerr << "error: --import-maps and --export-maps are "
+ << "mutually exclusive" << endl;
+
+ return false;
+ }
+
+ if (import_maps && !ctx.polymorphic)
+ {
+ wcerr << "error: --import-maps can only be specified together with "
+ << "--generate-polymorphic" << endl;
+
+ return false;
+ }
+
+ if (export_maps && !ctx.polymorphic)
+ {
+ wcerr << "error: --export-maps can only be specified together " <<
+ "with --generate-polymorphic" << endl;
+
+ return false;
+ }
+
+ //
+ //
+ if (options.value<CLI::char_type> () != "char" &&
+ options.value<CLI::char_type> () != "wchar_t" &&
+ !ctx.is_disabled ("T003"))
+ {
+ wcerr << "warning T003: unknown base character type '" <<
+ options.value<CLI::char_type> ().c_str () << "'" << endl;
+ }
+
+ //
+ //
+ NarrowString tn (options.value<CLI::type_naming> ());
+
+ if (tn != "knr" && tn != "ucc" && tn != "java")
+ {
+ wcerr << "error: unknown type naming style specified: '" <<
+ tn.c_str () << "'" << endl;
+
+ return false;
+ }
+
+ NarrowString fn (options.value<CLI::function_naming> ());
+
+ if (fn != "knr" && fn != "lcc" && fn != "java")
+ {
+ wcerr << "error: unknown function naming style specified: '" <<
+ fn.c_str () << "'" << endl;
+
+ return false;
+ }
+
+ //
+ //
+ Boolean element_type (options.value<CLI::generate_element_type> ());
+ Boolean par (!options.value<CLI::suppress_parsing> ());
+ Boolean ser (options.value<CLI::generate_serialization> ());
+
+ if (options.value<CLI::generate_element_map> ())
+ {
+ if (!element_type)
+ {
+ wcerr << "error: --generate-element-map can only be specified " <<
+ "together with --generate-element-type" << endl;
+
+ return false;
+ }
+
+ if (!(par || ser))
+ {
+ wcerr << "error: --generate-element-map is specified but " <<
+ "neither parsing nor serialization code is generated" << endl;
+
+ return false;
+ }
+ }
+
+ // Issue a warning if there are more than one global element
+ // and we are generating parsing/serialization functions or
+ // element types for all of them by default.
+ //
+
+ if (counts.global_elements > 1 &&
+ (element_type || par || ser) &&
+ !options.value<CLI::root_element_first> () &&
+ !options.value<CLI::root_element_last> () &&
+ !options.value<CLI::root_element_all> () &&
+ !options.value<CLI::root_element_none> () &&
+ options.value<CLI::root_element> ().empty () &&
+ !ctx.is_disabled ("T004"))
+ {
+ wcerr << schema.file () << ": warning T004: generating ";
+
+ if (element_type)
+ wcerr << "element types";
+ else
+ {
+ wcerr << (par ? "parsing " : "") <<
+ (ser ? (par ? "and serialization " : "serialization ") : "") <<
+ "functions";
+ }
+ wcerr << " for " << counts.global_elements << " global elements" <<
+ endl;
+
+ wcerr << schema.file () << ": info: use --root-element-* options "
+ << "to specify document root(s)" << endl;
+ }
+
+
+ // Test for anonymout types.
+ //
+ {
+ AnonymousType traverser (ctx);
+ traverser.dispatch (schema);
+ }
+
+ // Test the rest.
+ //
+ if (valid)
+ {
+ Traverser traverser (ctx);
+ traverser.dispatch (schema);
+ }
+
+ return valid;
+ }
+ }
+}
diff --git a/xsd/cxx/tree/validator.hxx b/xsd/cxx/tree/validator.hxx
new file mode 100644
index 0000000..f7fdc34
--- /dev/null
+++ b/xsd/cxx/tree/validator.hxx
@@ -0,0 +1,33 @@
+// file : xsd/cxx/tree/validator.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef CXX_TREE_VALIDATOR_HXX
+#define CXX_TREE_VALIDATOR_HXX
+
+#include <cxx/tree/elements.hxx>
+#include <cxx/tree/cli.hxx>
+
+#include <xsd.hxx>
+
+namespace CXX
+{
+ namespace Tree
+ {
+ class Validator
+ {
+ public:
+ Validator (); // Dummy ctor, helps with long symbols on HP-UX.
+
+ Boolean
+ validate (CLI::Options const& options,
+ SemanticGraph::Schema&,
+ SemanticGraph::Path const& tu,
+ const WarningSet& disabled_warnings,
+ Counts const& counts);
+ };
+ }
+}
+
+#endif // CXX_TREE_VALIDATOR_HXX
diff --git a/xsd/elements.hxx b/xsd/elements.hxx
new file mode 100644
index 0000000..bfde527
--- /dev/null
+++ b/xsd/elements.hxx
@@ -0,0 +1,135 @@
+// file : xsd/elements.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef ELEMENTS_HXX
+#define ELEMENTS_HXX
+
+#include <cult/types.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+using namespace Cult;
+typedef WideString String;
+
+namespace SemanticGraph = XSDFrontend::SemanticGraph;
+namespace Traversal = XSDFrontend::Traversal;
+
+
+// Anonymous feedback via belongs edge.
+//
+struct AnonymousBase : Traversal::Element,
+ Traversal::Attribute
+{
+ AnonymousBase (Traversal::NodeDispatcherBase& d1)
+ : complex_ (&d1, 0)
+ {
+ edge_traverser (belongs_);
+ belongs_.node_traverser (complex_);
+ }
+
+ AnonymousBase (Traversal::NodeDispatcherBase& d1,
+ Traversal::NodeDispatcherBase& d2)
+ : complex_ (&d1, &d2)
+ {
+ edge_traverser (belongs_);
+ belongs_.node_traverser (complex_);
+ }
+
+ // Hooks.
+ //
+public:
+ virtual void
+ member_pre (SemanticGraph::Member&)
+ {
+ }
+
+ virtual void
+ member_post (SemanticGraph::Member&)
+ {
+ }
+
+ /*
+ virtual void
+ type_pre (SemanticGraph::Type& t)
+ {
+ }
+
+ virtual void
+ type_post (SemanticGraph::Type& t)
+ {
+ }
+ */
+
+public:
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ SemanticGraph::Type& t (e.type ());
+
+ if (!t.named () && !t.context ().count ("seen"))
+ {
+ t.context ().set ("seen", true);
+
+ member_pre (e);
+
+ Element::belongs (e, belongs_);
+
+ member_post (e);
+
+ t.context ().remove ("seen");
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Attribute& a)
+ {
+ SemanticGraph::Type& t (a.type ());
+
+ if (!t.named () && !t.context ().count ("seen"))
+ {
+ t.context ().set ("seen", true);
+
+ member_pre (a);
+
+ Attribute::belongs (a, belongs_);
+
+ member_post (a);
+
+ t.context ().remove ("seen");
+ }
+ }
+
+private:
+ struct Complex : Traversal::Complex
+ {
+ Complex (Traversal::NodeDispatcherBase* d1,
+ Traversal::NodeDispatcherBase* d2)
+ : d1_ (d1), d2_ (d2)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ if (d1_)
+ d1_->dispatch (c);
+
+ if (d2_)
+ d2_->dispatch (c);
+ }
+
+ private:
+ Traversal::NodeDispatcherBase* d1_;
+ Traversal::NodeDispatcherBase* d2_;
+
+ } complex_;
+
+ Traversal::Belongs belongs_;
+};
+
+#endif // ELEMENTS_HXX
+
diff --git a/xsd/makefile b/xsd/makefile
new file mode 100644
index 0000000..e09a737
--- /dev/null
+++ b/xsd/makefile
@@ -0,0 +1,132 @@
+# file : xsd/makefile
+# author : Boris Kolpackov <boris@codesynthesis.com>
+# copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+# license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+include $(dir $(lastword $(MAKEFILE_LIST)))../build/bootstrap.make
+
+cxx_tun := xsd.cxx
+
+cxx_tun += cxx/elements.cxx
+
+cxx_tun += cxx/parser/elements.cxx \
+ cxx/parser/validator.cxx \
+ cxx/parser/name-processor.cxx \
+ cxx/parser/type-processor.cxx \
+ cxx/parser/state-processor.cxx \
+ cxx/parser/generator.cxx \
+ cxx/parser/parser-header.cxx \
+ cxx/parser/parser-inline.cxx \
+ cxx/parser/parser-source.cxx \
+ cxx/parser/parser-forward.cxx \
+ cxx/parser/impl-header.cxx \
+ cxx/parser/impl-source.cxx \
+ cxx/parser/driver-source.cxx \
+ cxx/parser/element-validation-source.cxx \
+ cxx/parser/attribute-validation-source.cxx \
+ cxx/parser/characters-validation-source.cxx
+
+cxx_tun += cxx/tree/elements.cxx \
+ cxx/tree/validator.cxx \
+ cxx/tree/counter.cxx \
+ cxx/tree/name-processor.cxx \
+ cxx/tree/generator.cxx \
+ cxx/tree/tree-forward.cxx \
+ cxx/tree/tree-header.cxx \
+ cxx/tree/tree-inline.cxx \
+ cxx/tree/tree-source.cxx \
+ cxx/tree/parser-header.cxx \
+ cxx/tree/parser-source.cxx \
+ cxx/tree/stream-header.cxx \
+ cxx/tree/stream-source.cxx \
+ cxx/tree/serialization-header.cxx \
+ cxx/tree/serialization-source.cxx \
+ cxx/tree/stream-insertion-header.cxx \
+ cxx/tree/stream-insertion-source.cxx \
+ cxx/tree/stream-extraction-source.cxx
+
+
+# Type map
+#
+cxx_tun += type-map/lexer.cxx \
+ type-map/parser.cxx
+
+# Processing
+#
+cxx_tun += processing/cardinality/processor.cxx \
+ processing/inheritance/processor.cxx
+
+
+cxx_obj := $(addprefix $(out_base)/,$(cxx_tun:.cxx=.o))
+cxx_od := $(cxx_obj:.o=.o.d)
+
+xsd := $(out_base)/xsd
+clean := $(out_base)/.clean
+install := $(out_base)/.install
+
+# Import.
+#
+$(call import,\
+ $(scf_root)/import/libcult/stub.make,\
+ l: cult.l,cpp-options: cult.l.cpp-options)
+
+$(call import,\
+ $(scf_root)/import/libbackend-elements/stub.make,\
+ l: be.l,cpp-options: be.l.cpp-options)
+
+# This is needed because libbe does not link properly to regex.
+#
+$(call import,\
+ $(scf_root)/import/libboost/regex/stub.make,\
+ l: re.l,cpp-options: re.l.cpp-options)
+
+$(call import,\
+ $(scf_root)/import/libboost/filesystem/stub.make,\
+ l: fs.l,cpp-options: fs.l.cpp-options)
+
+$(call import,\
+ $(scf_root)/import/libxsd-frontend/stub.make,\
+ l: xsd_fe.l,cpp-options: xsd_fe.l.cpp-options)
+
+# Build.
+#
+$(xsd): $(cxx_obj) $(xsd_fe.l) $(be.l) $(cult.l) $(fs.l) $(re.l) $(xerces_c.l)
+
+$(cxx_obj) $(cxx_od): cpp_options := -I$(src_base)
+$(cxx_obj) $(cxx_od): \
+ $(xsd_fe.l.cpp-options) \
+ $(be.l.cpp-options) \
+ $(cult.l.cpp-options) \
+ $(fs.l.cpp-options) \
+ $(re.l.cpp-options)
+
+$(call include-dep,$(cxx_od))
+
+# Alias for default target.
+#
+.PHONY: $(out_base)/
+$(out_base)/: $(xsd)
+
+# install
+#
+.PHONY: $(install)
+
+$(install): $(xsd)
+ $(call install-exec,$<,$(install_bin_dir)/xsd)
+
+# clean
+#
+.PHONY: $(clean)
+
+$(clean): \
+ $(xsd).o.clean \
+ $(addsuffix .cxx.clean,$(cxx_obj)) \
+ $(addsuffix .cxx.clean,$(cxx_od))
+
+
+# how to
+#
+$(call include,$(bld_root)/cxx/o-e.make)
+$(call include,$(bld_root)/cxx/cxx-o.make)
+$(call include,$(bld_root)/cxx/cxx-d.make)
+$(call include,$(bld_root)/install.make)
diff --git a/xsd/processing/cardinality/processor.cxx b/xsd/processing/cardinality/processor.cxx
new file mode 100644
index 0000000..fae30f6
--- /dev/null
+++ b/xsd/processing/cardinality/processor.cxx
@@ -0,0 +1,407 @@
+// file : processing/cardinality/processor.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <processing/cardinality/processor.hxx>
+
+#include <elements.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cult/containers/map.hxx>
+
+namespace Processing
+{
+ using namespace Cult;
+
+ namespace SemanticGraph = XSDFrontend::SemanticGraph;
+ namespace Traversal = XSDFrontend::Traversal;
+
+ typedef WideString String;
+
+ namespace Cardinality
+ {
+ namespace
+ {
+ //
+ //
+ struct ElementInfo
+ {
+ ElementInfo ()
+ : min (0), max (0), e_ (0)
+ {
+ }
+
+ ElementInfo (SemanticGraph::Element& e)
+ : min (1), max (1), e_ (&e)
+ {
+ }
+
+ ElementInfo (SemanticGraph::Element& e,
+ UnsignedLong min_, UnsignedLong max_)
+ : min (min_), max (max_), e_ (&e)
+ {
+ }
+
+ SemanticGraph::Element&
+ element ()
+ {
+ assert (e_ != 0);
+ return *e_;
+ }
+
+ public:
+ UnsignedLong min, max;
+
+ private:
+ SemanticGraph::Element* e_;
+ };
+
+ typedef Cult::Containers::Map<String, ElementInfo> ElementInfoMap;
+
+ //
+ //
+ struct AnyInfo
+ {
+ AnyInfo ()
+ : min (0), max (0), a_ (0)
+ {
+ }
+
+ AnyInfo (SemanticGraph::Any& a)
+ : min (1), max (1), a_ (&a)
+ {
+ }
+
+ AnyInfo (SemanticGraph::Any& a,
+ UnsignedLong min_, UnsignedLong max_)
+ : min (min_), max (max_), a_ (&a)
+ {
+ }
+
+ SemanticGraph::Any&
+ any ()
+ {
+ assert (a_ != 0);
+ return *a_;
+ }
+
+ public:
+ UnsignedLong min, max;
+
+ private:
+ SemanticGraph::Any* a_;
+ };
+
+ typedef Cult::Containers::Map<String, AnyInfo> AnyInfoMap;
+
+ //
+ //
+ struct Particle: Traversal::All,
+ Traversal::Choice,
+ Traversal::Sequence,
+ Traversal::Element,
+ Traversal::Any
+ {
+ virtual Void
+ traverse (SemanticGraph::All& a)
+ {
+ traverse_sequence (a);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Choice& c)
+ {
+ using SemanticGraph::Compositor;
+
+ // Go over all particles we contain and add them to the map.
+ //
+ for (Compositor::ContainsIterator ci (c.contains_begin ());
+ ci != c.contains_end (); ++ci)
+ {
+ Particle t;
+ t.dispatch (ci->particle ());
+
+ // Handle elements.
+ //
+ if (ci == c.contains_begin ())
+ el_map = t.el_map; // First arm.
+ else
+ {
+ // For elements that are in the map but not in this
+ // arm of choice, we need to set min to 0 while for
+ // those that are we need to choose minimum between
+ // the two for min and maximum for max.
+ //
+ for (ElementInfoMap::Iterator i (el_map.begin ());
+ i != el_map.end (); ++i)
+ {
+ String const& name (i->first);
+ ElementInfo& ei (i->second);
+
+ ElementInfoMap::Iterator j (t.el_map.find (name));
+
+ if (j == t.el_map.end ())
+ ei.min = 0;
+ else
+ {
+ ei.min = j->second.min < ei.min ? j->second.min : ei.min;
+ ei.max = j->second.max > ei.max ? j->second.max : ei.max;
+ }
+ }
+
+ // Now elements that are in this arm of choice but are
+ // not in the map, we need to add to the map and set their
+ // min to 0.
+ //
+ for (ElementInfoMap::Iterator i (t.el_map.begin ());
+ i != t.el_map.end (); ++i)
+ {
+ String const& name (i->first);
+ ElementInfo& ei (i->second);
+
+ ElementInfoMap::Iterator j (el_map.find (name));
+
+ if (j == el_map.end ())
+ el_map[name] = ElementInfo (ei.element (), 0, ei.max);
+ }
+ }
+
+ // Handle wildcards. Since each wildcard is treated as unique,
+ // we need to copy them from each arm of choice and set min to
+ // 0.
+ //
+ for (AnyInfoMap::Iterator i (t.any_map.begin ());
+ i != t.any_map.end (); ++i)
+ {
+ String const& name (i->first);
+ AnyInfo& ai (i->second);
+
+ assert (any_map.find (name) == any_map.end ());
+
+ any_map[name] = AnyInfo (ai.any (), 0, ai.max);
+ }
+ }
+
+ // Choice's min and max.
+ //
+ UnsignedLong cmin (c.min ()), cmax (c.max ());
+
+ // Iterate over elements and wildcards in the maps and multiply
+ // their cardinality by cmin and cmax.
+ //
+ for (ElementInfoMap::Iterator i (el_map.begin ());
+ i != el_map.end (); ++i)
+ {
+ i->second.min *= cmin;
+ i->second.max *= cmax;
+ }
+
+ for (AnyInfoMap::Iterator i (any_map.begin ());
+ i != any_map.end (); ++i)
+ {
+ i->second.min *= cmin; // Not really necessary since min == 0.
+ i->second.max *= cmax;
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Sequence& s)
+ {
+ traverse_sequence (s);
+ }
+
+ Void
+ traverse_sequence (SemanticGraph::Compositor& c)
+ {
+ using SemanticGraph::Compositor;
+
+ // Sequence's min and max.
+ //
+ UnsignedLong smin (c.min ()), smax (c.max ());
+
+ // Go over all particles we contain and add them to the map.
+ //
+ for (Compositor::ContainsIterator ci (c.contains_begin ());
+ ci != c.contains_end (); ++ci)
+ {
+ Particle t;
+ t.dispatch (ci->particle ());
+
+ // Handle elements.
+ //
+ for (ElementInfoMap::Iterator i (t.el_map.begin ());
+ i != t.el_map.end (); ++i)
+ {
+ String const& name (i->first);
+ ElementInfo& ei (i->second);
+ UnsignedLong min (ei.min * smin);
+ UnsignedLong max (ei.max * smax);
+ ElementInfoMap::Iterator j (el_map.find (name));
+
+ if (j != el_map.end ())
+ {
+ // Add i's cardinality to j
+ //
+ j->second.min += min;
+ j->second.max = (j->second.max == 0 || max == 0) ?
+ 0 : (j->second.max + max);
+ }
+ else
+ el_map[name] = ElementInfo (ei.element (), min, max);
+ }
+
+ // Handle wildcards.
+ //
+ for (AnyInfoMap::Iterator i (t.any_map.begin ());
+ i != t.any_map.end (); ++i)
+ {
+ String const& name (i->first);
+ AnyInfo& ai (i->second);
+ UnsignedLong min (ai.min * smin);
+ UnsignedLong max (ai.max * smax);
+
+ assert (any_map.find (name) == any_map.end ());
+
+ any_map[name] = AnyInfo (ai.any (), min, max);
+ }
+ }
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ SemanticGraph::ContainsParticle& cp (e.contained_particle ());
+
+ String name (e.qualified ()
+ ? e.namespace_ ().name () + L" " + e.name ()
+ : e.name ());
+
+ el_map[name] = ElementInfo (e, cp.min (), cp.max ());
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Any& a)
+ {
+ SemanticGraph::ContainsParticle& cp (a.contained_particle ());
+
+ any_map[a.name ()] = AnyInfo (a, cp.min (), cp.max ());
+ }
+
+ public:
+ AnyInfoMap any_map;
+ ElementInfoMap el_map;
+ };
+
+
+ //
+ //
+ struct Complex: Traversal::Complex
+ {
+ virtual Void
+ traverse (Type& c)
+ {
+ if (c.contains_compositor_p ())
+ {
+ Particle t;
+ t.dispatch (c.contains_compositor ().compositor ());
+
+ for (ElementInfoMap::Iterator i (t.el_map.begin ());
+ i != t.el_map.end (); ++i)
+ {
+ ElementInfo& ei (i->second);
+ FrontendElements::Context& ctx (ei.element ().context ());
+
+ ctx.set ("min", ei.min);
+ ctx.set ("max", ei.max);
+ }
+
+ for (AnyInfoMap::Iterator i (t.any_map.begin ());
+ i != t.any_map.end (); ++i)
+ {
+ AnyInfo& ai (i->second);
+ FrontendElements::Context& ctx (ai.any ().context ());
+
+ ctx.set ("min", ai.min);
+ ctx.set ("max", ai.max);
+ }
+ }
+
+ // Traverse attributes and anonymous types (via elements).
+ //
+ Complex::names (c);
+ }
+ };
+
+
+ //
+ //
+ struct Attribute: Traversal::Attribute
+ {
+ virtual Void
+ traverse (Type& a)
+ {
+ FrontendElements::Context& ctx (a.context ());
+
+ ctx.set ("min", a.optional () ? 0UL : 1UL);
+ ctx.set ("max", 1UL);
+ }
+ };
+
+ // Go into implied/included/imported schemas while making sure
+ // we don't process the same stuff more than once.
+ //
+ struct Uses: Traversal::Uses
+ {
+ virtual Void
+ traverse (Type& u)
+ {
+ SemanticGraph::Schema& s (u.schema ());
+
+ if (!s.context ().count ("processing-cardinality-seen"))
+ {
+ s.context ().set ("processing-cardinality-seen", true);
+ Traversal::Uses::traverse (u);
+ }
+ }
+ };
+ }
+
+ Void Processor::
+ process (SemanticGraph::Schema& tu, SemanticGraph::Path const&)
+ {
+ Traversal::Schema schema;
+ Uses uses;
+
+ schema >> uses >> schema;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+
+ schema >> schema_names >> ns >> ns_names;
+
+ Complex complex_type;
+ AnonymousBase anonymous (complex_type);
+
+ ns_names >> complex_type;
+ ns_names >> anonymous;
+
+ Attribute attribute;
+ Traversal::Names names;
+
+ complex_type >> names;
+
+ names >> attribute;
+ names >> anonymous;
+
+ // Some twisted schemas do recusive inclusions.
+ //
+ tu.context ().set ("processing-cardinality-seen", true);
+
+ schema.dispatch (tu);
+ }
+ }
+}
diff --git a/xsd/processing/cardinality/processor.hxx b/xsd/processing/cardinality/processor.hxx
new file mode 100644
index 0000000..feed41a
--- /dev/null
+++ b/xsd/processing/cardinality/processor.hxx
@@ -0,0 +1,32 @@
+// file : processing/cardinality/processor.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef PROCESSING_CARDINALITY_PROCESSOR_HXX
+#define PROCESSING_CARDINALITY_PROCESSOR_HXX
+
+#include <cult/types.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx> // Path
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+namespace Processing
+{
+ namespace Cardinality
+ {
+ using namespace Cult::Types;
+
+ class Processor
+ {
+ public:
+ struct Failed {};
+
+ Void
+ process (XSDFrontend::SemanticGraph::Schema&,
+ XSDFrontend::SemanticGraph::Path const& file);
+ };
+ }
+}
+
+#endif // PROCESSING_CARDINALITY_PROCESSOR_HXX
diff --git a/xsd/processing/inheritance/processor.cxx b/xsd/processing/inheritance/processor.cxx
new file mode 100644
index 0000000..dbc9237
--- /dev/null
+++ b/xsd/processing/inheritance/processor.cxx
@@ -0,0 +1,474 @@
+// file : processing/inheritance/processor.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <processing/inheritance/processor.hxx>
+
+#include <elements.hxx>
+
+#include <xsd-frontend/semantic-graph.hxx>
+#include <xsd-frontend/traversal.hxx>
+
+#include <cult/containers/set.hxx>
+
+#include <iostream>
+using std::wcerr;
+using std::endl;
+
+namespace Processing
+{
+ using namespace Cult;
+
+ namespace SemanticGraph = XSDFrontend::SemanticGraph;
+ namespace Traversal = XSDFrontend::Traversal;
+
+ typedef WideString String;
+
+ namespace Inheritance
+ {
+ namespace
+ {
+ struct Dep
+ {
+ Dep (SemanticGraph::Type& t,
+ SemanticGraph::Member* m = 0,
+ String const& xpath = L"")
+ : type (t), member (m), member_xpath (xpath)
+ {
+ }
+
+ SemanticGraph::Type& type;
+ SemanticGraph::Member* member; // Member if type is anonymous.
+ String member_xpath;
+ };
+
+ inline Boolean
+ operator< (Dep const& a, Dep const& b)
+ {
+ return &a.type < &b.type;
+ }
+
+ typedef Containers::Set<Dep> DepSet;
+ typedef Containers::Set<SemanticGraph::Type*> TypeSet;
+
+
+ String
+ xpath (SemanticGraph::Nameable& n)
+ {
+ if (dynamic_cast<SemanticGraph::Namespace*> (&n) != 0)
+ return L"<namespace-level>"; // There is a bug if you see this.
+
+ if (n.named ())
+ {
+ SemanticGraph::Scope& scope (n.scope ());
+
+ if (dynamic_cast<SemanticGraph::Namespace*> (&scope) != 0)
+ return n.name ();
+
+ return xpath (scope) + L"/" + n.name ();
+ }
+ else
+ {
+ return L"(anonymous type for " +
+ n.context ().get<String> ("instance-name") + L")";
+ }
+ }
+
+
+ // Calculate the list of dependencies for this complex
+ // type.
+ //
+ struct ComplexType: Traversal::Complex,
+ Traversal::Member
+ {
+ ComplexType (DepSet& dep_set)
+ : dep_set_ (dep_set), last_ (0)
+ {
+ *this >> names_ >> *this;
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ using SemanticGraph::Complex;
+
+ if (c.inherits_p ())
+ dep_set_.insert (Dep (c.inherits ().base (), last_, last_xpath_));
+
+ types_seen_.insert (&c);
+
+ // Go after anonymous types.
+ //
+ names (c);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Member& m)
+ {
+ SemanticGraph::Type& t (m.type ());
+
+ if (!t.named () && types_seen_.find (&t) == types_seen_.end ())
+ {
+ FrontendElements::Context& ctx (t.context ());
+
+ last_xpath_ = xpath (m);
+
+ String prev_xpath;
+
+ if (ctx.count ("instance-name"))
+ prev_xpath = ctx.get<String> ("instance-name");
+
+ ctx.set ("instance-name", last_xpath_);
+
+ last_ = &m;
+ dispatch (t);
+
+ if (prev_xpath)
+ ctx.set ("instance-name", prev_xpath);
+ else
+ ctx.remove ("instance-name");
+ }
+ }
+
+ private:
+ DepSet& dep_set_;
+ TypeSet types_seen_;
+
+ SemanticGraph::Member* last_;
+ String last_xpath_;
+
+ Traversal::Names names_;
+ };
+
+
+ //
+ //
+ template <typename N, typename A>
+ struct NodeArgs
+ {
+ NodeArgs (N& node, A arg)
+ : node_ (node), arg_ (arg)
+ {
+ }
+
+ operator N& () const
+ {
+ return node_;
+ }
+
+ template <typename E>
+ Void
+ add_edge_left (E& e)
+ {
+ node_.add_edge_left (e, arg_);
+ }
+
+ template <typename E>
+ Void
+ add_edge_right (E& e)
+ {
+ node_.add_edge_right (e, arg_);
+ }
+
+ private:
+ N& node_;
+ A arg_;
+ };
+
+
+ //
+ //
+ struct Global: Traversal::Type,
+ Traversal::Complex,
+ Traversal::Element
+ {
+ Global (SemanticGraph::Schema& root,
+ SemanticGraph::Schema& schema,
+ Boolean& failed)
+ : root_ (root), schema_ (schema), failed_ (failed)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Type& t)
+ {
+ if (t.named ())
+ types_seen_.insert (&t);
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Complex& c)
+ {
+ check_dep (c, c);
+ types_seen_.insert (&c);
+ };
+
+ virtual Void
+ traverse (SemanticGraph::Element& e)
+ {
+ SemanticGraph::Type& t (e.type ());
+
+ if (!t.named ())
+ {
+ t.context ().set ("instance-name", xpath (e));
+ check_dep (e, t);
+ t.context ().remove ("instance-name");
+ }
+ };
+
+ private:
+ Void
+ check_dep (SemanticGraph::Nameable& global,
+ SemanticGraph::Type& type)
+ {
+ using SemanticGraph::Type;
+ using SemanticGraph::Scope;
+ using SemanticGraph::Names;
+ using SemanticGraph::Schema;
+
+ DepSet prereqs;
+
+ // Calculate our prerequisistes.
+ //
+ {
+ ComplexType complex (prereqs);
+ complex.dispatch (type);
+ }
+
+ for (DepSet::ConstIterator i (prereqs.begin ());
+ i != prereqs.end (); ++i)
+ {
+ Dep const& dep (*i);
+ Type& t (dep.type);
+
+ // We won't be able to generate compilable code in case of a
+ // dependency on ourselves (e.g., a member element with
+ // anonymous type that inherits from us).
+ //
+ if (&t == &type)
+ {
+ assert (dep.member != 0);
+
+ SemanticGraph::Member& m (*dep.member);
+
+ wcerr << t.file () << ":" << t.line () << ":" << t.column ()
+ << " error: nested anonymous type for '"
+ << dep.member_xpath << "' cyclicly inherits from '"
+ << t.name () << "'" << endl;
+
+ wcerr << t.file () << ":" << t.line () << ":" << t.column ()
+ << " error: unable to generate valid code for such "
+ << "cyclic inheritance" << endl;
+
+ wcerr << m.file () << ":" << m.line () << ":" << m.column ()
+ << " info: '" << m.name () << "' element is declared here"
+ << endl;
+
+ wcerr << t.file () << ":" << t.line () << ":" << t.column ()
+ << ": info: consider explicitly naming this type "
+ << "or remove the --preserve-anonymous option"
+ << endl;
+
+ failed_ = true;
+ continue;
+ }
+
+ if (types_seen_.find (&t) == types_seen_.end ())
+ {
+ Scope& scope (t.scope ());
+ Schema& schema (dynamic_cast<Schema&> (scope.scope ()));
+
+ // Don't worry about types that are in included/imported
+ // schemas.
+ //
+ if (&schema != &schema_ && !sources_p (schema_, schema))
+ continue;
+
+ if (t.context ().count ("seen"))
+ {
+ wcerr << t.file () << ":" << t.line () << ":" << t.column ()
+ << " error: nested anonymous type in '" << t.name ()
+ << "' or '" << type.name () << "' inherits from one of "
+ << "these types and makes them mutually dependant"
+ << endl;
+
+ wcerr << t.file () << ":" << t.line () << ":" << t.column ()
+ << " error: unable to generate valid code for such "
+ << "cyclic dependency" << endl;
+
+ wcerr << type.file () << ":" << type.line () << ":"
+ << type.column () << " info: '" << type.name ()
+ << "' type is defined here"
+ << endl;
+
+ wcerr << t.file () << ":" << t.line () << ":" << t.column ()
+ << ": info: consider explicitly naming the anonymous "
+ << "type or remove the --preserve-anonymous option"
+ << endl;
+
+ failed_ = true;
+ continue;
+ }
+
+
+ //wcerr << "type '" << t.name () << "' needs to be moved " <<
+ // "before " << (global.is_a<Type> () ? "type" : "element") <<
+ // " '" << global.name () << "'" << endl;
+
+
+ // Delete current Names edge.
+ //
+ String name (t.name ());
+ {
+ Names& n (t.named_ ());
+ root_.delete_edge (scope, t, n);
+ }
+
+ // Insert a new Names edge before global.
+ //
+ {
+ // Convert to the insert-after call.
+ //
+ Scope::NamesIterator i (scope.find (global.named_ ()));
+
+ if (i == scope.names_begin ())
+ i = scope.names_end ();
+ else
+ --i;
+
+ NodeArgs<Scope, Scope::NamesIterator> na (scope, i);
+ root_.new_edge<Names> (na, t, name);
+ }
+
+ // Recursively process the moved type.
+ //
+ global.context ().set ("seen", true);
+ dispatch (t);
+ global.context ().remove ("seen");
+ }
+ }
+ }
+
+ private:
+ // Return true if root sources s.
+ //
+ Boolean
+ sources_p (SemanticGraph::Schema& root, SemanticGraph::Schema& s)
+ {
+ using SemanticGraph::Schema;
+ using SemanticGraph::Sources;
+
+ for (Schema::UsesIterator i (root.uses_begin ());
+ i != root.uses_end (); ++i)
+ {
+ if (i->is_a<Sources> ())
+ {
+ if (&i->schema () == &s || sources_p (i->schema (), s))
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ private:
+ SemanticGraph::Schema& root_;
+ SemanticGraph::Schema& schema_;
+ TypeSet types_seen_;
+ Boolean& failed_;
+ };
+
+
+ // Go into included/imported schemas while making sure we don't
+ // process the same stuff more than once.
+ //
+ struct Uses: Traversal::Includes, Traversal::Imports
+ {
+ Uses (SemanticGraph::Schema& root, Boolean& failed)
+ : root_ (root), failed_ (failed)
+ {
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Includes& i)
+ {
+ traverse (i.schema ());
+ }
+
+ virtual Void
+ traverse (SemanticGraph::Imports& i)
+ {
+ traverse (i.schema ());
+ }
+
+ private:
+ Void
+ traverse (SemanticGraph::Schema& s)
+ {
+ if (!s.context ().count ("processing-inheritance-seen"))
+ {
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+
+ schema >> sources >> schema;
+ schema >> *this;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+
+ schema >> schema_names >> ns >> ns_names;
+
+ Global global (root_, s, failed_);
+
+ ns_names >> global;
+
+ s.context ().set ("processing-inheritance-seen", true);
+ schema.dispatch (s);
+ }
+ }
+
+ private:
+ SemanticGraph::Schema& root_;
+ Boolean& failed_;
+ };
+ }
+
+ Void Processor::
+ process (SemanticGraph::Schema& tu, SemanticGraph::Path const&)
+ {
+ Boolean failed (false);
+
+ // We need to process include/imported schemas since other
+ // parts of the process, for example, name processors can
+ // rely on the order of types in the schema.
+ //
+ Traversal::Schema schema;
+ Traversal::Sources sources;
+ Uses uses (tu, failed);
+
+ schema >> sources >> schema;
+ schema >> uses;
+
+ Traversal::Names schema_names;
+ Traversal::Namespace ns;
+ Traversal::Names ns_names;
+
+ schema >> schema_names >> ns >> ns_names;
+
+ Global global (tu, tu, failed);
+
+ ns_names >> global;
+
+ // Some twisted schemas do recusive self-inclusion.
+ //
+ tu.context ().set ("processing-inheritance-seen", true);
+
+ schema.dispatch (tu);
+
+ if (failed)
+ throw Failed ();
+ }
+ }
+}
diff --git a/xsd/processing/inheritance/processor.hxx b/xsd/processing/inheritance/processor.hxx
new file mode 100644
index 0000000..ee0743d
--- /dev/null
+++ b/xsd/processing/inheritance/processor.hxx
@@ -0,0 +1,32 @@
+// file : processing/inheritance/processor.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2006-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef PROCESSING_INHERITANCE_PROCESSOR_HXX
+#define PROCESSING_INHERITANCE_PROCESSOR_HXX
+
+#include <cult/types.hxx>
+
+#include <xsd-frontend/semantic-graph/elements.hxx> // Path
+#include <xsd-frontend/semantic-graph/schema.hxx>
+
+namespace Processing
+{
+ namespace Inheritance
+ {
+ using namespace Cult::Types;
+
+ class Processor
+ {
+ public:
+ struct Failed {};
+
+ Void
+ process (XSDFrontend::SemanticGraph::Schema&,
+ XSDFrontend::SemanticGraph::Path const& file);
+ };
+ }
+}
+
+#endif // PROCESSING_INHERITANCE_PROCESSOR_HXX
diff --git a/xsd/type-map/lexer.cxx b/xsd/type-map/lexer.cxx
new file mode 100644
index 0000000..4376730
--- /dev/null
+++ b/xsd/type-map/lexer.cxx
@@ -0,0 +1,133 @@
+// file : xsd/type-map/lexer.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2007-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <iostream>
+
+#include <type-map/lexer.hxx>
+
+using std::wcerr;
+using std::endl;
+
+namespace TypeMap
+{
+ Lexer::Lexer (std::istream& is, String const& path)
+ : locale_ ("C"), is_ (is), path_ (path), line_ (1), comment_ (false)
+ {
+ is_.exceptions (std::ios_base::badbit);
+ }
+
+ Lexer::Token Lexer::
+ next ()
+ {
+ if (held_lexeme_)
+ {
+ Token t (Token::punct, held_lexeme_, line_);
+ held_lexeme_.clear ();
+ return t;
+ }
+
+ typedef std::char_traits<char> Traits;
+ typedef Traits::char_type CharType;
+ typedef Traits::int_type IntType;
+
+ IntType i;
+ CharType c ('\0');
+ NarrowString lexeme;
+
+ // Skip all whitespaces including comments.
+ //
+ while (!is_.eof ())
+ {
+ i = is_.get ();
+
+ if (i == Traits::eof ())
+ break;
+
+ c = Traits::to_char_type (i);
+
+ if (comment_)
+ {
+ if (c == '\n')
+ comment_ = false;
+ }
+ else
+ {
+ if (!(std::isspace (c, locale_) || c == '#'))
+ break;
+
+ if (c == '#')
+ comment_ = true;
+ }
+
+ if (c == '\n')
+ ++line_;
+ }
+
+ if (is_.eof ())
+ return Token (Token::eos, L"<end-of-stream>", line_);
+
+ Boolean quote (c == '"');
+
+ if (!quote)
+ lexeme += c;
+
+ if (c != ';' && c != '{' && c != '}')
+ {
+ // Accumulate non-whitespace character sequence.
+ //
+
+ while (!is_.eof ())
+ {
+ i = is_.get ();
+
+ if (i == Traits::eof ())
+ break;
+
+ c = Traits::to_char_type (i);
+
+ if (!quote && c == '#')
+ {
+ comment_ = true;
+ break;
+ }
+
+ if (std::isspace (c, locale_))
+ {
+ if (c == '\n')
+ ++line_;
+
+ if (!quote)
+ break;
+ }
+
+ if (!quote && (c == ';' || c == '{' || c == '}'))
+ {
+ held_lexeme_ += c;
+ break;
+ }
+
+ if (quote && c == '"')
+ break;
+
+ lexeme += c;
+ }
+
+ if (quote && c != '"')
+ {
+ wcerr << path_ << ":" << line_ << ": error: closing '\"' expected"
+ << endl;
+
+ throw Failed ();
+ }
+ }
+
+ if (!quote && (lexeme == ";" || lexeme == "{" || lexeme == "}"))
+ {
+ return Token (Token::punct, lexeme, line_);
+ }
+ else
+ return Token (Token::token, lexeme, line_);
+ }
+}
diff --git a/xsd/type-map/lexer.hxx b/xsd/type-map/lexer.hxx
new file mode 100644
index 0000000..2969e5d
--- /dev/null
+++ b/xsd/type-map/lexer.hxx
@@ -0,0 +1,80 @@
+// file : xsd/type-map/lexer.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2007-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_TYPE_MAP_LEXER_HXX
+#define XSD_TYPE_MAP_LEXER_HXX
+
+#include <locale>
+#include <iosfwd>
+
+#include <cult/types.hxx>
+
+namespace TypeMap
+{
+ using namespace Cult::Types;
+ typedef WideString String;
+
+ class Lexer
+ {
+ public:
+ class Token
+ {
+ public:
+ enum Type
+ {
+ token,
+ punct,
+ eos
+ };
+
+ Token (Type type, String const& lexeme, UnsignedLong line)
+ : type_ (type), lexeme_ (lexeme), line_ (line)
+ {
+ }
+
+ Type
+ type () const
+ {
+ return type_;
+ }
+
+ String const&
+ lexeme () const
+ {
+ return lexeme_;
+ }
+
+ UnsignedLong
+ line () const
+ {
+ return line_;
+ }
+
+ private:
+ Type type_;
+ String lexeme_;
+ UnsignedLong line_;
+ };
+
+ Lexer (std::istream&, String const& path);
+
+ struct Failed {};
+
+ Token
+ next ();
+
+ private:
+ std::locale locale_;
+ std::istream& is_;
+ String path_;
+ UnsignedLong line_;
+ String held_lexeme_;
+ Boolean comment_;
+ };
+
+}
+
+#endif // XSD_TYPE_MAP_LEXER_HXX
+
diff --git a/xsd/type-map/parser.cxx b/xsd/type-map/parser.cxx
new file mode 100644
index 0000000..9bf1576
--- /dev/null
+++ b/xsd/type-map/parser.cxx
@@ -0,0 +1,281 @@
+// file : xsd/type-map/parser.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2007-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <iostream>
+
+#include <backend-elements/regex.hxx>
+
+#include <type-map/parser.hxx>
+
+using std::endl;
+
+namespace TypeMap
+{
+ typedef Lexer::Token Token;
+ typedef BackendElements::Regex::Format<WideChar> Format;
+
+ Parser::Parser (Lexer& lex, String const& path)
+ : lex_ (lex), path_ (path), e (std::wcerr)
+ {
+ }
+
+ Boolean Parser::
+ parse (Namespaces& ns)
+ {
+ try
+ {
+ Namespace* global = 0;
+
+ for (Token t (lex_.next ()); t.type () != Token::eos; t = lex_.next ())
+ {
+ String l (t.lexeme ());
+
+ if (l == L"namespace")
+ {
+ global = 0;
+
+ if (!namespace_ (ns))
+ return false;
+ }
+ else if (l == L"include")
+ {
+ if (global == 0)
+ {
+ ns.push_back (Namespace (Pattern ()));
+ global = &(*ns.rbegin ());
+ }
+
+ if (!include (*global))
+ return false;
+ }
+ else if (l == L"type" || t.type () == Token::token)
+ {
+ // Type mapping can have 'type' specifier omitted.
+ //
+ if (l == L"type")
+ t = lex_.next ();
+
+ if (global == 0)
+ {
+ ns.push_back (Namespace (Pattern ()));
+ global = &(*ns.rbegin ());
+ }
+
+ if (!type (t, *global))
+ return false;
+ }
+ else
+ {
+ e << path_ << ":" << t.line () << ": unexpected '" << l << "'"
+ << endl;
+
+ return false;
+ }
+ }
+ }
+ catch (Lexer::Failed const&)
+ {
+ return false;
+ }
+
+ return true;
+ }
+
+ Boolean Parser::
+ namespace_ (Namespaces& ns)
+ {
+ // First get XML namespace.
+ //
+ Token t (lex_.next ());
+
+ Pattern xsd_name;
+
+ try
+ {
+ xsd_name = t.lexeme ();
+ }
+ catch (Format const& ex)
+ {
+ e << path_ << ":" << t.line () << ": invalid namespace pattern: "
+ << ex.description () << endl;
+ return false;
+ }
+
+ if (t.type () != Token::token)
+ {
+ e << path_ << ":" << t.line () << ": expected XML namespace "
+ << "instead of '" << xsd_name << "'" << endl;
+ return false;
+ }
+
+
+ // See if we've got optional C++ mapping.
+ //
+ t = lex_.next ();
+
+ Boolean has_cxx_name (false);
+ String cxx_name;
+
+ if (t.type () != Token::token)
+ {
+ if (t.lexeme () != L"{")
+ {
+ e << path_ << ":" << t.line () << ": expected C++ namespace or '{' "
+ << "instead of '" << t.lexeme () << "'" << endl;
+ return false;
+ }
+ }
+ else
+ {
+ has_cxx_name = true;
+ cxx_name = t.lexeme ();
+ }
+
+ // Swallow '{' if needed.
+ //
+ if (has_cxx_name)
+ {
+ t = lex_.next ();
+
+ if (t.type () != Token::punct || t.lexeme () != L"{")
+ {
+ e << path_ << ":" << t.line () << ": expected '{' instead of '"
+ << t.lexeme () << "'" << endl;
+ return false;
+ }
+ }
+
+ Namespace n (xsd_name, has_cxx_name, cxx_name);
+
+ // Parse namespace body.
+ //
+ for (t = lex_.next ();; t = lex_.next ())
+ {
+ String l (t.lexeme ());
+
+ if (l == L"include")
+ {
+ if (!include (n))
+ return false;
+ }
+ else if (l == L"type" || t.type () == Token::token)
+ {
+ // Type mapping can have 'type' specifier omitted.
+ //
+ if (l == L"type")
+ t = lex_.next ();
+
+ if (!type (t, n))
+ return false;
+ }
+ else if (t.type () == Token::punct && l == L"}")
+ {
+ break;
+ }
+ else
+ {
+ e << path_ << ":" << t.line () << ": unexpected '" << l << "'"
+ << endl;
+ return false;
+ }
+ }
+
+ if (cxx_name || n.types_begin () != n.types_end () ||
+ n.includes_begin () != n.includes_end ())
+ {
+ ns.push_back (n);
+ }
+
+ return true;
+ }
+
+ Boolean Parser::
+ include (Namespace& n)
+ {
+ Token t (lex_.next ());
+
+ String path (t.lexeme ());
+
+ if (t.type () != Token::token)
+ {
+ e << path_ << ":" << t.line () << ": expected include path "
+ << "instead of '" << path << "'" << endl;
+ return false;
+ }
+
+ if (path && path[0] == L'<')
+ n.includes_push_back (path);
+ else
+ n.includes_push_back (L'"' + path + L'"');
+
+ t = lex_.next ();
+
+ if (t.type () != Token::punct || t.lexeme () != L";")
+ {
+ e << path_ << ":" << t.line () << ": expected ';' after '"
+ << path << "'" << endl;
+ return false;
+ }
+
+ return true;
+ }
+
+ Boolean Parser::
+ type (Token t, Namespace& n)
+ {
+ Pattern xsd_name;
+
+ try
+ {
+ xsd_name = t.lexeme ();
+ }
+ catch (Format const& ex)
+ {
+ e << path_ << ":" << t.line () << ": invalid namespace pattern: "
+ << ex.description () << endl;
+ return false;
+ }
+
+ if (t.type () != Token::token)
+ {
+ e << path_ << ":" << t.line () << ": expected XML Schema type name "
+ << "instead of '" << xsd_name << "'" << endl;
+ return false;
+ }
+
+ t = lex_.next ();
+ String cxx_ret_name (t.lexeme ());
+
+ if (t.type () != Token::token)
+ {
+ e << path_ << ":" << t.line () << ": expected C++ type name "
+ << "instead of '" << cxx_ret_name << "'" << endl;
+ return false;
+ }
+
+ t = lex_.next ();
+
+ String cxx_arg_name;
+
+ // See if we've got optional argument type.
+ //
+ if (t.type () == Token::token)
+ {
+ cxx_arg_name = t.lexeme ();
+ t = lex_.next ();
+ }
+
+ if (t.type () != Token::punct || t.lexeme () != L";")
+ {
+ e << path_ << ":" << t.line () << ": expected ';' after '"
+ << cxx_arg_name << "'" << endl;
+ return false;
+ }
+
+ n.types_push_back (xsd_name, cxx_ret_name, cxx_arg_name);
+
+ return true;
+ }
+}
diff --git a/xsd/type-map/parser.hxx b/xsd/type-map/parser.hxx
new file mode 100644
index 0000000..514ad86
--- /dev/null
+++ b/xsd/type-map/parser.hxx
@@ -0,0 +1,46 @@
+// file : xsd/type-map/parser.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2007-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_TYPE_MAP_PARSER_HXX
+#define XSD_TYPE_MAP_PARSER_HXX
+
+#include <cult/types.hxx>
+
+#include <type-map/type-map.hxx>
+#include <type-map/lexer.hxx>
+
+namespace TypeMap
+{
+ using namespace Cult::Types;
+ typedef WideString String;
+
+ class Parser
+ {
+ public:
+ Parser (Lexer&, String const& path);
+
+ // Merge parsed namespaces.
+ //
+ Boolean
+ parse (Namespaces&);
+
+ private:
+ Boolean
+ namespace_ (Namespaces&);
+
+ Boolean
+ include (Namespace&);
+
+ Boolean
+ type (Lexer::Token, Namespace&);
+
+ private:
+ Lexer& lex_;
+ String path_;
+ std::wostream& e;
+ };
+}
+
+#endif // XSD_TYPE_MAP_PARSER_HXX
diff --git a/xsd/type-map/type-map.hxx b/xsd/type-map/type-map.hxx
new file mode 100644
index 0000000..b9b0d5c
--- /dev/null
+++ b/xsd/type-map/type-map.hxx
@@ -0,0 +1,160 @@
+// file : xsd/type-map/type-map.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2007-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_TYPE_MAP_TYPE_MAP_HXX
+#define XSD_TYPE_MAP_TYPE_MAP_HXX
+
+#include <cult/types.hxx>
+#include <cult/containers/vector.hxx>
+
+#include <backend-elements/regex.hxx>
+
+namespace TypeMap
+{
+ using namespace Cult::Types;
+ typedef WideString String;
+ typedef BackendElements::Regex::Pattern<WideChar> Pattern;
+
+ class Type
+ {
+ public:
+ Type (Pattern const& xsd_name,
+ String const& cxx_ret_name,
+ String const& cxx_arg_name)
+ : xsd_name_ (xsd_name),
+ cxx_ret_name_ (cxx_ret_name),
+ cxx_arg_name_ (cxx_arg_name)
+ {
+ }
+
+ Pattern const&
+ xsd_name () const
+ {
+ return xsd_name_;
+ }
+
+ String const&
+ cxx_ret_name () const
+ {
+ return cxx_ret_name_;
+ }
+
+ String const&
+ cxx_arg_name () const
+ {
+ return cxx_arg_name_;
+ }
+
+ private:
+ Pattern xsd_name_;
+ String cxx_ret_name_;
+ String cxx_arg_name_;
+ };
+
+ class Namespace
+ {
+ public:
+ Namespace (Pattern const& xsd_name)
+ : xsd_name_ (xsd_name), has_cxx_name_ (false)
+ {
+ }
+
+ Namespace (Pattern const& xsd_name, String const& cxx_name)
+ : xsd_name_ (xsd_name), has_cxx_name_ (true), cxx_name_ (cxx_name)
+ {
+ }
+
+ Namespace (Pattern const& xsd_name,
+ Boolean has_cxx_name,
+ String const& cxx_name)
+ : xsd_name_ (xsd_name),
+ has_cxx_name_ (has_cxx_name),
+ cxx_name_ (cxx_name)
+ {
+ }
+
+ //
+ //
+ typedef Cult::Containers::Vector<String> Includes;
+ typedef Includes::ConstIterator IncludesIterator;
+
+ IncludesIterator
+ includes_begin () const
+ {
+ return includes_.begin ();
+ }
+
+ IncludesIterator
+ includes_end () const
+ {
+ return includes_.end ();
+ }
+
+ Void
+ includes_push_back (String const& i)
+ {
+ includes_.push_back (i);
+ }
+
+ //
+ //
+ typedef Cult::Containers::Vector<Type> Types;
+ typedef Types::ConstIterator TypesIterator;
+
+ TypesIterator
+ types_begin () const
+ {
+ return types_.begin ();
+ }
+
+ TypesIterator
+ types_end () const
+ {
+ return types_.end ();
+ }
+
+ Void
+ types_push_back (Pattern const& xsd_type,
+ String const& cxx_ret_type,
+ String const& cxx_arg_type = L"")
+ {
+ types_.push_back (Type (xsd_type, cxx_ret_type, cxx_arg_type));
+ }
+
+ //
+ //
+ Pattern const&
+ xsd_name () const
+ {
+ return xsd_name_;
+ }
+
+ //
+ //
+ Boolean
+ has_cxx_name () const
+ {
+ return has_cxx_name_;
+ }
+
+ String const&
+ cxx_name () const
+ {
+ return cxx_name_;
+ }
+
+ private:
+ Includes includes_;
+ Types types_;
+ Pattern xsd_name_;
+ Boolean has_cxx_name_;
+ String cxx_name_;
+ };
+
+ typedef Cult::Containers::Vector<Namespace> Namespaces;
+}
+
+#endif // XSD_TYPE_MAP_TYPE_MAP_HXX
+
diff --git a/xsd/usage.hxx b/xsd/usage.hxx
new file mode 100644
index 0000000..5107a96
--- /dev/null
+++ b/xsd/usage.hxx
@@ -0,0 +1,226 @@
+// file : xsd/usage.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef USAGE_HXX
+#define USAGE_HXX
+
+#include <cult/types.hxx>
+
+#include <backend-elements/indentation/buffer.hxx>
+#include <backend-elements/indentation/clip.hxx>
+
+namespace CLI
+{
+ using namespace Cult::Types;
+
+ template <typename C>
+ class OptionsUsage: public BackendElements::Indentation::Buffer<C>
+ {
+ typedef BackendElements::Indentation::Buffer<C> Buffer;
+
+ public:
+ typedef
+ typename Buffer::Traits
+ Traits;
+
+ typedef
+ typename Buffer::AsChar
+ AsChar;
+
+ typedef
+ typename Buffer::AsInt
+ AsInt;
+
+ typedef
+ typename Buffer::Write
+ Write;
+
+ public:
+ OptionsUsage (Buffer& out)
+ : out_ (out),
+ option_length_ (0),
+ construct_ (Construct::newline)
+ {
+ }
+
+ public:
+ virtual AsInt
+ put (AsChar c)
+ {
+ AsInt result (Traits::to_int_type (c));
+
+ try
+ {
+ switch (c)
+ {
+ case '\n':
+ {
+ switch (construct_)
+ {
+ case Construct::newline:
+ {
+ result = out_.put (c);
+ break;
+ }
+ case Construct::option:
+ {
+ construct_ = Construct::newline;
+ break;
+ }
+ case Construct::description:
+ {
+ result = out_.put (c);
+ construct_ = Construct::newline;
+ break;
+ }
+ default:
+ {
+ abort ();
+ }
+ }
+
+ break;
+ }
+ case '-':
+ {
+ switch (construct_)
+ {
+ case Construct::newline:
+ {
+ construct_ = Construct::option;
+
+ option_length_ = 0;
+
+ output_indentation ();
+ result = out_.put (c);
+
+ ++option_length_;
+
+ break;
+ }
+ case Construct::option:
+ {
+ ++option_length_;
+ //fall through
+ }
+ case Construct::description:
+ {
+ result = out_.put (c);
+ break;
+ }
+ default:
+ {
+ abort ();
+ }
+ }
+
+ break;
+ }
+ default:
+ {
+ switch (construct_)
+ {
+ case Construct::newline:
+ {
+ construct_ = Construct::description;
+
+ output_indentation ();
+
+ result = out_.put (c);
+ break;
+ }
+ case Construct::option:
+ {
+ ++option_length_;
+ //fall through
+ }
+ default:
+ {
+ result = out_.put (c);
+ break;
+ }
+ }
+
+ break;
+ }
+ }
+ }
+ catch (Write const&)
+ {
+ result = Traits::eof ();
+ }
+
+ return result;
+ }
+
+ virtual Void
+ unbuffer ()
+ {
+ }
+
+ private:
+ Void
+ output_indentation ()
+ {
+ UnsignedLong spaces;
+
+ switch (construct_)
+ {
+ case Construct::option:
+ {
+ spaces = 2;
+ option_length_ += 2;
+ break;
+ }
+ case Construct::description:
+ {
+ spaces = 29;
+
+ if (option_length_)
+ {
+ if (option_length_ > spaces)
+ spaces = 1;
+ else
+ spaces -= option_length_;
+
+ option_length_ = 0;
+ }
+
+ break;
+ }
+ default:
+ {
+ abort ();
+ }
+ }
+
+ while (spaces--)
+ out_.put (' ');
+ }
+
+ private:
+ Buffer& out_;
+ UnsignedLong option_length_;
+
+ struct Construct
+ {
+ enum Value
+ {
+ newline,
+ option,
+ description
+ };
+ };
+
+ typename Construct::Value construct_;
+ };
+
+ //@@ rename Indentation to Indent in be?
+ //
+ namespace Indent = BackendElements::Indentation;
+}
+
+#endif // USAGE_HXX
+
diff --git a/xsd/xsd.cxx b/xsd/xsd.cxx
new file mode 100644
index 0000000..7aa18e6
--- /dev/null
+++ b/xsd/xsd.cxx
@@ -0,0 +1,1219 @@
+// file : xsd/xsd.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#include <cult/types.hxx>
+
+#include <cult/trace/log.hxx>
+
+#include <cult/containers/map.hxx>
+#include <cult/containers/vector.hxx>
+
+#include <cult/cli/exceptions.hxx>
+#include <cult/cli/file-arguments.hxx>
+#include <cult/cli/options.hxx>
+#include <cult/cli/options-spec.hxx>
+#include <cult/cli/options-parser.hxx>
+
+#include <xsd-frontend/parser.hxx>
+#include <xsd-frontend/transformations/anonymous.hxx>
+#include <xsd-frontend/transformations/restriction.hxx>
+#include <xsd-frontend/transformations/schema-per-type.hxx>
+#include <xsd-frontend/transformations/simplifier.hxx>
+
+#include <backend-elements/regex.hxx>
+#include <backend-elements/indentation/clip.hxx>
+
+#include <cxx/tree/generator.hxx>
+#include <cxx/parser/generator.hxx>
+
+#include <processing/cardinality/processor.hxx>
+#include <processing/inheritance/processor.hxx>
+
+#include <iostream>
+#include <boost/filesystem/fstream.hpp>
+
+#include <xsd.hxx>
+#include <usage.hxx>
+
+#include "../libxsd/xsd/cxx/version.hxx"
+
+using namespace Cult::Types;
+
+typedef Cult::Containers::Vector<NarrowString> NarrowStrings;
+
+namespace SemanticGraph = XSDFrontend::SemanticGraph;
+namespace Transformations = XSDFrontend::Transformations;
+
+using std::wcerr;
+using std::endl;
+
+namespace CLI
+{
+ using namespace Cult::CLI;
+
+ typedef Char const Key[];
+
+ extern Key help = "help";
+ extern Key version = "version";
+ extern Key proprietary_license = "proprietary-license";
+
+ typedef Cult::CLI::Options
+ <
+ help, Boolean,
+ version, Boolean,
+ proprietary_license, Boolean
+ >
+ HelpOptions;
+
+ struct HelpOptionsSpec: Cult::CLI::OptionsSpec<HelpOptions> {};
+
+
+ extern Key disable_warning = "disable-warning";
+ extern Key sloc_limit = "sloc-limit";
+ extern Key morph_anonymous = "morph-anonymous";
+ extern Key preserve_anonymous = "preserve-anonymous";
+ extern Key anonymous_regex = "anonymous-regex";
+ extern Key anonymous_regex_trace = "anonymous-regex-trace";
+ extern Key location_map = "location-map";
+ extern Key location_regex = "location-regex";
+ extern Key location_regex_trace = "location-regex-trace";
+ extern Key file_per_type = "file-per-type";
+ extern Key type_file_regex = "type-file-regex";
+ extern Key type_file_regex_trace = "type-file-regex-trace";
+ extern Key file_list = "file-list";
+ extern Key file_list_prologue = "file-list-prologue";
+ extern Key file_list_epilogue = "file-list-epilogue";
+ extern Key file_list_delim = "file-list-delim";
+ extern Key disable_multi_import = "disable-multi-import"; // Undocumented.
+ extern Key disable_full_check = "disable-full-check"; // Undocumented.
+
+
+ typedef Cult::CLI::Options
+ <
+ disable_warning, Cult::Containers::Vector<NarrowString>,
+ sloc_limit, UnsignedLong,
+ morph_anonymous, Boolean,
+ preserve_anonymous, Boolean,
+ anonymous_regex, NarrowStrings,
+ anonymous_regex_trace, Boolean,
+ location_map, NarrowStrings,
+ location_regex, NarrowStrings,
+ location_regex_trace, Boolean,
+ file_per_type, Boolean,
+ type_file_regex, NarrowStrings,
+ type_file_regex_trace, Boolean,
+ file_list, NarrowString,
+ file_list_prologue, NarrowString,
+ file_list_epilogue, NarrowString,
+ file_list_delim, NarrowString,
+ disable_multi_import, Boolean,
+ disable_full_check, Boolean
+ >
+ CommonOptions;
+
+ struct CommonOptionsSpec: Cult::CLI::OptionsSpec<CommonOptions> {};
+}
+
+//
+//
+struct LocationTranslator: XSDFrontend::LocationTranslator
+{
+ struct Failed {};
+
+ LocationTranslator (NarrowStrings const& map,
+ NarrowStrings const& regex,
+ Boolean trace);
+
+ virtual NarrowString
+ translate (NarrowString const&);
+
+private:
+ typedef Cult::Containers::Map<NarrowString, NarrowString> Map;
+
+ typedef BackendElements::Regex::Expression<Char> Regex;
+ typedef BackendElements::Regex::Format<Char> RegexFormat;
+ typedef Cult::Containers::Vector<Regex> RegexVector;
+
+ typedef Cult::Containers::Map<NarrowString, NarrowString> Cache;
+
+ Map map_;
+ RegexVector regex_;
+ Cache cache_;
+ Boolean trace_;
+};
+
+//
+//
+struct AnonymousNameTranslator: Transformations::AnonymousNameTranslator
+{
+ struct Failed {};
+
+ AnonymousNameTranslator (NarrowStrings const& regex, Boolean trace);
+
+ virtual WideString
+ translate (WideString const& file,
+ WideString const& ns,
+ WideString const& name,
+ WideString const& xpath);
+
+private:
+ typedef BackendElements::Regex::Expression<WideChar> Regex;
+ typedef BackendElements::Regex::Format<WideChar> RegexFormat;
+ typedef Cult::Containers::Vector<Regex> RegexVector;
+
+ RegexVector regex_;
+ Boolean trace_;
+
+};
+
+//
+//
+struct TypeSchemaTranslator: Transformations::TypeSchemaTranslator
+{
+ struct Failed {};
+
+ TypeSchemaTranslator (NarrowStrings const& regex, Boolean trace);
+
+ virtual WideString
+ translate (WideString const& ns, WideString const& name);
+
+private:
+ typedef BackendElements::Regex::Expression<WideChar> Regex;
+ typedef BackendElements::Regex::Format<WideChar> RegexFormat;
+ typedef Cult::Containers::Vector<Regex> RegexVector;
+
+ RegexVector regex_;
+ Boolean trace_;
+};
+
+// Expand the \n escape sequence.
+//
+Void
+expand_nl (NarrowString& s);
+
+Int
+main (Int argc, Char* argv[])
+{
+ std::wostream& e (wcerr);
+
+ Cult::Trace::Log::instance ().level (0);
+
+ try
+ {
+ CLI::FileArguments args (argc, argv, "--options-file");
+
+ CLI::HelpOptions help_options (
+ CLI::parse (CLI::HelpOptionsSpec (), args, CLI::UnknownMode::stop));
+
+ NarrowString cmd;
+
+ if (args.size () > 1)
+ {
+ cmd = args[1];
+ args.erase (1);
+ }
+
+ if (help_options.value<CLI::version> () || cmd == "version")
+ {
+ e << "CodeSynthesis XSD XML Schema to C++ compiler " <<
+ XSD_STR_VERSION << endl
+ << "Copyright (C) 2005-2009 Code Synthesis Tools CC" << endl;
+
+ if (!help_options.value<CLI::proprietary_license> () &&
+ cmd == "version")
+ {
+ // Parse the options after the command to detect trailing
+ // --proprietary-license.
+ //
+ help_options = CLI::parse (
+ CLI::HelpOptionsSpec (), args, CLI::UnknownMode::stop);
+ }
+
+ if (help_options.value<CLI::proprietary_license> ())
+ {
+ e << "The compiler was invoked in the Proprietary License mode. You "
+ << "should have\nreceived a proprietary license from Code Synthesis "
+ << "Tools CC that entitles\nyou to use it in this mode." << endl;
+ }
+ else
+ {
+ e << "This is free software; see the source for copying conditions. "
+ << "There is NO\nwarranty; not even for MERCHANTABILITY or FITNESS "
+ << "FOR A PARTICULAR PURPOSE." << endl;
+ }
+
+ return 0;
+ }
+
+ if (help_options.value<CLI::help> () || cmd == "help")
+ {
+ if (cmd == "help" && args.size () > 1)
+ {
+ NarrowString arg (args[1]);
+
+ if (arg == "cxx-tree")
+ {
+ e << "Usage: " << args[0] << " cxx-tree [options] file [file ...]"
+ << endl
+ << "Options:" << endl;
+
+ CXX::Tree::Generator::usage ();
+ }
+ else if (arg == "cxx-parser")
+ {
+ e << "Usage: " << args[0] << " cxx-parser [options] file [file ...]"
+ << endl
+ << "Options:" << endl;
+
+ CXX::Parser::Generator::usage ();
+ }
+ else
+ {
+ e << "error: unknown command '" << arg.c_str () << "'" << endl
+ << "info: try '" << args[0] << " help' for the list of commands"
+ << endl;
+
+ return 1;
+ }
+
+ ::CLI::Indent::Clip< ::CLI::OptionsUsage, WideChar> clip (e);
+
+ // Disable warning option.
+ //
+ e << "--disable-warning <warn>" << endl
+ << " Disable printing warning with id <warn>. If 'all'\n"
+ << " is specified for the warning id then all warnings\n"
+ << " are disabled."
+ << endl;
+
+ // Anonymous morphing options.
+ //
+ e << "--preserve-anonymous" << endl
+ << " Preserve anonymous types. By default anonymous\n"
+ << " types are automatically named with names derived\n"
+ << " from the enclosing elements/attributes."
+ << endl;
+
+ e << "--anonymous-regex <regex>" << endl
+ << " Add the provided regular expression to the list of\n"
+ << " regular expressions used to derive names for\n"
+ << " anonymous types from the names of the enclosing\n"
+ << " attributes/elements."
+ << endl;
+
+ e << "--anonymous-regex-trace" << endl
+ << " Trace the process of applying regular expressions\n"
+ << " specified with the --anonymous-regex option."
+ << endl;
+
+ // Location mapping options.
+ //
+ e << "--location-map <ol>=<nl>" << endl
+ << " Map the original schema location <ol> that is\n"
+ << " specified in the XML Schema include or import\n"
+ << " elements to new schema location <nl>. Repeat\n"
+ << " this option to map more than one schema location."
+ << endl;
+
+ e << "--location-regex <regex>" << endl
+ << " Add <regex> to the list of regular expressions\n"
+ << " used to map schema locations that are specified\n"
+ << " in the XML Schema include or import elements."
+ << endl;
+
+ e << "--location-regex-trace" << endl
+ << " Trace the process of applying regular expressions\n"
+ << " specified with the --location-regex option."
+ << endl;
+
+ // File-per-type compilation mode options.
+ //
+ e << "--file-per-type" << endl
+ << " Generate a separate set of C++ files for each\n"
+ << " type defined in XML Schema."
+ << endl;
+
+ e << "--type-file-regex <regex>" << endl
+ << " Add the provided regular expression to the list of\n"
+ << " regular expressions used to translate type names\n"
+ << " to file names when the --type-per-file option is\n"
+ << " specified."
+ << endl;
+
+ e << "--type-file-regex-trace" << endl
+ << " Trace the process of applying regular expressions\n"
+ << " specified with the --type-file-regex option."
+ << endl;
+
+ // File list options.
+ //
+ e << "--file-list <file>" << endl
+ << " Write a list of generated C++ files to <file>."
+ << endl;
+
+ e << "--file-list-prologue <p>" << endl
+ << " Insert <p> at the beginning of the file list. All\n"
+ << " occurrences of the \\n character sequence in <p>\n"
+ << " are replaced with new lines."
+ << endl;
+
+ e << "--file-list-prologue <e>" << endl
+ << " Insert <e> at the end of the file list. All\n"
+ << " occurrences of the \\n character sequence in <e>\n"
+ << " are replaced with new lines."
+ << endl;
+
+ e << "--file-list-delim <d>" << endl
+ << " Delimit file names written to the file list with\n"
+ << " <d> instead of new lines. All occurrences of the\n"
+ << " \\n character sequence in <d> are replaced with\n"
+ << " new lines."
+ << endl;
+ }
+ else
+ {
+ e << "Usage: " << args[0] << " <cmd> ..." << endl
+ << "Commands:" << endl;
+
+ e << " help Print usage information and exit. Use\n"
+ << " 'help <cmd>' for command-specific options."
+ << endl;
+
+ e << " version Print version and exit."
+ << endl;
+
+ e << " cxx-tree Generate the C++/Tree mapping."
+ << endl;
+
+ e << " cxx-parser Generate the C++/Parser mapping."
+ << endl;
+ }
+
+ return 0;
+ }
+
+ if (cmd.empty ())
+ {
+ e << "error: no command specified" << endl
+ << "info: try '" << args[0] << " help' for usage information" << endl;
+
+ return 1;
+ }
+
+ if (cmd != "cxx-tree" && cmd != "cxx-parser")
+ {
+ e << "error: unknown command '" << cmd.c_str () << "'" << endl
+ << "info: try '" << args[0] << " help' for the list of commands"
+ << endl;
+
+ return 1;
+ }
+
+ // We need to parse command line options before we can get to
+ // the arguments.
+ //
+ CLI::CommonOptionsSpec common_spec;
+ common_spec.option<CLI::file_list_delim> ().default_value ("\n");
+
+ CLI::CommonOptions common_ops (
+ CLI::parse (
+ common_spec,
+ args,
+ CLI::UnknownMode::skip,
+ CLI::UnknownMode::skip));
+
+ WarningSet disabled_w;
+ {
+ typedef Cult::Containers::Vector<NarrowString> Warnings;
+ Warnings const& w (common_ops.value<CLI::disable_warning> ());
+
+ for (Warnings::ConstIterator i (w.begin ()); i != w.end (); ++i)
+ disabled_w.insert (*i);
+ }
+
+ Boolean disabled_w_all (disabled_w.find ("all") != disabled_w.end ());
+
+ if (common_ops.value<CLI::morph_anonymous> () &&
+ !disabled_w_all && disabled_w.find ("D001") == disabled_w.end ())
+ {
+ e << "warning D001: the --morph-anonymous option is on by default and "
+ << "no longer required"
+ << endl;
+ }
+
+ Evptr<CXX::Tree::CLI::Options> tree_ops;
+ Evptr<CXX::Parser::CLI::Options> parser_ops;
+
+ Boolean show_sloc (false);
+
+ if (cmd == "cxx-tree")
+ {
+ tree_ops = new CXX::Tree::CLI::Options (
+ CLI::parse (CXX::Tree::Generator::options_spec (), args));
+
+ tree_ops->value<CXX::Tree::CLI::disable_multi_import> () =
+ common_ops.value<CLI::disable_multi_import> ();
+
+ show_sloc = tree_ops->value<CXX::Tree::CLI::show_sloc> ();
+ }
+ else if (cmd == "cxx-parser")
+ {
+ parser_ops = new CXX::Parser::CLI::Options (
+ CLI::parse (CXX::Parser::Generator::options_spec (), args));
+
+ show_sloc = parser_ops->value<CXX::Parser::CLI::show_sloc> ();
+ }
+
+
+ if (args.size () < 2)
+ {
+ e << "error: no input file specified" << endl;
+ return 1;
+ }
+
+ Boolean fpt (common_ops.value<CLI::file_per_type> ());
+
+ if (cmd == "cxx-tree" || cmd == "cxx-parser")
+ {
+ Boolean gen (false), use (false);
+
+ if (cmd == "cxx-tree")
+ {
+ gen = tree_ops->value<CXX::Tree::CLI::generate_xml_schema> ();
+ use = tree_ops->value<CXX::Tree::CLI::extern_xml_schema> ();
+ }
+ else if (cmd == "cxx-parser")
+ {
+ gen = parser_ops->value<CXX::Parser::CLI::generate_xml_schema> ();
+ use = parser_ops->value<CXX::Parser::CLI::extern_xml_schema> ();
+ }
+
+ // Things get complicated when we are compiling several schemas at
+ // once (non-file-per-type mode) and use the --generate-xml-schema/
+ // --extern-xml-schema options. The only way we can figure out which
+ // file corresponds to XML Schema is if the --extern-xml-schema option
+ // is also present. So we are going to require it for this case,
+ // especially since it generally makes sense.
+ //
+ if (!fpt)
+ {
+ if (args.size () > 2 && gen && !use)
+ {
+ e << "error: --extern-xml-schema is required when compiling more "
+ << "than one schema and --generate-xml-schema is specified"
+ << endl;
+
+ return 1;
+ }
+
+ if (args.size () == 2 && gen && use)
+ {
+ e << "error: --generate-xml-schema and --extern-xml-schema are "
+ << "mutually exclusive when compiling a single schema" << endl;
+
+ return 1;
+ }
+ }
+ else
+ {
+ // The --file-per-type and --generate-xml-schema options are
+ // incompatible. It also makes sense to use --file-per-type
+ // and --extern-xml-schema.
+ //
+ if (gen)
+ {
+ e << "error: --file-per-type and --generate-xml-schema are "
+ << "incompatible" << endl
+ << "info: use --generate-xml-schema in a separate invocation "
+ << "of the compiler" << endl;
+
+ return 1;
+ }
+
+ if (!use &&
+ !disabled_w_all && disabled_w.find ("D002") == disabled_w.end ())
+ {
+ e << "warning D002: --extern-xml-schema is recommended when "
+ << "--file-per-type is specified to reduce generated code size"
+ << endl;
+ }
+ }
+ }
+
+ //
+ //
+ FileList file_list;
+ AutoUnlinks unlinks;
+ UnsignedLong sloc (0);
+
+ LocationTranslator loc_translator (
+ common_ops.value<CLI::location_map> (),
+ common_ops.value<CLI::location_regex> (),
+ common_ops.value<CLI::location_regex_trace> ());
+
+ AnonymousNameTranslator anon_translator (
+ common_ops.value<CLI::anonymous_regex> (),
+ common_ops.value<CLI::anonymous_regex_trace> ());
+
+ if (!fpt)
+ {
+ // File-per-schema compilation mode.
+ //
+
+ for (Size i (1); i < args.size (); ++i)
+ {
+ // Parse schema.
+ //
+ SemanticGraph::Path tu;
+
+ try
+ {
+ tu = SemanticGraph::Path (args[i], boost::filesystem::native);
+ }
+ catch (SemanticGraph::InvalidPath const&)
+ {
+ e << "error: '" << args[i] << "' is not a valid "
+ << "filesystem path" << endl;
+
+ return 1;
+ }
+
+ XSDFrontend::Parser parser (
+ cmd != "cxx-tree",
+ !common_ops.value<CLI::disable_multi_import> (),
+ !common_ops.value<CLI::disable_full_check> (),
+ loc_translator,
+ disabled_w);
+
+ Evptr<SemanticGraph::Schema> schema;
+
+ if (cmd == "cxx-tree" || cmd == "cxx-parser")
+ {
+ // See if we are generating code for the XML Schema namespace.
+ // We could be compiling several schemas at once in which case
+ // handling of the --generate-xml-schema option gets tricky: we
+ // will need to rely on the presence of the --extern-xml-schema
+ // to tell us which (fake) schema file corresponds to XML Schema.
+ //
+ Boolean gen_xml_schema (false);
+
+ if (cmd == "cxx-tree")
+ {
+ gen_xml_schema =
+ tree_ops->value<CXX::Tree::CLI::generate_xml_schema> ();
+
+ if (gen_xml_schema)
+ {
+ if (NarrowString name =
+ tree_ops->value<CXX::Tree::CLI::extern_xml_schema> ())
+ {
+ if (tu.native_file_string () != name)
+ gen_xml_schema = false;
+ }
+ }
+ }
+ else if (cmd == "cxx-parser")
+ {
+ gen_xml_schema =
+ parser_ops->value<CXX::Parser::CLI::generate_xml_schema> ();
+
+ if (gen_xml_schema)
+ {
+ if (NarrowString name =
+ parser_ops->value<CXX::Parser::CLI::extern_xml_schema> ())
+ {
+ if (tu.native_file_string () != name)
+ gen_xml_schema = false;
+ }
+ }
+ }
+
+ if (gen_xml_schema)
+ schema = parser.xml_schema (tu);
+ else
+ schema = parser.parse (tu);
+ }
+ else
+ schema = parser.parse (tu);
+
+ // Morph anonymous types.
+ //
+ if (!common_ops.value<CLI::preserve_anonymous> ())
+ {
+ try
+ {
+ Transformations::Anonymous trans (anon_translator);
+ trans.transform (*schema, tu, true);
+ }
+ catch (Transformations::Anonymous::Failed const&)
+ {
+ return 1; // Diagnostic has already been issued.
+ }
+ }
+
+ // Simplify the schema graph.
+ //
+ if (cmd == "cxx-parser")
+ {
+ Transformations::Simplifier trans;
+ trans.transform (*schema, tu);
+ }
+
+ // Try to rearrange definitions so that there is no forward
+ // inheritance.
+ //
+ try
+ {
+ Processing::Inheritance::Processor proc;
+ proc.process (*schema, tu);
+ }
+ catch (Processing::Inheritance::Processor::Failed const&)
+ {
+ return 1; // Diagnostic has already been issued.
+ }
+
+ // Normalize and annotate complex content restrictions.
+ //
+ if (cmd == "cxx-parser")
+ {
+ try
+ {
+ Transformations::Restriction trans;
+ trans.transform (*schema, tu);
+ }
+ catch (Transformations::Restriction::Failed const&)
+ {
+ return 1; // Diagnostic has already been issued.
+ }
+ }
+
+ // Calculate cardinality.
+ //
+ {
+ Processing::Cardinality::Processor proc;
+ proc.process (*schema, tu);
+ }
+
+ // Generate mapping.
+ //
+ if (cmd == "cxx-tree")
+ {
+ try
+ {
+ sloc += CXX::Tree::Generator::generate (
+ *tree_ops, *schema, tu, disabled_w, file_list, unlinks);
+ }
+ catch (CXX::Tree::Generator::Failed const&)
+ {
+ // Diagnostic has already been issued.
+ //
+ return 1;
+ }
+ }
+ else if (cmd == "cxx-parser")
+ {
+ try
+ {
+ sloc += CXX::Parser::Generator::generate (
+ *parser_ops, *schema, tu, true, disabled_w, file_list, unlinks);
+ }
+ catch (CXX::Parser::Generator::Failed const&)
+ {
+ // Diagnostic has already been issued.
+ //
+ return 1;
+ }
+ }
+ }
+ }
+ else
+ {
+ // File-per-type compilation mode.
+ //
+ SemanticGraph::Paths paths;
+
+ for (Size i (1); i < args.size (); ++i)
+ {
+ try
+ {
+ paths.push_back (
+ SemanticGraph::Path (args[i], boost::filesystem::native));
+ }
+ catch (SemanticGraph::InvalidPath const&)
+ {
+ e << "error: '" << args[i] << "' is not a valid "
+ << "filesystem path" << endl;
+
+ return 1;
+ }
+ }
+
+ if (cmd == "cxx-parser" &&
+ paths.size () > 1 &&
+ parser_ops->value<CXX::Parser::CLI::generate_test_driver> ())
+ {
+ e << "info: generating test driver for the first schema only: '" <<
+ paths[0] << "'" << endl;
+ }
+
+ XSDFrontend::Parser parser (
+ cmd != "cxx-tree",
+ !common_ops.value<CLI::disable_multi_import> (),
+ !common_ops.value<CLI::disable_full_check> (),
+ loc_translator,
+ disabled_w);
+
+ Evptr<SemanticGraph::Schema> schema (parser.parse (paths));
+
+ // Morph anonymous types.
+ //
+ if (!common_ops.value<CLI::preserve_anonymous> ())
+ {
+ try
+ {
+ Transformations::Anonymous trans (anon_translator);
+ trans.transform (*schema, "", false);
+ }
+ catch (Transformations::Anonymous::Failed const&)
+ {
+ return 1; // Diagnostic has already been issued.
+ }
+ }
+
+ // Simplify the schema graph.
+ //
+ if (cmd == "cxx-parser")
+ {
+ Transformations::Simplifier trans;
+ trans.transform (*schema, "");
+ }
+
+ // Normalize and annotate complex content restrictions.
+ //
+ if (cmd == "cxx-parser")
+ {
+ try
+ {
+ Transformations::Restriction trans;
+ trans.transform (*schema, "");
+ }
+ catch (Transformations::Restriction::Failed const&)
+ {
+ return 1; // Diagnostic has already been issued.
+ }
+ }
+
+ // Calculate cardinality.
+ //
+ {
+ Processing::Cardinality::Processor proc;
+ proc.process (*schema, "");
+ }
+
+ // Rearrange the graph so that each type is in a seperate
+ // schema file.
+ //
+ typedef Cult::Containers::Vector<SemanticGraph::Schema*> Schemas;
+
+ TypeSchemaTranslator type_translator (
+ common_ops.value<CLI::type_file_regex> (),
+ common_ops.value<CLI::type_file_regex_trace> ());
+
+ Transformations::SchemaPerType trans (type_translator);
+ Schemas schemas (trans.transform (*schema));
+
+ // Generate code.
+ //
+ for (Schemas::Iterator b (schemas.begin ()), i (b), e (schemas.end ());
+ i != e; ++i)
+ {
+ SemanticGraph::Schema& s (**i);
+ SemanticGraph::Path path (s.used_begin ()->path ());
+
+ if (cmd == "cxx-tree")
+ {
+ try
+ {
+ sloc += CXX::Tree::Generator::generate (
+ *tree_ops, s, path, disabled_w, file_list, unlinks);
+ }
+ catch (CXX::Tree::Generator::Failed const&)
+ {
+ // Diagnostic has already been issued.
+ //
+ return 1;
+ }
+ }
+ else if (cmd == "cxx-parser")
+ {
+ try
+ {
+ // Only generate driver for the first schema.
+ //
+ sloc += CXX::Parser::Generator::generate (
+ *parser_ops, s, path, i == b, disabled_w, file_list, unlinks);
+ }
+ catch (CXX::Parser::Generator::Failed const&)
+ {
+ // Diagnostic has already been issued.
+ //
+ return 1;
+ }
+ }
+ }
+ }
+
+ // See if we need to produce the file list.
+ //
+ if (NarrowString fl = common_ops.value<CLI::file_list> ())
+ {
+ typedef boost::filesystem::ofstream OutputFileStream;
+
+ try
+ {
+ OutputFileStream ofs;
+ SemanticGraph::Path path (fl);
+
+ ofs.open (fl, std::ios_base::out);
+
+ if (!ofs.is_open ())
+ {
+ wcerr << path << ": error: unable to open in write mode" << endl;
+ return 1;
+ }
+
+ NarrowString d (common_ops.value<CLI::file_list_delim> ());
+ expand_nl (d);
+
+ if (NarrowString p = common_ops.value<CLI::file_list_prologue> ())
+ {
+ expand_nl (p);
+ ofs << p;
+ }
+
+ for (FileList::Iterator i (file_list.begin ()), e (file_list.end ());
+ i != e;)
+ {
+ ofs << *i;
+
+ if (++i != e)
+ ofs << d;
+ }
+
+ if (NarrowString e = common_ops.value<CLI::file_list_epilogue> ())
+ {
+ expand_nl (e);
+ ofs << e;
+ }
+ }
+ catch (SemanticGraph::InvalidPath const&)
+ {
+ wcerr << "error: '" << fl.c_str () << "' is not a valid "
+ << "filesystem path" << endl;
+ return 1;
+ }
+ }
+
+ if (show_sloc)
+ e << "total: " << sloc << endl;
+
+ if (UnsignedLong sloc_limit = common_ops.value<CLI::sloc_limit> ())
+ {
+ if (sloc_limit < sloc)
+ {
+ e << "error: SLOC limit of " << sloc_limit
+ << " lines has been exceeded" << endl;
+
+ return 1;
+ }
+ }
+
+ unlinks.cancel ();
+
+ return 0;
+ }
+ catch (LocationTranslator::Failed const&)
+ {
+ // Diagnostic has already been issued.
+ }
+ catch (AnonymousNameTranslator::Failed const&)
+ {
+ // Diagnostic has already been issued.
+ }
+ catch (TypeSchemaTranslator::Failed const&)
+ {
+ // Diagnostic has already been issued.
+ }
+ catch (Transformations::SchemaPerType::Failed const&)
+ {
+ // Diagnostic has already been issued.
+ }
+ catch (XSDFrontend::InvalidSchema const&)
+ {
+ // Diagnostic has already been issued.
+ }
+ catch (CLI::UnexpectedOption const& e)
+ {
+ wcerr << "error: unknown option '" << e.option ().c_str () << "'" << endl
+ << "info: try '" << argv[0] << " help' for usage information"
+ << endl;
+ }
+ catch (CLI::OptionFormat const& e)
+ {
+ wcerr << "error: value for option '" << e.option ().c_str ()
+ << "' is invalid or missing" << endl
+ << "info: try '" << argv[0] << " help' for usage information"
+ << endl;
+ }
+ catch (CLI::OptionFile const& e)
+ {
+ if (e.value ())
+ wcerr << "error: " << e.value ().c_str () << ": "
+ << e.description ().c_str () << endl;
+ else
+ wcerr << "error: missing --options-file argument" << endl;
+ }
+
+ return 1;
+}
+
+// LocationTranslator
+//
+
+LocationTranslator::
+LocationTranslator (NarrowStrings const& map,
+ NarrowStrings const& regex,
+ Boolean trace)
+ : trace_ (trace)
+{
+ // Map.
+ //
+ for (NarrowStrings::ConstIterator i (map.begin ()); i != map.end (); ++i)
+ {
+ // Split the string in two parts at the last '='.
+ //
+ Size pos (i->rfind ('='));
+
+ if (pos == NarrowString::npos)
+ {
+ wcerr << "error: invalid location map: '" << i->c_str () <<
+ "': delimiter ('=') not found" << endl;
+
+ throw Failed ();
+ }
+
+ map_[NarrowString (*i, 0, pos)] = NarrowString (*i, pos + 1);
+ }
+
+ // Regex.
+ //
+ for (NarrowStrings::ConstIterator i (regex.begin ()); i != regex.end (); ++i)
+ {
+ try
+ {
+ regex_.push_back (Regex (*i));
+ }
+ catch (RegexFormat const& e)
+ {
+ wcerr << "error: invalid location regex: '" <<
+ e.expression ().c_str () << "': " <<
+ e.description ().c_str () << endl;
+
+ throw Failed ();
+ }
+ }
+}
+
+NarrowString LocationTranslator::
+translate (NarrowString const& l)
+{
+ // First check the cache.
+ //
+ Cache::ConstIterator ci (cache_.find (l));
+
+ if (ci != cache_.end ())
+ return ci->second;
+
+ // Then check the direct map.
+ //
+ Map::ConstIterator mi (map_.find (l));
+
+ if (mi != map_.end ())
+ {
+ cache_[l] = mi->second;
+ return mi->second;
+ }
+
+ // Finally try regex.
+ //
+ if (trace_)
+ wcerr << "location: '" << l.c_str () << "'" << endl;
+
+ for (RegexVector::ReverseIterator i (regex_.rbegin ());
+ i != regex_.rend (); ++i)
+ {
+ if (trace_)
+ wcerr << "try: '" << i->pattern () << "' : ";
+
+ if (i->match (l))
+ {
+ NarrowString r (i->merge (l));
+
+ if (trace_)
+ wcerr << "'" << r.c_str () << "' : +" << endl;
+
+ cache_[l] = r;
+ return r;
+ }
+
+ if (trace_)
+ wcerr << '-' << endl;
+ }
+
+ // No match - return the original location.
+ //
+ cache_[l] = l;
+ return l;
+}
+
+// AnonymousNameTranslator
+//
+
+AnonymousNameTranslator::
+AnonymousNameTranslator (NarrowStrings const& regex, Boolean trace)
+ : trace_ (trace)
+{
+ for (NarrowStrings::ConstIterator i (regex.begin ()); i != regex.end (); ++i)
+ {
+ try
+ {
+ regex_.push_back (Regex (*i));
+ }
+ catch (RegexFormat const& e)
+ {
+ wcerr << "error: invalid anonymous type regex: '" <<
+ e.expression () << "': " << e.description () << endl;
+
+ throw Failed ();
+ }
+ }
+}
+
+WideString AnonymousNameTranslator::
+translate (WideString const& file,
+ WideString const& ns,
+ WideString const& name,
+ WideString const& xpath)
+{
+ if (regex_.empty ())
+ return name;
+
+ WideString s (file + L' ' + ns + L' ' + xpath);
+
+ if (trace_)
+ wcerr << "anonymous type: '" << s << "'" << endl;
+
+ for (RegexVector::ReverseIterator i (regex_.rbegin ());
+ i != regex_.rend (); ++i)
+ {
+ if (trace_)
+ wcerr << "try: '" << i->pattern () << "' : ";
+
+ if (i->match (s))
+ {
+ WideString r (i->merge (s));
+
+ if (trace_)
+ wcerr << "'" << r << "' : +" << endl;
+
+ return r;
+ }
+
+ if (trace_)
+ wcerr << '-' << endl;
+ }
+
+ // No match - return the name.
+ //
+ return name;
+}
+
+// TypeSchemaTranslator
+//
+
+TypeSchemaTranslator::
+TypeSchemaTranslator (NarrowStrings const& regex, Boolean trace)
+ : trace_ (trace)
+{
+ for (NarrowStrings::ConstIterator i (regex.begin ()); i != regex.end (); ++i)
+ {
+ try
+ {
+ regex_.push_back (Regex (*i));
+ }
+ catch (RegexFormat const& e)
+ {
+ wcerr << "error: invalid type file regex: '" <<
+ e.expression () << "': " << e.description () << endl;
+
+ throw Failed ();
+ }
+ }
+}
+
+WideString TypeSchemaTranslator::
+translate (WideString const& ns, WideString const& name)
+{
+ if (regex_.empty ())
+ return name;
+
+ WideString s (ns + L' ' + name);
+
+ if (trace_)
+ wcerr << "type: '" << s << "'" << endl;
+
+ for (RegexVector::ReverseIterator i (regex_.rbegin ());
+ i != regex_.rend (); ++i)
+ {
+ if (trace_)
+ wcerr << "try: '" << i->pattern () << "' : ";
+
+ if (i->match (s))
+ {
+ WideString r (i->merge (s));
+
+ if (trace_)
+ wcerr << "'" << r << "' : +" << endl;
+
+ return r;
+ }
+
+ if (trace_)
+ wcerr << '-' << endl;
+ }
+
+ // No match - return the type name.
+ //
+ return name;
+}
+
+//
+//
+Void
+expand_nl (NarrowString& s)
+{
+ for (Size i (0); i < s.size ();)
+ {
+ if (s[i] == '\\' && (i + 1) < s.size () && s[i + 1] == 'n')
+ {
+ NarrowString tmp (s, 0, i);
+ tmp += '\n';
+ tmp.append (s.c_str () + i + 2);
+ s = tmp;
+ }
+ else
+ ++i;
+ }
+}
diff --git a/xsd/xsd.hxx b/xsd/xsd.hxx
new file mode 100644
index 0000000..f09b18d
--- /dev/null
+++ b/xsd/xsd.hxx
@@ -0,0 +1,80 @@
+// file : xsd/xsd.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : Copyright (c) 2005-2009 Code Synthesis Tools CC
+// license : GNU GPL v2 + exceptions; see accompanying LICENSE file
+
+#ifndef XSD_HXX
+#define XSD_HXX
+
+#include <xsd-frontend/semantic-graph/elements.hxx> // Path
+
+#include <cult/types.hxx>
+#include <cult/containers/set.hxx>
+#include <cult/containers/vector.hxx>
+
+
+#include <cstdio> // std::remove
+
+using namespace Cult::Types;
+
+//
+//
+typedef Cult::Containers::Set<NarrowString> WarningSet;
+
+//
+//
+typedef Cult::Containers::Vector<NarrowString> FileList;
+
+//
+//
+struct AutoUnlink
+{
+ AutoUnlink (XSDFrontend::SemanticGraph::Path const& file)
+ : file_ (file), canceled_ (false)
+ {
+ }
+
+ ~AutoUnlink ()
+ {
+ if (!canceled_)
+ {
+ std::remove (file_.native_file_string ().c_str ());
+ }
+ }
+
+ void
+ cancel ()
+ {
+ canceled_ = true;
+ }
+
+private:
+ XSDFrontend::SemanticGraph::Path file_;
+ Boolean canceled_;
+};
+
+//
+//
+struct AutoUnlinks
+{
+ Void
+ add (XSDFrontend::SemanticGraph::Path const& file)
+ {
+ unlinks_.push_back (Evptr<AutoUnlink> (new AutoUnlink (file)));
+ }
+
+ Void
+ cancel ()
+ {
+ for (Unlinks::Iterator i (unlinks_.begin ()); i != unlinks_.end (); ++i)
+ {
+ (*i)->cancel ();
+ }
+ }
+
+private:
+ typedef Cult::Containers::Vector<Evptr<AutoUnlink> > Unlinks;
+ Unlinks unlinks_;
+};
+
+#endif // XSD_HXX