#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);
}
}
|