aboutsummaryrefslogtreecommitdiff
path: root/xml
diff options
context:
space:
mode:
authorBoris Kolpackov <boris@codesynthesis.com>2014-05-08 17:02:55 -0700
committerBoris Kolpackov <boris@codesynthesis.com>2014-05-08 17:02:55 -0700
commita6e24513d89067c16a3df214a7e2679e1f1675f1 (patch)
treeb622213d673b73005bcd6002e67b121714c9c55b /xml
parent8234b273aea9a662b8675190d3e73c90ce159f1a (diff)
Add helpers for parsing elements with simple content
Diffstat (limited to 'xml')
-rw-r--r--xml/parser.cxx36
-rw-r--r--xml/parser.hxx56
-rw-r--r--xml/parser.ixx48
-rw-r--r--xml/parser.txx13
4 files changed, 148 insertions, 5 deletions
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 <typename T> 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 <typename T>
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 <typename T>
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 <typename T>
+ T
+ element ();
+
+ std::string
+ element (const std::string& name);
+
+ std::string
+ element (const qname_type& qname);
+
+ template <typename T>
+ T
+ element (const std::string& name);
+
+ template <typename T>
+ 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 <typename T>
+ T
+ element (const std::string& name, const T& default_value);
+
+ template <typename T>
+ 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 <typename T>
+ inline T parser::
+ element ()
+ {
+ return value_traits<T>::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 <typename T>
+ inline T parser::
+ element (const std::string& n)
+ {
+ return value_traits<T>::parse (element (n), *this);
+ }
+
+ template <typename T>
+ inline T parser::
+ element (const qname_type& qn)
+ {
+ return value_traits<T>::parse (element (qn), *this);
+ }
+
+ inline std::string parser::
+ element (const std::string& n, const std::string& dv)
+ {
+ return element (qname_type (n), dv);
+ }
+
+ template <typename T>
+ inline T parser::
+ element (const std::string& n, const T& dv)
+ {
+ return element<T> (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 <typename T>
+ T parser::
+ element (const qname_type& qn, const T& dv)
+ {
+ if (peek () == start_element && qname () == qn)
+ {
+ next ();
+ return element<T> ();
+ }
+
+ return dv;
+ }
}