diff options
Diffstat (limited to 'examples/cxx/hybrid/filter')
-rw-r--r-- | examples/cxx/hybrid/filter/README | 71 | ||||
-rw-r--r-- | examples/cxx/hybrid/filter/driver.cxx | 98 | ||||
-rw-r--r-- | examples/cxx/hybrid/filter/makefile | 80 | ||||
-rw-r--r-- | examples/cxx/hybrid/filter/people-custom-pimpl.cxx | 26 | ||||
-rw-r--r-- | examples/cxx/hybrid/filter/people-custom-pimpl.hxx | 24 | ||||
-rw-r--r-- | examples/cxx/hybrid/filter/people-custom-simpl.cxx | 32 | ||||
-rw-r--r-- | examples/cxx/hybrid/filter/people-custom-simpl.hxx | 23 | ||||
-rw-r--r-- | examples/cxx/hybrid/filter/people.xml | 35 | ||||
-rw-r--r-- | examples/cxx/hybrid/filter/people.xsd | 37 |
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> |