aboutsummaryrefslogtreecommitdiff
path: root/examples/cxx/hybrid/filter
diff options
context:
space:
mode:
Diffstat (limited to 'examples/cxx/hybrid/filter')
-rw-r--r--examples/cxx/hybrid/filter/README71
-rw-r--r--examples/cxx/hybrid/filter/driver.cxx98
-rw-r--r--examples/cxx/hybrid/filter/makefile80
-rw-r--r--examples/cxx/hybrid/filter/people-custom-pimpl.cxx26
-rw-r--r--examples/cxx/hybrid/filter/people-custom-pimpl.hxx24
-rw-r--r--examples/cxx/hybrid/filter/people-custom-simpl.cxx32
-rw-r--r--examples/cxx/hybrid/filter/people-custom-simpl.hxx23
-rw-r--r--examples/cxx/hybrid/filter/people.xml35
-rw-r--r--examples/cxx/hybrid/filter/people.xsd37
9 files changed, 426 insertions, 0 deletions
diff --git a/examples/cxx/hybrid/filter/README b/examples/cxx/hybrid/filter/README
new file mode 100644
index 0000000..6ff8f76
--- /dev/null
+++ b/examples/cxx/hybrid/filter/README
@@ -0,0 +1,71 @@
+This example shows how to filter the XML data during parsing and object
+model during serialization in the Embedded C++/Hybrid mapping. Filtering
+allows only parts of the XML document to be parsed into the object model
+or only parts of the object model to be serialized to XML.
+
+This example uses the parser and serializer customization mechanisms
+provided by the C++/Hybrid mapping. For more information, see Section
+4.8, "Customizing the Object Model" and Section 6.1, "Customizing
+Parsers and Serializers" in the Embedded C++/Hybrid Mapping Getting
+Started Guide.
+
+The example consists of the following files:
+
+people.xsd
+ XML Schema which describes a collection of person records.
+
+people.xml
+ Sample XML instance document.
+
+people.hxx
+people.cxx
+
+people-pskel.hxx
+people-pskel.cxx
+people-pimpl.hxx
+people-pimpl.cxx
+
+people-pskel.hxx
+people-pskel.cxx
+people-pimpl.hxx
+people-pimpl.cxx
+ Object model (the first pair of files), parser skeletons (the second
+ pair), parser implementations (the third pair), serializer skeletons
+ (the fourth pair), and serializer implementations (the fifth pair).
+ These files are generated by the XSD/e compiler from people.xsd. The
+ --generate-parser, --generate-serializer, and --generate-aggregate
+ options were used to request the generation of the parsing and
+ serialization code. The --custom-parser option was used to customize
+ the people_pimpl parser implementation. The --custom-serializer
+ option was used to customize the people_simpl serializer
+ implementation.
+
+people-custom-pimpl.hxx
+people-custom-pimpl.cxx
+ Custom people parser implementation. It uses the implementation
+ generated by the XSD/e compiler as a base and overrides the person()
+ callback to filter the records being parsed.
+
+people-custom-simpl.hxx
+people-custom-simpl.cxx
+ Custom people serializer implementation. It uses the implementation
+ generated by the XSD/e compiler as a base and overrides the
+ person_next() callbacks to filter the records being serialized.
+
+driver.cxx
+ Driver for the example. It first sets the filter parameters on the
+ parser object and then calls it to construct the object model from
+ the input XML file. Only records matching the parser filter end up
+ in the object model. The driver then prints the content of the object
+ model to STDERR. Finally, the driver sets the filter parameters on
+ the serializer object and calls it to serialize the object model back
+ to XML. Only records matching the serializer filter end up in the
+ resulting XML.
+
+To run the example on the sample XML instance document simply execute:
+
+$ ./driver people.xml
+
+The example reads from STDIN if input file is not specified:
+
+$ ./driver <people.xml
diff --git a/examples/cxx/hybrid/filter/driver.cxx b/examples/cxx/hybrid/filter/driver.cxx
new file mode 100644
index 0000000..9bc9f64
--- /dev/null
+++ b/examples/cxx/hybrid/filter/driver.cxx
@@ -0,0 +1,98 @@
+// file : examples/cxx/hybrid/filter/driver.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#include <memory> // std::auto_ptr
+#include <iostream>
+
+#include "people.hxx"
+
+#include "people-pimpl.hxx"
+#include "people-simpl.hxx"
+
+using namespace std;
+
+int
+main (int argc, char* argv[])
+{
+ const char* input;
+
+ if (argc < 2)
+ {
+ input = "STDIN";
+ cerr << "XML file not specified, reading from STDIN" << endl;
+ }
+ else
+ input = argv[1];
+
+ try
+ {
+ // Parse.
+ //
+ people_paggr people_p;
+ people_pimpl& root_p = people_p.root_parser ();
+
+ // Initialize the filter.
+ //
+ root_p.age_filter (1, 30);
+
+ xml_schema::document_pimpl doc_p (root_p, people_p.root_name ());
+
+ people_p.pre ();
+
+ if (argc < 2)
+ doc_p.parse (cin);
+ else
+ doc_p.parse (argv[1]);
+
+ auto_ptr<people> ppl (people_p.post ());
+
+ // Print what we've got.
+ //
+ people::person_sequence& ps = ppl->person ();
+
+ for (people::person_iterator i = ps.begin (); i != ps.end (); ++i)
+ {
+ cerr << "first: " << i->first_name () << endl
+ << "last: " << i->last_name () << endl
+ << "gender: " << i->gender () << endl
+ << "age: " << i->age () << endl
+ << endl;
+ }
+
+ // Serialize.
+ //
+ people_saggr people_s;
+ people_simpl& root_s = people_s.root_serializer ();
+
+ // Initialize the filter.
+ //
+ gender g;
+ g.assign ("female");
+ root_s.gender_filter (g);
+
+ xml_schema::document_simpl doc_s (root_s, people_s.root_name ());
+
+ people_s.pre (*ppl);
+ doc_s.serialize (cout);
+ people_s.post ();
+ }
+ catch (const xml_schema::parser_exception& e)
+ {
+ cerr << input << ":" << e.line () << ":" << e.column () << ": "
+ << e.text () << endl;
+ return 1;
+ }
+ catch (const xml_schema::serializer_exception& e)
+ {
+ cerr << "error: " << e.text () << endl;
+ return 1;
+ }
+ catch (const std::ios_base::failure&)
+ {
+ cerr << input << ": unable to open or read/write failure" << endl;
+ return 1;
+ }
+
+ return 0;
+}
diff --git a/examples/cxx/hybrid/filter/makefile b/examples/cxx/hybrid/filter/makefile
new file mode 100644
index 0000000..4273a59
--- /dev/null
+++ b/examples/cxx/hybrid/filter/makefile
@@ -0,0 +1,80 @@
+# file : examples/cxx/hybrid/filter/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-pimpl.cxx people-custom-simpl.cxx
+
+obj := $(addprefix $(out_base)/,\
+$(cxx:.cxx=.o) \
+$(xsd:.xsd=.o) \
+$(xsd:.xsd=-pskel.o) \
+$(xsd:.xsd=-pimpl.o) \
+$(xsd:.xsd=-sskel.o) \
+$(xsd:.xsd=-simpl.o))
+
+dep := $(obj:.o=.o.d)
+
+xsde.l := $(out_root)/libxsde/xsde/xsde.l
+xsde.l.cpp-options := $(out_root)/libxsde/xsde/xsde.l.cpp-options
+
+driver := $(out_base)/driver
+clean := $(out_base)/.clean
+
+# Build.
+#
+$(driver): $(obj) $(xsde.l)
+
+$(obj) $(dep): $(xsde.l.cpp-options)
+
+gen := $(out_base)/$(xsd:.xsd=.hxx) \
+ $(out_base)/$(xsd:.xsd=.cxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-pskel.cxx) \
+ $(out_base)/$(xsd:.xsd=-pimpl.hxx) \
+ $(out_base)/$(xsd:.xsd=-pimpl.cxx) \
+ $(out_base)/$(xsd:.xsd=-sskel.hxx) \
+ $(out_base)/$(xsd:.xsd=-sskel.cxx) \
+ $(out_base)/$(xsd:.xsd=-simpl.hxx) \
+ $(out_base)/$(xsd:.xsd=-simpl.cxx)
+
+$(gen): $(out_root)/xsde/xsde
+$(gen): xsde := $(out_root)/xsde/xsde
+$(gen): xsde_options += --generate-parser --generate-serializer \
+--generate-aggregate \
+--custom-parser people=people_base_pimpl/people-custom-pimpl.hxx \
+--custom-serializer people=people_base_simpl/people-custom-simpl.hxx
+
+$(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)/xsde/hybrid/xsd-cxx.make)
+
+
+# Dependencies.
+#
+$(call import,$(src_root)/xsde/makefile)
+$(call import,$(src_root)/libxsde/xsde/makefile)
diff --git a/examples/cxx/hybrid/filter/people-custom-pimpl.cxx b/examples/cxx/hybrid/filter/people-custom-pimpl.cxx
new file mode 100644
index 0000000..e8a096f
--- /dev/null
+++ b/examples/cxx/hybrid/filter/people-custom-pimpl.cxx
@@ -0,0 +1,26 @@
+// file : examples/cxx/hybrid/filter/people-custom-pimpl.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Include people-pimpl.hxx (which includes people-custom-pimpl.hxx)
+// instead of people-custom-pimpl.hxx.
+//
+#include "people-pimpl.hxx"
+
+void people_pimpl::
+age_filter (unsigned short min, unsigned short max)
+{
+ min_age_ = min;
+ max_age_ = max;
+}
+
+void people_pimpl::
+person (const ::person& p)
+{
+ // Check if the age constraints are met.
+ //
+ unsigned short age = p.age ();
+
+ if (age >= min_age_ && age <= max_age_)
+ people_base_pimpl::person (p);
+}
diff --git a/examples/cxx/hybrid/filter/people-custom-pimpl.hxx b/examples/cxx/hybrid/filter/people-custom-pimpl.hxx
new file mode 100644
index 0000000..1856811
--- /dev/null
+++ b/examples/cxx/hybrid/filter/people-custom-pimpl.hxx
@@ -0,0 +1,24 @@
+// file : examples/cxx/hybrid/filter/people-custom-pimpl.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef PEOPLE_CUSTOM_PIMPL_HXX
+#define PEOPLE_CUSTOM_PIMPL_HXX
+
+// Customized people parser implementation.
+//
+class people_pimpl: public people_base_pimpl
+{
+public:
+ void
+ age_filter (unsigned short min, unsigned short max);
+
+ virtual void
+ person (const ::person&);
+
+private:
+ unsigned short min_age_;
+ unsigned short max_age_;
+};
+
+#endif // PEOPLE_CUSTOM_PIMPL_HXX
diff --git a/examples/cxx/hybrid/filter/people-custom-simpl.cxx b/examples/cxx/hybrid/filter/people-custom-simpl.cxx
new file mode 100644
index 0000000..3e7d9ff
--- /dev/null
+++ b/examples/cxx/hybrid/filter/people-custom-simpl.cxx
@@ -0,0 +1,32 @@
+// file : examples/cxx/hybrid/filter/people-custom-simpl.cxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+// Include people-simpl.hxx (which includes people-custom-simpl.hxx)
+// instead of people-custom-simpl.hxx.
+//
+#include "people-simpl.hxx"
+
+void people_simpl::
+gender_filter (gender g)
+{
+ gender_ = g;
+}
+
+bool people_simpl::
+person_next ()
+{
+ // See if we have any more person records with the gender we
+ // are interested in.
+ //
+ people::person_const_iterator& i = people_base_simpl_state_.person_;
+ people::person_const_iterator& e = people_base_simpl_state_.person_end_;
+
+ for (; i != e; ++i)
+ {
+ if (i->gender () == gender_)
+ break;
+ }
+
+ return i != e;
+}
diff --git a/examples/cxx/hybrid/filter/people-custom-simpl.hxx b/examples/cxx/hybrid/filter/people-custom-simpl.hxx
new file mode 100644
index 0000000..c3df238
--- /dev/null
+++ b/examples/cxx/hybrid/filter/people-custom-simpl.hxx
@@ -0,0 +1,23 @@
+// file : examples/cxx/hybrid/filter/people-custom-simpl.hxx
+// author : Boris Kolpackov <boris@codesynthesis.com>
+// copyright : not copyrighted - public domain
+
+#ifndef PEOPLE_CUSTOM_SIMPL_HXX
+#define PEOPLE_CUSTOM_SIMPL_HXX
+
+// Customized people serializer implementation.
+//
+class people_simpl: public people_base_simpl
+{
+public:
+ void
+ gender_filter (gender);
+
+ virtual bool
+ person_next ();
+
+private:
+ gender gender_;
+};
+
+#endif // PEOPLE_CUSTOM_SIMPL_HXX
diff --git a/examples/cxx/hybrid/filter/people.xml b/examples/cxx/hybrid/filter/people.xml
new file mode 100644
index 0000000..2a3fd11
--- /dev/null
+++ b/examples/cxx/hybrid/filter/people.xml
@@ -0,0 +1,35 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/hybrid/filter/people.xml
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<people xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+ xsi:noNamespaceSchemaLocation="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>
+
+ <person>
+ <first-name>Joe</first-name>
+ <last-name>Dirt</last-name>
+ <gender>male</gender>
+ <age>25</age>
+ </person>
+
+</people>
diff --git a/examples/cxx/hybrid/filter/people.xsd b/examples/cxx/hybrid/filter/people.xsd
new file mode 100644
index 0000000..bb6e5dd
--- /dev/null
+++ b/examples/cxx/hybrid/filter/people.xsd
@@ -0,0 +1,37 @@
+<?xml version="1.0"?>
+
+<!--
+
+file : examples/cxx/hybrid/filter/people.xsd
+author : Boris Kolpackov <boris@codesynthesis.com>
+copyright : not copyrighted - public domain
+
+-->
+
+<xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema">
+
+ <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="gender"/>
+ <xsd:element name="age" type="xsd:unsignedShort"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:complexType name="people">
+ <xsd:sequence>
+ <xsd:element name="person" type="person" maxOccurs="unbounded"/>
+ </xsd:sequence>
+ </xsd:complexType>
+
+ <xsd:element name="people" type="people"/>
+
+</xsd:schema>