diff options
Diffstat (limited to 'xsd/examples/cxx/parser/wildcard')
| -rw-r--r-- | xsd/examples/cxx/parser/wildcard/README | 27 | ||||
| -rw-r--r-- | xsd/examples/cxx/parser/wildcard/driver.cxx | 239 | ||||
| -rw-r--r-- | xsd/examples/cxx/parser/wildcard/email.xml | 31 | ||||
| -rw-r--r-- | xsd/examples/cxx/parser/wildcard/email.xsd | 50 | ||||
| -rw-r--r-- | xsd/examples/cxx/parser/wildcard/makefile | 102 | 
5 files changed, 449 insertions, 0 deletions
diff --git a/xsd/examples/cxx/parser/wildcard/README b/xsd/examples/cxx/parser/wildcard/README new file mode 100644 index 0000000..89f9aa9 --- /dev/null +++ b/xsd/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/xsd/examples/cxx/parser/wildcard/driver.cxx b/xsd/examples/cxx/parser/wildcard/driver.cxx new file mode 100644 index 0000000..fa82ec0 --- /dev/null +++ b/xsd/examples/cxx/parser/wildcard/driver.cxx @@ -0,0 +1,239 @@ +// file      : examples/cxx/parser/wildcard/driver.cxx +// 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 () +  { +    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: +  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/xsd/examples/cxx/parser/wildcard/email.xml b/xsd/examples/cxx/parser/wildcard/email.xml new file mode 100644 index 0000000..f5d0359 --- /dev/null +++ b/xsd/examples/cxx/parser/wildcard/email.xml @@ -0,0 +1,31 @@ +<?xml version="1.0"?> + +<!-- + +file      : examples/cxx/parser/wildcard/email.xml +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 <jane@doe.com></to> +  <from>John Doe <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/xsd/examples/cxx/parser/wildcard/email.xsd b/xsd/examples/cxx/parser/wildcard/email.xsd new file mode 100644 index 0000000..087fc7e --- /dev/null +++ b/xsd/examples/cxx/parser/wildcard/email.xsd @@ -0,0 +1,50 @@ +<?xml version="1.0"?> + +<!-- + +file      : examples/cxx/parser/wildcard/email.xsd +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/xsd/examples/cxx/parser/wildcard/makefile b/xsd/examples/cxx/parser/wildcard/makefile new file mode 100644 index 0000000..524f8da --- /dev/null +++ b/xsd/examples/cxx/parser/wildcard/makefile @@ -0,0 +1,102 @@ +# file      : examples/cxx/parser/wildcard/makefile +# copyright : Copyright (c) 2005-2014 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 +install  := $(out_base)/.install +dist     := $(out_base)/.dist +dist-win := $(out_base)/.dist-win +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$(out_base) -I$(src_base) -I$(src_root)/libxsd +$(obj) $(dep): $(xerces_c.l.cpp-options) + +genf := $(xsd:.xsd=-pskel.hxx) $(xsd:.xsd=-pskel.ixx) $(xsd:.xsd=-pskel.cxx) +gen  := $(addprefix $(out_base)/,$(genf)) + +$(gen): xsd := $(out_root)/xsd/xsd +$(gen): $(out_root)/xsd/xsd + +$(call include-dep,$(dep),$(obj),$(gen)) + +# Convenience alias for default target. +# +$(out_base)/: $(driver) + + +# Install & Dist. +# +dist-common := $(out_base)/.dist-common + +$(install) $(dist) $(dist-win) $(dist-common): path := $(subst $(src_root)/,,$(src_base)) + +$(install): +	$(call install-data,$(src_base)/README,$(install_doc_dir)/xsd/$(path)/README) +	$(call install-data,$(src_base)/driver.cxx,$(install_doc_dir)/xsd/$(path)/driver.cxx) +	$(call install-data,$(src_base)/email.xsd,$(install_doc_dir)/xsd/$(path)/email.xsd) +	$(call install-data,$(src_base)/email.xml,$(install_doc_dir)/xsd/$(path)/email.xml) + +$(dist-common): +	$(call install-data,$(src_base)/driver.cxx,$(dist_prefix)/$(path)/driver.cxx) +	$(call install-data,$(src_base)/email.xsd,$(dist_prefix)/$(path)/email.xsd) +	$(call install-data,$(src_base)/email.xml,$(dist_prefix)/$(path)/email.xml) + +$(dist): $(dist-common) +	$(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README) + +$(dist-win): $(dist-common) +	$(call install-data,$(src_base)/README,$(dist_prefix)/$(path)/README.txt) +	$(call message,,todos $(dist_prefix)/$(path)/README.txt) + + +# Clean. +# +$(clean): $(driver).o.clean                                 \ +  $(addsuffix .cxx.clean,$(obj))                            \ +  $(addsuffix .cxx.clean,$(dep))                            \ +  $(addprefix $(out_base)/,$(xsd:.xsd=-pskel.cxx.xsd.clean)) + +# Generated .gitignore. +# +ifeq ($(out_base),$(src_base)) +$(gen): | $(out_base)/.gitignore +$(driver): | $(out_base)/.gitignore + +$(out_base)/.gitignore: files := driver $(genf) +$(clean): $(out_base)/.gitignore.clean + +$(call include,$(bld_root)/git/gitignore.make) +endif + +# 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) +$(call include,$(scf_root)/xsd/parser/xsd-cxx.make) + + +# Dependencies. +# +$(call import,$(src_root)/xsd/makefile)  | 
