::std::string request = clearCreateNode("book", createNode("author", "", "name='Freddy' surname='Smith'") + createNode("author", "", "name='Bill' surname='Joe'") + clearCreateNode("quote", "This is the best unknown book I've ever quoted!" + createNode("author", "", "name='Mr. Bob'")), "isbn='123456789' name='Some book' year='2011'");
stream
? - because there is an nesting of elements. Although stream
is the first thing that comes to mind and for the imperative approach, it is hardly possible to get something different from “feeding the right object to the left”.clearNode
or clearCreateNode
- I could not. And no matter how short the name can be, even if just "T"
is insanity. It is akin to repeating “I speak” in front of each remark in a dialogue with someone, and “offer:” before each sentence, “word:” before the word, and so on. Do not insanity? with (Object) begin a := 1; b := "foobar"; end;
((book :isbn "123456789" :name "Some book" :year "2011") ((author :name "Freddy" :surname "Smith")) ((author :name "Bill" :surname "Joe")) (quote "This is the best unknown book I've ever quoted!" (author :name "Mr. Bob")))
<book isbn='123456789' name='Some book' year='2011'><author name='Freddy' surname='Smith'/><author name='Bill' surname='Joe'/><quote>This is the best unknown book I've ever quoted!<author name='Mr. Bob'/></quote></book>
<book isbn='123456789' name='Some book' year='2011'> <author name='Freddy' surname='Smith'/> <author name='Bill' surname='Joe'/> <quote>This is the best unknown book I've ever quoted! <author name='Mr. Bob'/> </quote> </book>
const xml::Tag book ("book"); const xml::Tag author ("author"); const xml::Tag quote ("quote"); xml::Element request = xml::Element() (book ("isbn", "123456789") ("name", "Some book") ("year", "2011"), xml::Element() (author ("name", "Freddy") ("surname", "Smith")) (author ("name", "Bill") ("surname", "Joe")) (quote, xml::Element() ("This is the best unknown book I've ever quoted!") (author ("name", "Mr. Bob"))));
namespace library { namespace books { const xml::Tag book ("book"); const xml::Tag author ("author"); const xml::Tag quote ("quote"); } }
namespace bks = ::library::books; xml::Element request = xml::Element() (bks::book ("isbn", "123456789") ("name", "Some book") ("year", "2011"), xml::Element() (bks::author ("name", "Freddy") ("surname", "Smith")) (bks::author ("name", "Bill") ("surname", "Joe")) (bks::quote, xml::Element() ("This is the best unknown book I've ever quoted!") (bks::author ("name", "Mr. Bob"))));
xml::Element()
at the attachment point). But there is progress: it is no longer necessary to repeat for each tag that it is a TAG, and you can collect analytics for the entire document under construction and make on its basis, for example, pretty print or something else, since we are already dealing with an object, more precisely with a tree common root.Element
class: template <class T> void addContent(const T & content); void addEmptyTag(const Tag & tag); template <class T> void addTag(const Tag & tag, const T & content); void addTagElement(const Tag & tag, const Element & element);
Element
Class Operators: template <class T> inline Element & operator () (const T & content) { addContent(content); return *this; } inline Element & operator () (const Tag & tag) { addEmptyTag(tag); return *this; } template <class T> inline Element & operator () (const Tag & tag, const T & content) { addTag(tag, content); return *this; } template <> inline Element & operator () (const Tag & tag, const Element & element) { addTagElement(tag, element); return *this; }
Tag
class interface, which is not so interesting to share, due to the lack of nesting tags names and attributes. template <class T> void addContent(const T & content) { ::std::ostringstream oss; oss << content; buf += http_encode(oss.str()); } void addEmptyTag(const Tag & tag) { buf += createNode(tag.name, "", tag.args); } template <class T> void addTag(const Tag & tag, const T & content) { ::std::ostringstream oss; oss << content; buf += createNode(tag.name, oss.str(), tag.args); } void addTagElement(const Tag & tag, const Element & element) { buf += clearCreateNode(tag.name, element.str(), tag.args); }
Tag
class code: class Tag { public: // DSL : template <class K> Tag & operator () (const K & attr_name) { ::std::ostringstream oss; oss << " " << attr_name; args += oss.str(); return *this; } template <class K, class T> Tag & operator () (const K & attr_name, const T & value) { ::std::ostringstream oss; oss << " " << attr_name << "='" << value << "'"; args += oss.str(); return *this; } // DSL : template <class K> Tag operator () (const K & attr_name) const { Tag copy(*this); return copy (attr_name); } template <class K, class T> Tag operator () (const K & attr_name, const T & value) const { Tag copy(*this); return copy (attr_name, value); } // : template <class T> Tag(const T & name) : name(name) {} Tag(const Tag & ref) : name(ref.name), args(ref.args) {} ::std::string name; ::std::string args; };
<?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:fn="http://www.w3.org/2005/xpath-functions"> <xsl:output method="text" version="1.0" encoding="windows-1251" indent="no"/> <xsl:template match="/"> <xsl:apply-templates/> ; </xsl:template> <xsl:template match="text()">"<xsl:value-of select="."/>"</xsl:template> <xsl:template match="attribute::*"> ("<xsl:value-of select="name()"/>", "<xsl:value-of select="."/>")</xsl:template> <xsl:template match="*"><xsl:if test="child::node()">xml::Element()</xsl:if> (<xsl:value-of select="name()"/><xsl:apply-templates select="attribute::*"/><xsl:if test="child::node()">, <xsl:apply-templates/></xsl:if>)</xsl:template> </xsl:stylesheet>
Source: https://habr.com/ru/post/128933/
All Articles