diff options
Diffstat (limited to 'examples/hybrid/dom.cxx')
-rw-r--r-- | examples/hybrid/dom.cxx | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/examples/hybrid/dom.cxx b/examples/hybrid/dom.cxx new file mode 100644 index 0000000..cd1e0e0 --- /dev/null +++ b/examples/hybrid/dom.cxx @@ -0,0 +1,115 @@ +// file : examples/hybrid/dom.cxx +// copyright : not copyrighted - public domain + +#include <xml/parser.hxx> +#include <xml/serializer.hxx> + +#include "dom.hxx" + +using namespace std; +using namespace xml; + +static bool +whitespace (const string& s) +{ + for (string::size_type i (0); i < s.size (); ++i) + { + char c (s[i]); + if (c != 0x20 && c != 0x0A && c != 0x0D && c != 0x09) + return false; + } + + return true; +} + +element:: +element (parser& p, bool se) +{ + if (se) + p.next_expect (parser::start_element); + + name_ = p.qname (); + + // Extract attributes. + // + const parser::attribute_map_type& m (p.attribute_map ()); + for (parser::attribute_map_type::const_iterator i (m.begin ()); + i != m.end (); + ++i) + attributes_[i->first] = i->second.value; + + // Parse content (nested elements or text). + // + while (p.peek () != parser::end_element) + { + switch (p.next ()) + { + case parser::start_element: + { + if (!text_.empty ()) + { + if (!whitespace (text_)) + throw parsing (p, "element in simple content"); + + text_.clear (); + } + + elements_.push_back (element (p, false)); + p.next_expect (parser::end_element); + + break; + } + case parser::characters: + { + if (!elements_.empty ()) + { + if (!whitespace (p.value ())) + throw parsing (p, "characters in complex content"); + + break; // Ignore whitespaces. + } + + text_ += p.value (); + break; + } + default: + break; // Ignore any other events. + } + } + + if (se) + p.next_expect (parser::end_element); +} + +void element:: +serialize (serializer& s, bool se) const +{ + if (se) + s.start_element (name_); + + // Add attributes. + // + for (attributes_type::const_iterator i (attributes_.begin ()); + i != attributes_.end (); + ++i) + { + s.attribute (i->first, i->second); + } + + // Serialize content (nested elements or text). + // + if (!elements_.empty ()) + { + for (elements_type::const_iterator i (elements_.begin ()); + i != elements_.end (); + ++i) + { + i->serialize (s); + } + } + else if (!text_.empty ()) + s.characters (text_); + + if (se) + s.end_element (); +} |