BOOST xml resolves the same tag child node
The main use of the Boost_foreach macro, the Ptree to traverse:
int Secsrcmconf::readfromxml () {Ifstream file;
File.Open (M_conffilepath.c_str (), ios::in);
if (!file.is_open ()) {cerr << "file" << M_conffilepath << "Open failed" << Endl;
return-1;
} file.close ();
Ptree pt;
Read_xml (M_conffilepath, PT, Xml_parser::trim_whitespace); Parsesysteminfofromxml (Pt.get_child ("SRCM").
System ")); Parsemmiinfofromxml (Pt.get_child ("SRCM").
MMI "));
Boost_foreach (Ptree::value_type &v, Pt.get_child ("SRCM")) {string tmp;
if (V.first = = "Substation") {srcmsubconf subconf;
Subconf.m_subname = v.second.get<string> ("Name");
TMP = v.second.get<string> ("Protocol"); if (Tmp.length ()) {if (tmp = = ext104) | | tmp = = "EXT104") {Subconf.m_protocoltype =
protocol_ext104; else if (tmp = = "iec61850" | | tmp = = "IEC61850") {Subconf.m_protocoltype = protocol_iec61850;
else {subconf.m_protocoltype = Protocol_null;
} TMP = v.second.get<string> ("Compress"); if (Tmp.length ()) {if (tmp = = "Zip" | | | tmp = = "Zip") {Subconf.m_compresstype = Compr
Ess_zip;
else if (TMP = = "gzip" | | tmp = = "gzip" | | TMP = = "GZ" | |
TMP = = "GZ") {subconf.m_compresstype = Compress_gzip;
else {subconf.m_compresstype = Compress_null; } subconf.m_cimlastupdate = Str2time (v.second.get<string> ("Devicecimfile.
LastUpdateTime "));
Subconf.m_cimlastimport = Str2time (v.second.get<string> ("Devicecimfile.lastimporttime")); Subconf.m_svglastupdate = Str2time (v.second.get<string> ("Devicesvgfile.lastupdatetime"));
Subconf.m_svglastimport = Str2time (v.second.get<string> ("Devicesvgfile.lastimporttime")
));
Subconf.m_maplastupdate = Str2time (v.second.get<string> ("Devicemapfile.lastupdatetime"));
Subconf.m_maplastimport = Str2time (v.second.get<string> ("Devicemapfile.lastimporttime"));
M_subconfmap.insert (pair<string, srcmsubconf> (Subconf.m_subname, subconf));
} return 0; }
BOOST XML parsing Chinese issues
Ptree parsing the main XML file format is Utf-8 format, if the XML file contains Unicode such as Chinese characters, parsing out is garbled. Parsing Unicode to use Wptree, the interface of this class supports wide characters and the interface and Ptree remain consistent. To support Chinese parsing only wptree is not enough, but also need a Unicode converter to help, the converter can achieve wide and narrow character conversion, the width of the conversion function has many implementations, but the c++11 in a more simple unified way to achieve the conversion of the narrow character.
The conversion of the narrow character in c++11:
std::wstring_convert<std::codecvt<wchar_t,char,std::mbstate_t>> Conv
(newstd::codecvt<wchar_ T,char,std::mbstate_t> ("CHS"));
Wide character to narrow character
string str = conv.to_bytes (L "Hello");
The narrow character is converted to a wide character
string wstr = Conv.from_bytes (str);
Boost.property_tree when parsing an XML file that contains Chinese, you need to convert the file first. Boost Solution:
#include "boost/program_options/detail/utf8_codecvt_facet.hpp"
void Parsechn ()
{
Std::wifstream f ( FileName);
Std::locale Utf8locale (Std::locale (), new boost::p rogram_options::d etail::utf8_codecvt_facet ());
F.imbue (Utf8locale); First convert
///Use Wptree to resolve
property_tree::wptree Ptree;
Property_tree::read_xml (f, ptree);
One drawback of this approach is the introduction of Boost's Libboost_program_options library, which has more than 20 m, just to solve a Chinese problem, but it's a bit of a hassle. Fortunately, C++11 offers a simpler way to do this with c++11:
void Init (const wstring& filename, wptree& ptree)
{
std::wifstream f (filename);
Std::locale Utf8locale (Std::locale (), new std::codecvt_utf8<wchar_t>);
F.imbue (Utf8locale); First convert
///use Wptree to parse
property_tree::read_xml (f, ptree);
}
With c++11, you don't need to introduce boost's libboost_program_options library, it's simple. Alternatively, you can get the Chinese string by using Ptree and string, just after you remove the string and do a conversion to Unicode. For example:
Auto Child = Item.second.get_child ("Scenes.scene");
Auto Oname = child.get_optional<string> ("<XMLATTR>. Name ");
Oname inside a Unicode string that needs to be converted to a wide string to get the Chinese
std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
std::wstring wide = converter.from_bytes (*oname);
The wide string is converted to a narrow string
//std::string narrow = converter.to_bytes (L "foo");
BOOST writes XML file format problem
The main use of boost::p roperty_tree::xml_writer_settings. If the compiler uses the C++11, use the following notation to indent two spaces:
Boost::p roperty_tree::xml_writer_settings<char> settings (', 2);
Boost::p roperty_tree::write_xml (filename, pt,std::local (), settings);
If there is no c++11 feature, then use the Xml_writer_make_settings method:
Boost::p roperty_tree::xml_writer_settings<string> settings =
bp::xml_writer_make_settings<string > (', 2);
Boost::p Roperty_tree::write_xml (Xml_path, Root, Locale (), settings);