forked from bgat/examples
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathxml-describe.cpp
More file actions
124 lines (102 loc) · 2.59 KB
/
xml-describe.cpp
File metadata and controls
124 lines (102 loc) · 2.59 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
#include <iostream>
#include <iterator>
#include <string>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
static const std::string xmlattr("<xmlattr>");
std::string describe(boost::property_tree::ptree &p, int indent = 0, std::string term = ", ")
{
std::string ret("");
// describe attributes first, even if they aren't the first element
boost::property_tree::ptree pc;
pc = p.get_child(xmlattr, pc);
if (pc.size())
{
ret += "(";
ret += describe(pc, 0, ", ");
ret.pop_back();
ret.pop_back();
ret += ")\n";
}
for (auto i = p.begin(); i != p.end(); ++i)
{
if (i->first.data() == xmlattr)
continue; // (already described above)
ret.append(indent, ' ');
ret += i->first.data();
if (i->second.size()) // describe children, if any
ret += describe(i->second, indent + 1, "\n");
if (i->second.data().length())
{
// describe this element
if (ret.back() == '\n')
{
ret.append(indent + 1, ' ');
ret += "...";
}
ret += " = ";
ret = ret + "\"" + i->second.data() + "\"";
ret += term;
}
}
return ret;
}
#include <boost/program_options.hpp>
namespace po = boost::program_options;
static void add_options(po::options_description &desc, std::string *tag)
{
desc.add_options()
("help,?", "emit this help message")
("tag,t", po::value<std::string>(tag), "describe (only) this tag's data")
;
}
//
// illustrates how to use property-tree to parse XML
//
int main(int argc, const char* argv[])
{
std::string tag("");
po::options_description desc("Arguments");
add_options(desc, &tag);
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);
po::notify(vm);
if (vm.count("help")) {
std::cerr << argv[0] << "-" << GIT_VERSION << std::endl;
std::cerr << "Describes an XML document" << std::endl;
std::cerr << desc << std::endl;
return 1;
}
// read all of stdin
std::istreambuf_iterator<char> begin(std::cin), end;
std::string s(begin, end);
std::istringstream is(s);
// convert xml to property-tree
boost::property_tree::ptree p;
int flags = boost::property_tree::xml_parser::trim_whitespace;
boost::property_tree::read_xml(is, p, flags);
std::string ret;
if (tag.length())
{
boost::property_tree::ptree pt;
pt = p.get_child(tag);
if (pt.size()) {
ret = tag;
ret += describe(pt, 1, "\n");
std::string pts = pt.get_value<std::string>();
if (pts.length())
ret = ret + " = \"" + pts + "\"";
}
else
{
ret = tag;
ret += " = \"";
ret += p.get<std::string>(tag);
ret += "\"";
}
}
else
ret = describe(p);
std::cout << ret << std::endl;
return 0;
}