1 /* 2 * Courtesy: https://gist.github.com/sebclaeys/1227644 3 */ 4 5 6 #ifndef XML_WRITER_H 7 # define XML_WRITER_H 8 9 # define HEADER "<?xml version=\"1.0\" encoding=\"utf-8\"?>\n" 10 # define INDENT " " 11 # define NEWLINE "\n" 12 13 # include <string> 14 # include <stack> 15 # include <iostream> 16 17 class xmlWriter 18 { 19 public: 20 xmlWriter(std::ostream & os)21 xmlWriter(std::ostream& os) : os(os), tag_open(false), new_line(true) {os << HEADER;} ~xmlWriter()22 ~xmlWriter() {} 23 openElt(const char * tag)24 xmlWriter& openElt(const char* tag) { 25 this->closeTag(); 26 if (elt_stack.size() > 0) 27 os << NEWLINE; 28 this->indent(); 29 this->os << "<" << tag; 30 elt_stack.push(tag); 31 tag_open = true; 32 new_line = false; 33 return *this; 34 } 35 closeElt()36 xmlWriter& closeElt() { 37 this->closeTag(); 38 std::string elt = elt_stack.top(); 39 this->elt_stack.pop(); 40 if (new_line) 41 { 42 os << NEWLINE; 43 this->indent(); 44 } 45 new_line = true; 46 this->os << "</" << elt << ">"; 47 return *this; 48 } 49 closeAll()50 xmlWriter& closeAll() { 51 while (elt_stack.size()) 52 this->closeElt(); 53 return *this; 54 } 55 attr(const char * key,const char * val)56 xmlWriter& attr(const char* key, const char* val) { 57 this->os << " " << key << "=\""; 58 this->write_escape(val); 59 this->os << "\""; 60 return *this; 61 } 62 attr(const char * key,std::string val)63 xmlWriter& attr(const char* key, std::string val) { 64 return attr(key, val.c_str()); 65 } 66 content(const char * val)67 xmlWriter& content(const char* val) { 68 this->closeTag(); 69 this->write_escape(val); 70 return *this; 71 } 72 73 private: 74 std::ostream& os; 75 bool tag_open; 76 bool new_line; 77 std::stack<std::string> elt_stack; 78 closeTag()79 inline void closeTag() { 80 if (tag_open) 81 { 82 this->os << ">"; 83 tag_open = false; 84 } 85 } 86 indent()87 inline void indent() { 88 for (int i = 0; i < (int)elt_stack.size(); i++) 89 os << (INDENT); 90 } 91 write_escape(const char * str)92 inline void write_escape(const char* str) { 93 for (; *str; str++) 94 switch (*str) { 95 case '&': os << "&"; break; 96 case '<': os << "<"; break; 97 case '>': os << ">"; break; 98 case '\'': os << "'"; break; 99 case '"': os << """; break; 100 default: os.put(*str); break; 101 } 102 } 103 }; 104 105 #endif /* !XML_WRITER_H */ 106