(C++) XmlToPretty
February 24, 2017 · View on GitHub
(C++) XmlToPretty
XmlToPretty is an XML code snippet.
#include <algorithm> #include <cassert> #include <iostream> #include <iterator> #include <string> #include <vector> ///Split an XML std::string into its parts //From http://www.richelbilderbeek.nl/CppSplitXml.htm const std::vector<std::string> SplitXml(const std::string& s) { std::vector<std::string> v; std::string::const_iterator i = s.begin(); std::string::const_iterator j = s.begin(); const std::string::const_iterator end = s.end(); while (j!=end) { ++j; if ((*j=='>' || *j == '<') && std::distance(i,j) > 1) { std::string t; std::copy( *i=='<' ? i : i+1, *j=='>' ? j+1 : j, std::back_inserter(t)); v.push_back(t); i = j; } } return v; } ///Pretty-print an XML std::string by indenting its elements //From http://www.richelbilderbeek.nl/CppXmlToPretty.htm const std::vector<std::string> XmlToPretty(const std::string& s) { std::vector<std::string> v = SplitXml(s); int n = -2; std::for_each(v.begin(),v.end(), [&n](std::string& s) { assert(!s.empty()); if (s[0] == '<' && s[1] != '/') { n+=2; } s = std::string(n,' ') + s; if (s[n+0] == '<' && s[n+1] == '/') { n-=2; } } ); return v; }
Testing code
XmlToPretty is tested with the code below.
Technical facts
Operating system(s) or programming environment(s)
Lubuntu 12.10 (quantal)
Qt Creator 2.5.2
- G++ 4.7.2
Libraries used:
STL: GNU ISO C++ Library, version
4.7.2
Qt project file: CppXmlToPretty.pro
TEMPLATE = app QMAKE_CXXFLAGS += -std=c++11 CONFIG += console CONFIG -= qt SOURCES += main.cpp
main.cpp
#include <algorithm> #include <cassert> #include <iostream> #include <iterator> #include <string> #include <vector> ///Split an XML std::string into its parts //From http://www.richelbilderbeek.nl/CppSplitXml.htm const std::vector<std::string> SplitXml(const std::string& s) { std::vector<std::string> v; std::string::const_iterator i = s.begin(); std::string::const_iterator j = s.begin(); const std::string::const_iterator end = s.end(); while (j!=end) { ++j; if ((*j=='>' || *j == '<') && std::distance(i,j) > 1) { std::string t; std::copy( *i=='<' ? i : i+1, *j=='>' ? j+1 : j, std::back_inserter(t)); v.push_back(t); i = j; } } return v; } ///Pretty-print an XML std::string by indenting its elements //From http://www.richelbilderbeek.nl/CppXmlToPretty.htm const std::vector<std::string> XmlToPretty(const std::string& s) { std::vector<std::string> v = SplitXml(s); int n = -2; std::for_each(v.begin(),v.end(), [&n](std::string& s) { assert(!s.empty()); if (s[0] == '<' && s[1] != '/') { n+=2; } s = std::string(n,' ') + s; if (s[n+0] == '<' && s[n+1] == '/') { n-=2; } } ); return v; } int main() { { const std::string s = "<a>A</a>"; const std::vector<std::string> split = SplitXml(s); const std::vector<std::string> split_expected = { "<a>", "A", "</a>" }; assert(split == split_expected); const std::vector<std::string> pretty = XmlToPretty(s); const std::vector<std::string> pretty_expected = { "<a>", "A", "</a>" }; assert(pretty == pretty_expected); } { const std::string s = "<a>A<b>B</b></a>"; const std::vector<std::string> split = SplitXml(s); const std::vector<std::string> split_expected = { "<a>", "A", "<b>", "B", "</b>", "</a>" }; assert(split == split_expected); const std::vector<std::string> pretty = XmlToPretty(s); const std::vector<std::string> pretty_expected = { "<a>", "A", " <b>", " B", " </b>", "</a>" }; assert(pretty == pretty_expected); } { const std::string s = "<a>A<b>B1</b><b>B2</b></a>"; const std::vector<std::string> split = SplitXml(s); const std::vector<std::string> split_expected = { "<a>", "A", "<b>", "B1", "</b>", "<b>", "B2", "</b>", "</a>" }; assert(split == split_expected); const std::vector<std::string> pretty = XmlToPretty(s); const std::vector<std::string> pretty_expected = { "<a>", "A", " <b>", " B1", " </b>", " <b>", " B2", " </b>", "</a>" }; assert(pretty == pretty_expected); } }