summaryrefslogtreecommitdiff
path: root/examples/cxx/tree/custom/contacts
diff options
context:
space:
mode:
Diffstat (limited to 'examples/cxx/tree/custom/contacts')
-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
7 files changed, 304 insertions, 0 deletions
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)