From a8ce5c380c69539fe0c7c62c397634d9d0c9fde2 Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Fri, 18 Dec 2020 18:48:46 +0300 Subject: Switch to build2 --- xsd-examples/cxx/tree/custom/mixed/.gitignore | 1 + xsd-examples/cxx/tree/custom/mixed/README | 50 +++++++++ xsd-examples/cxx/tree/custom/mixed/buildfile | 30 +++++ xsd-examples/cxx/tree/custom/mixed/driver.cxx | 122 +++++++++++++++++++++ .../cxx/tree/custom/mixed/people-custom.cxx | 89 +++++++++++++++ .../cxx/tree/custom/mixed/people-custom.hxx | 83 ++++++++++++++ xsd-examples/cxx/tree/custom/mixed/people.xml | 38 +++++++ xsd-examples/cxx/tree/custom/mixed/people.xsd | 45 ++++++++ 8 files changed, 458 insertions(+) create mode 100644 xsd-examples/cxx/tree/custom/mixed/.gitignore create mode 100644 xsd-examples/cxx/tree/custom/mixed/README create mode 100644 xsd-examples/cxx/tree/custom/mixed/buildfile create mode 100644 xsd-examples/cxx/tree/custom/mixed/driver.cxx create mode 100644 xsd-examples/cxx/tree/custom/mixed/people-custom.cxx create mode 100644 xsd-examples/cxx/tree/custom/mixed/people-custom.hxx create mode 100644 xsd-examples/cxx/tree/custom/mixed/people.xml create mode 100644 xsd-examples/cxx/tree/custom/mixed/people.xsd (limited to 'xsd-examples/cxx/tree/custom/mixed') diff --git a/xsd-examples/cxx/tree/custom/mixed/.gitignore b/xsd-examples/cxx/tree/custom/mixed/.gitignore new file mode 100644 index 0000000..83d0a51 --- /dev/null +++ b/xsd-examples/cxx/tree/custom/mixed/.gitignore @@ -0,0 +1 @@ +people.?xx diff --git a/xsd-examples/cxx/tree/custom/mixed/README b/xsd-examples/cxx/tree/custom/mixed/README new file mode 100644 index 0000000..7b56812 --- /dev/null +++ b/xsd-examples/cxx/tree/custom/mixed/README @@ -0,0 +1,50 @@ +This example shows how to use type customization to parse and serialize +mixed content. The example achieves this by customizing the type with +the mixed content model to include a DOM document that stores the data +as a raw XML representation. The customized type also provides its own +parsing constructor and serialization operator where the mixed content +is extracted from and inserted back to DOM, respectively. The use of +DOM for mixed content storage is one of the options. You may find other +data structures (e.g., a string) more suitable depending on your situation. + +For more information on the C++/Tree mapping customization see the C++/Tree +Mapping Customization Guide[1]. + +[1] http://wiki.codesynthesis.com/Tree/Customization_guide + +The example consists of the following files: + +people.xsd + XML Schema definition for a simple person record vocabulary. Each + record includes the bio element which represents arbitrary XHTML + fragments as mixed content. + +people.xml + Sample XML instance document. + +people.hxx +people.ixx +people.cxx + C++ types that represent the given vocabulary, a set of parsing + functions that convert XML instance documents to a tree-like in-memory + object model, and a set of serialization functions that convert the + object model back to XML. These are generated by XSD from people.xsd + with the --custom-type option in order to customize the bio type. + +people-custom.hxx + Header file which defines our own bio class by inheriting from the + generated bio_base. It is included at the end of people.hxx using + the --hxx-epilogue option. + +people-custom.cxx + Source file which contains the implementation of our bio class. + +driver.cxx + Driver for the example. It first calls one of the parsing functions + that constructs the object model from the input file. It then prints + the data to STDERR, including the bio information converted to text. + Finally, the driver serializes the object model back to XML. + +To run the example on the sample XML instance document simply execute: + +$ ./driver people.xml diff --git a/xsd-examples/cxx/tree/custom/mixed/buildfile b/xsd-examples/cxx/tree/custom/mixed/buildfile new file mode 100644 index 0000000..9da936e --- /dev/null +++ b/xsd-examples/cxx/tree/custom/mixed/buildfile @@ -0,0 +1,30 @@ +# file : cxx/tree/custom/mixed/buildfile +# license : not copyrighted - public domain + +import libs = libxsd%lib{xsd} +import libs += libxerces-c%lib{xerces-c} + +./: exe{driver} doc{README} + +exe{driver}: {hxx cxx}{* -people} {hxx ixx cxx}{people} $libs + +exe{driver}: xml{people}: test.input = true + +<{hxx ixx cxx}{people}>: xsd{people} $xsd +{{ + diag xsd ($<[0]) # @@ TMP + + $xsd cxx-tree --std c++11 \ + --generate-inline \ + --generate-serialization \ + --custom-type bio=/bio_base \ + --hxx-epilogue '#include "people-custom.hxx"' \ + --output-dir $out_base \ + $path($<[0]) +}} + +cxx.poptions =+ "-I$out_base" "-I$src_base" + +# Define XSD_CXX11 since we include libxsd headers directly. +# +cxx.poptions += -DXSD_CXX11 diff --git a/xsd-examples/cxx/tree/custom/mixed/driver.cxx b/xsd-examples/cxx/tree/custom/mixed/driver.cxx new file mode 100644 index 0000000..08c83e0 --- /dev/null +++ b/xsd-examples/cxx/tree/custom/mixed/driver.cxx @@ -0,0 +1,122 @@ +// file : cxx/tree/custom/mixed/driver.cxx +// copyright : not copyrighted - public domain + +#include // std::unique_ptr +#include + +#include +#include + +#include "people.hxx" + +// The following transcode() utility function is handy when working with +// Xerces. Include it after the generated header in order to get only char +// or wchar_t version depending on how you compiled your schemas. +// +#include + +using std::cerr; +using std::endl; +using namespace xercesc; + +void +xhtml2txt (const DOMElement*); + +int +main (int argc, char* argv[]) +{ + if (argc != 2) + { + cerr << "usage: " << argv[0] << " people.xml" << endl; + return 1; + } + + int r (0); + + // The Xerces-C++ DOM document that will be used to store the XHTML + // fragments "out-live" the call to the parsing function. Therefore + // we need to initialize the Xerces-C++ runtime ourselves. + // + XMLPlatformUtils::Initialize (); + + try + { + using namespace people; + + // Parse. + // + std::unique_ptr d ( + directory_ (argv[1], xml_schema::flags::dont_initialize)); + + // Print what we've got. + // + const directory::person_sequence& s (d->person ()); + + for (directory::person_const_iterator i (s.begin ()); i != s.end (); ++i) + { + cerr << "First : " << i->first_name () << endl + << "Last : " << i->last_name () << endl + << "Gender : " << i->gender () << endl + << "Age : " << i->age () << endl; + + const bio& b (i->bio ()); + const DOMElement* xhtml (b.xhtml ()); + + if (xhtml != 0) + { + cerr << "Bio : " << endl; + xhtml2txt (xhtml); + } + + cerr << endl; + } + + // Serialize. + // + xml_schema::namespace_infomap map; + + map["ppl"].name = "http://www.codesynthesis.com/people"; + map["ppl"].schema = "people.xsd"; + + directory_ ( + std::cout, *d, map, "UTF-8", xml_schema::flags::dont_initialize); + } + catch (const xml_schema::exception& e) + { + cerr << e << endl; + r = 1; + } + + XMLPlatformUtils::Terminate (); + return r; +} + +// Primitive XHTML to text converter that just prints all the text +// nodes and ignores everything else. +// +void +xhtml2txt (const DOMElement* e) +{ + namespace xml = xsd::cxx::xml; + + for (const DOMNode* n (e->getFirstChild ()); + n != 0; + n = n->getNextSibling ()) + { + switch (n->getNodeType ()) + { + case DOMNode::TEXT_NODE: + { + cerr << xml::transcode (n->getTextContent ()); + break; + } + case DOMNode::ELEMENT_NODE: + { + xhtml2txt (static_cast (n)); + break; + } + default: + break; // Ignore all other nodes (e.g., comments, etc). + } + } +} diff --git a/xsd-examples/cxx/tree/custom/mixed/people-custom.cxx b/xsd-examples/cxx/tree/custom/mixed/people-custom.cxx new file mode 100644 index 0000000..bd03fcc --- /dev/null +++ b/xsd-examples/cxx/tree/custom/mixed/people-custom.cxx @@ -0,0 +1,89 @@ +// file : cxx/tree/custom/mixed/people-custom.cxx +// copyright : not copyrighted - public domain + +#include + +// Include people.hxx instead of people-custom.hxx here. +// +#include "people.hxx" + +namespace people +{ + using namespace xercesc; + + const XMLCh ls[] = {chLatin_L, chLatin_S, chNull}; + + bio:: + bio () + : xhtml_ (0) + { + DOMImplementation* impl ( + DOMImplementationRegistry::getDOMImplementation (ls)); + + doc_.reset (impl->createDocument ()); + } + + bio:: + bio (const DOMElement& e, + xml_schema::flags f, + xml_schema::container* c) + : bio_base (e, f, c), xhtml_ (0) + { + DOMImplementation* impl ( + DOMImplementationRegistry::getDOMImplementation (ls)); + + doc_.reset (impl->createDocument ()); + + // Copy the xhtml element. Assume the first child element in + // e is always xhtml. + // + for (DOMNode* n (e.getFirstChild ()); n != 0; n = n->getNextSibling ()) + { + if (n->getNodeType () == DOMNode::ELEMENT_NODE) + { + xhtml_ = static_cast (doc_->importNode (n, true)); + break; + } + } + } + + bio:: + bio (const bio& d, + xml_schema::flags f, + xml_schema::container* c) + : bio_base (d, f, c), xhtml_ (0) + { + DOMImplementation* impl ( + DOMImplementationRegistry::getDOMImplementation (ls)); + + doc_.reset (impl->createDocument ()); + + xhtml_ = static_cast ( + doc_->importNode (const_cast (d.xhtml_), true)); + } + + bio* bio:: + _clone (xml_schema::flags f, xml_schema::container* c) const + { + return new bio (*this, f, c); + } + + void + operator<< (DOMElement& e, const bio& x) + { + // Allow our base to serialize first. + // + const bio_base& b (x); + e << b; + + // Copy the XHTML fragment if we have one. + // + const DOMElement* xhtml (x.xhtml ()); + + if (xhtml != 0) + { + DOMDocument* doc (e.getOwnerDocument ()); + e.appendChild (doc->importNode (const_cast (xhtml), true)); + } + } +} diff --git a/xsd-examples/cxx/tree/custom/mixed/people-custom.hxx b/xsd-examples/cxx/tree/custom/mixed/people-custom.hxx new file mode 100644 index 0000000..2ab949d --- /dev/null +++ b/xsd-examples/cxx/tree/custom/mixed/people-custom.hxx @@ -0,0 +1,83 @@ +// file : cxx/tree/custom/mixed/people-custom.hxx +// copyright : not copyrighted - public domain + +// Do not include this file directly, use people.hxx instead. This +// file is included into generated people.hxx so we do not need to +// guard against multiple inclusions. +// + +#include +#include + +namespace people +{ + class bio: public bio_base + { + // Standard constructors. + // + public: + bio (); + + bio (const xercesc::DOMElement&, + xml_schema::flags = 0, + xml_schema::container* = 0); + + bio (const bio&, + xml_schema::flags = 0, + xml_schema::container* = 0); + + virtual bio* + _clone (xml_schema::flags = 0, + xml_schema::container* = 0) const; + + // XHTML bio as a DOM document. + // + public: + const xercesc::DOMElement* + xhtml () const + { + return xhtml_; + } + + xercesc::DOMElement* + xhtml () + { + return xhtml_; + } + + // The element should belong to the DOMDocument returned by + // the dom_document() functions. + // + void + xhtml (xercesc::DOMElement* e) + { + assert (e->getOwnerDocument () == doc_.get ()); + + if (xhtml_ != 0) + xhtml_->release (); + + xhtml_ = e; + } + + const xercesc::DOMDocument& + dom_document () const + { + return *doc_; + } + + xercesc::DOMDocument& + dom_document () + { + return *doc_; + } + + private: + xercesc::DOMElement* xhtml_; + xml_schema::dom::unique_ptr doc_; + }; + + // Serialization operator. + // + void + operator<< (xercesc::DOMElement&, const bio&); +} diff --git a/xsd-examples/cxx/tree/custom/mixed/people.xml b/xsd-examples/cxx/tree/custom/mixed/people.xml new file mode 100644 index 0000000..4033f95 --- /dev/null +++ b/xsd-examples/cxx/tree/custom/mixed/people.xml @@ -0,0 +1,38 @@ + + + + + + + + John + Doe + male + 32 + + +

Married to Jane Doe.

+
+
+
+ + + Jane + Doe + female + 28 + + +

Married to John Doe.

+
+
+
+ +
diff --git a/xsd-examples/cxx/tree/custom/mixed/people.xsd b/xsd-examples/cxx/tree/custom/mixed/people.xsd new file mode 100644 index 0000000..739861b --- /dev/null +++ b/xsd-examples/cxx/tree/custom/mixed/people.xsd @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + -- cgit v1.1