I am parsing an XML file with boost::property_tree
. The data I need to parse includes regular decimal numbers such as 42
and hex numbers such as 0xF1
. For example:
<hex>0xF1</hex>
<dec>42</dec>
It's easy to parse decimal numbers and convert them to int
with ptree::get<int>()
. However, the same call on the hex number fails.
I can work around this by parsing the hex number as a std::string
and then using std::istringstream
and std::hex
to convert it to int
. Demonstrating with code:
#include <iostream>
#include <string>
#include <sstream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
using std::string;
namespace pt = boost::property_tree;
int main() {
pt::ptree tree;
try {
pt::read_xml("debug.xml", tree, pt::xml_parser::no_comments);
} catch (const pt::xml_parser_error&) {}
int hexnum;
// Doesn't work (throws exception)
try {
hexnum = tree.get<int>("hex");
} catch (const pt::ptree_bad_data&) {
std::cout << "caught bad ptree data exception";
}
// Workaround: parse as a string, then convert the string
string hexstring;
try {
hexstring = tree.get<string>("hex");
std::istringstream iss(hexstring);
iss >> std::hex >> hexnum;
if (!iss) throw std::ios_base::failure("invalid hex string");
} catch (const pt::ptree_error&) {
// get() failed
} catch (const std::ios_base::failure& fail) {
std::cout << fail.what();
}
// Parsing a regular decimal number is straightforward
int decnum;
try {
decnum = tree.get<int>("dec");
} catch (const pt::ptree_error&) {}
return 0;
}
Is there a more elegant way to do this, similar to how I can convert a std::string
into a number using std::istringstream
with std::hex
, std::oct
, or std::dec
? The documentation shows that there is a stream_translator.hpp
header file which looks promising as a way to do this -- but there's not much documentation for this file either on the Boost website or in the header file itself. The workaround with std::istringstream
is acceptable, but stream_translator.hpp
makes me wonder if boost::property_tree
provides a way to do this.
I need to be able to easily switch between parsing hex and decimal numbers, just as it's easy to do so with iss >> std::hex
or iss >> std::dec
on std::istringstream iss
.
(In case it matters, my compiler is VS2005. Yes, '05 not '15.)