From a6e24513d89067c16a3df214a7e2679e1f1675f1 Mon Sep 17 00:00:00 2001 From: Boris Kolpackov Date: Thu, 8 May 2014 17:02:55 -0700 Subject: Add helpers for parsing elements with simple content --- xml/parser.cxx | 36 ++++++++++++++++++++++++++++++++++++ xml/parser.hxx | 56 +++++++++++++++++++++++++++++++++++++++++++++++++++----- xml/parser.ixx | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ xml/parser.txx | 13 +++++++++++++ 4 files changed, 148 insertions(+), 5 deletions(-) (limited to 'xml') diff --git a/xml/parser.cxx b/xml/parser.cxx index d9d2fcb..6d5ab23 100644 --- a/xml/parser.cxx +++ b/xml/parser.cxx @@ -283,6 +283,42 @@ namespace xml qname_type (ns, n).string () + "' expected"); } + string parser:: + element () + { + content (simple); + string r; + + // The content of the element can be empty in which case there + // will be no characters event. + // + event_type e (next ()); + if (e == characters) + { + r.swap (value ()); + e = next (); + } + + // We cannot really get anything other than end_element since + // the simple content validation won't allow it. + // + assert (e == end_element); + + return r; + } + + string parser:: + element (const qname_type& qn, const string& dv) + { + if (peek () == start_element && qname () == qn) + { + next (); + return element (); + } + + return dv; + } + const parser::element_entry* parser:: get_element_ () const { diff --git a/xml/parser.hxx b/xml/parser.hxx index 51d589e..7c2cc45 100644 --- a/xml/parser.hxx +++ b/xml/parser.hxx @@ -219,6 +219,7 @@ namespace xml const std::string& name () const {return pqname_->name ();} const std::string& prefix () const {return pqname_->prefix ();} + std::string& value () {return *pvalue_;} const std::string& value () const {return *pvalue_;} template T value () const; @@ -246,11 +247,12 @@ namespace xml attribute (const std::string& name) const; std::string - attribute (const std::string& name, const std::string& dv) const; + attribute (const std::string& name, + const std::string& default_value) const; template T - attribute (const std::string& name, const T& dv) const; + attribute (const std::string& name, const T& default_value) const; const std::string& attribute (const qname_type& qname) const; @@ -260,11 +262,12 @@ namespace xml attribute (const qname_type& qname) const; std::string - attribute (const qname_type& qname, const std::string& dv) const; + attribute (const qname_type& qname, + const std::string& default_value) const; template T - attribute (const qname_type& qname, const T& dv) const; + attribute (const qname_type& qname, const T& default_value) const; bool attribute_present (const std::string& name) const; @@ -337,6 +340,49 @@ namespace xml const std::string& ns, const std::string& name, content_type); + // Helpers for parsing elements with simple content. The first two + // functions assume that start_element has already been parsed. The + // rest parse the complete element, from start to end. + // + // Note also that as with attribute(), there is no (namespace,name) + // overload since it would conflicts with (namespace,default_value). + // + public: + std::string + element (); + + template + T + element (); + + std::string + element (const std::string& name); + + std::string + element (const qname_type& qname); + + template + T + element (const std::string& name); + + template + T + element (const qname_type& qname); + + std::string + element (const std::string& name, const std::string& default_value); + + std::string + element (const qname_type& qname, const std::string& default_value); + + template + T + element (const std::string& name, const T& default_value); + + template + T + element (const qname_type& qname, const T& default_value); + // C++11 range-based for support. Generally, the iterator interface // doesn't make much sense for the parser so for now we have an // implementation that is just enough to the range-based for. @@ -420,7 +466,7 @@ namespace xml // and namespace decls. // const qname_type* pqname_; - const std::string* pvalue_; + std::string* pvalue_; unsigned long long line_; unsigned long long column_; diff --git a/xml/parser.ixx b/xml/parser.ixx index e58d2cf..c0fe256 100644 --- a/xml/parser.ixx +++ b/xml/parser.ixx @@ -125,6 +125,54 @@ namespace xml content (c); } + template + inline T parser:: + element () + { + return value_traits::parse (element (), *this); + } + + inline std::string parser:: + element (const std::string& n) + { + next_expect (start_element, n); + return element (); + } + + inline std::string parser:: + element (const qname_type& qn) + { + next_expect (start_element, qn); + return element (); + } + + template + inline T parser:: + element (const std::string& n) + { + return value_traits::parse (element (n), *this); + } + + template + inline T parser:: + element (const qname_type& qn) + { + return value_traits::parse (element (qn), *this); + } + + inline std::string parser:: + element (const std::string& n, const std::string& dv) + { + return element (qname_type (n), dv); + } + + template + inline T parser:: + element (const std::string& n, const T& dv) + { + return element (qname_type (n), dv); + } + inline const parser::element_entry* parser:: get_element () const { diff --git a/xml/parser.txx b/xml/parser.txx index e882c82..0167522 100644 --- a/xml/parser.txx +++ b/xml/parser.txx @@ -27,4 +27,17 @@ namespace xml return dv; } + + template + T parser:: + element (const qname_type& qn, const T& dv) + { + if (peek () == start_element && qname () == qn) + { + next (); + return element (); + } + + return dv; + } } -- cgit v1.1