Created
July 17, 2016 05:16
-
-
Save apfeltee/20d942f503067671026517fd28aae2bb to your computer and use it in GitHub Desktop.
Primitive XML/HTML writer in plain C++, modeled after javascript.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <iostream> | |
#include <sstream> | |
#include <string> | |
#include <map> | |
#include <vector> | |
class Element | |
{ | |
public: | |
using AttrMap = std::map<std::string, std::string>; | |
public: | |
static std::string htmlquote(const std::string& val) | |
{ | |
return val; | |
} | |
private: | |
std::string m_tag; | |
std::stringstream m_inline; | |
AttrMap m_attributes; | |
std::vector<Element> m_elements; | |
public: | |
Element(const Element& old) | |
{ | |
m_tag = old.m_tag; | |
m_inline << old.m_inline.str(); | |
m_attributes = old.m_attributes; | |
for(auto it=old.m_elements.begin(); it!=old.m_elements.end(); it++) | |
{ | |
m_elements.push_back(*it); | |
} | |
} | |
Element(const std::string& tname): m_tag(tname) | |
{ | |
} | |
Element(const std::string& tname, const std::string& txt): m_tag(tname) | |
{ | |
text() << txt; | |
} | |
Element createElement(const std::string& tname) const | |
{ | |
return Element(tname); | |
} | |
Element createElement(const std::string& tname, const std::string& txt) | |
{ | |
return Element(tname, txt); | |
} | |
Element& setAttribute(const std::string& key, const std::string& val) | |
{ | |
m_attributes[key] = val; | |
return *this; | |
} | |
Element& appendChild(const Element& elm) | |
{ | |
m_elements.push_back(elm); | |
return *this; | |
} | |
std::vector<Element> children() const | |
{ | |
return m_elements; | |
} | |
std::string toXML() const | |
{ | |
std::stringstream obuf; | |
obuf << "<" << m_tag; | |
if(m_attributes.size() > 0) | |
{ | |
obuf << " "; | |
for(auto attrit=m_attributes.begin(); attrit!=m_attributes.end(); attrit++) | |
{ | |
auto& key = attrit->first; | |
auto& value = attrit->second; | |
obuf << key << "=\"" << htmlquote(value) << "\""; | |
if(attrit != (--(m_attributes.end()))) | |
{ | |
obuf << " "; | |
} | |
} | |
} | |
obuf << ">"; | |
for(auto it=m_elements.begin(); it!=m_elements.end(); it++) | |
{ | |
auto& elm = *it; | |
obuf << elm.toXML(); | |
} | |
if(hasText()) | |
{ | |
obuf << "</" << m_tag << ">"; | |
} | |
return obuf.str(); | |
} | |
bool hasText() const | |
{ | |
return ( | |
(m_inline.str().size() > 0) || | |
(m_elements.size() > 0) | |
); | |
} | |
std::string text() const | |
{ | |
return m_inline.str(); | |
} | |
std::stringstream& text() | |
{ | |
return m_inline; | |
} | |
}; | |
int main() | |
{ | |
Element doc("html"); | |
auto form = doc.createElement("form"); | |
auto input = doc.createElement("input"); | |
auto submit = doc.createElement("submit"); | |
form.setAttribute("action", "/bin/submit.cgi"); | |
input.setAttribute("name", "fr_uname").setAttribute("type", "text"); | |
submit.setAttribute("type", "submit").setAttribute("value", "Go!"); | |
form.appendChild(input).appendChild(submit); | |
doc.appendChild(form); | |
std::cout << doc.toXML() << std::endl; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment