From c0d6c1d72ecdeb777e9e61b11f0d06b1724d4cd6 Mon Sep 17 00:00:00 2001 From: Michael Andres Date: Fri, 24 Jan 2014 08:22:20 +0100 Subject: [PATCH] Helper for generating xml output --- zypp/CMakeLists.txt | 1 + zypp/base/Xml.h | 122 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 123 insertions(+) create mode 100644 zypp/base/Xml.h diff --git a/zypp/CMakeLists.txt b/zypp/CMakeLists.txt index 35b8e2a..fb8300a 100644 --- a/zypp/CMakeLists.txt +++ b/zypp/CMakeLists.txt @@ -257,6 +257,7 @@ SET( zypp_base_HEADERS base/Tr1hash.h base/Unit.h base/WatchFile.h + base/Xml.h ) INSTALL( FILES diff --git a/zypp/base/Xml.h b/zypp/base/Xml.h new file mode 100644 index 0000000..283ddc2 --- /dev/null +++ b/zypp/base/Xml.h @@ -0,0 +1,122 @@ +/*---------------------------------------------------------------------\ +| ____ _ __ __ ___ | +| |__ / \ / / . \ . \ | +| / / \ V /| _/ _/ | +| / /__ | | | | | | | +| /_____||_| |_| |_| | +| | +\---------------------------------------------------------------------*/ +/** \file zypp/base/Xml.h + * +*/ +#ifndef ZYPP_BASE_XML_H +#define ZYPP_BASE_XML_H + +#include +#include +#include +#include +#include +#include + +#include "zypp/base/Easy.h" +#include "zypp/base/String.h" +#include "zypp/parser/xml/XmlEscape.h" + +/////////////////////////////////////////////////////////////////// +namespace zypp +{ + /////////////////////////////////////////////////////////////////// + namespace xmlout + { + using xml::escape; + using xml::unescape; + + /** \relates NodeAttr NODE ATTRIBUTE representation of types [str::asString] */ + template + std::string asXmlNodeAttr( const _Tp & val_r ) + { return str::asString( val_r ); } + + /////////////////////////////////////////////////////////////////// + /// \class NodeAttr + /// \brief (Key, Value) string pair of XML node attributes + struct NodeAttr : public std::pair + { + typedef std::pair Pair; + + template + NodeAttr( std::string key_r, const _Type & val_r ) + : Pair( std::move(key_r), asXmlNodeAttr(val_r) ) + {} + + NodeAttr( std::string key_r, std::string val_r ) + : Pair( std::move(key_r), std::move(val_r) ) + {} + }; + /////////////////////////////////////////////////////////////////// + + /////////////////////////////////////////////////////////////////// + /// \class Node + /// \brief RAII writing a nodes start/end tag + /// \code + /// { + /// Node node( std::cout, "node", { "attr", "val" } ); // + /// *node << "write nodes body...." + /// } // + /// \endcode + struct Node + { + NON_COPYABLE_BUT_MOVE( Node ); + + /** Ctor taking nodename and attribute list */ + Node( std::ostream & out_r, std::string name_r, const std::initializer_list & attrs_r = {} ) + : _out( out_r ), _name( std::move(name_r) ) + { + if ( ! _name.empty() ) + { + _out << "<" << _name; + for ( const auto & pair : attrs_r ) + _out << " " << pair.first << "=\"" << xml::escape( pair.second ) << "\""; + _out << ">"; + } + } + + /** Convenience ctor for one attribute pair */ + Node( std::ostream & out_r, std::string name_r, NodeAttr attr_r ) + : Node( out_r, std::move(name_r), { attr_r } ) + {} + + /** Dtor wrting end tag */ + ~Node() + { _out << ""; } + + /** Return the output stream */ + std::ostream & operator*() { return _out; } + + private: + std::ostream & _out; + std::string _name; + }; + /////////////////////////////////////////////////////////////////// + + /** \relates Node Write a leaf node without PCDATA + * \code + * + * \endcode + */ + void node( std::ostream & out_r, const std::string & name_r, const std::initializer_list & attrs_r = {} ) + { + out_r << "<" << name_r; + for ( const auto & pair : attrs_r ) + out_r << " " << pair.first << "=\"" << xml::escape( pair.second ) << "\""; + out_r << "/>"; + } + /** \overload for one attribute pair */ + void node( const std::string & name_r, NodeAttr attr_r ) + { node( name_r, { attr_r } ); } + + } // namespace xmlout + /////////////////////////////////////////////////////////////////// +} // namespace zypp +/////////////////////////////////////////////////////////////////// +#endif // ZYPP_BASE_XML_H -- 2.7.4