#ifndef XMLWRAP_H // -*- c++ -*- #define XMLWRAP_H #include "stringutil.h" #include /** * Wrap an xmlpp::Element for one-call loading / converting of typed values. * \note An ElementWrap keeps a reference to the Element. That might be * dangerous. */ class ElementWrap { public: ElementWrap(const std::string& filename, const xmlpp::Element& element) : filename_(filename), element_(element) {} ElementWrap(const ElementWrap& wrap, const xmlpp::Element& element) : filename_(wrap.filename_), element_(element) {} const xmlpp::Element& element() const { return element_; } std::string get_element_name() const { return element_.get_name(); } template C get_attribute(const std::string& name, const C& deflt = C()) const; template C get_required_attribute(const std::string& name) const; const xmlpp::Attribute* get_raw_attribute(const std::string& name) const { return element_.get_attribute(name); } std::string get_filename(const std::string& attrname) const; private: const std::string filename_; const xmlpp::Element& element_; }; // inline implementation of templates template inline C ElementWrap::get_attribute(const std::string& name, const C& deflt) const { if(const xmlpp::Attribute* cols = element_.get_attribute(name)) try { return to(cols->get_value()); } catch(const std::exception& err) { throw std::runtime_error(err.what() + std::string(", in ") + get_element_name() + " attribute " + name + ", \"" + filename_ + "\""); } else return deflt; } template inline C ElementWrap::get_required_attribute(const std::string& name) const { if(const xmlpp::Attribute* cols = element_.get_attribute(name)) try { return to(cols->get_value()); } catch(const std::exception& err) { throw std::runtime_error(err.what() + std::string(", in ") + get_element_name() + " attribute " + name + ", \"" + filename_ + "\""); } else throw std::runtime_error("Required attribute \"" + name + "\" missing in <" + get_element_name() + ">"); } #endif