Boost PropertyTree 所提供的 XML Parser 基本上是基于一个小巧快速的开源XML解析器RapidXML 这个 OpenSource 的 XML parser 来的;而官方文件裡也有提到,他并没有完整地支援 XML 所有的标准(例如他无法处理 DTD、也不支援 encoding 的处理),这是在使用上要注意的地方。不过对于一般使用来说,基本上应该是够用了。
boost中提供了对配置文件读取的支持,它就是:property_tree。
basic_ptree 是property_tree的核心基础。其接口像std::list。可以执行很多基本的元素操作,比如使用begin()、end()等。此外还加入了操作属性树的get()、get_child()、get_value()、data()等额外的操作。
<Capture fillter="tcp"/>
<Analysis>
<soinfo desc="analysis1" path="/rootMysqlCaptureweibo.so1" version="123"/>
<soinfo desc="analysis4" path="/rootMysqlCaptureweibo.so2" version="456"/>
<soinfo desc="analysis7" path="/rootMysqlCaptureweibo.so3" version="789"/>
</Analysis>
<Output>
<rule>
<cond key="1" value="2" relation="3"/>
<cond key="4" value="5" relation="6"/>
<cond key="7" value="8" relation="9"/>
<out where="file" dir="/root" dbname="" table=""/>
</rule>
<rule>
<cond key="11" value="12" relation="13"/>
<cond key="14" value="15" relation="16"/>
<cond key="17" value="18" relation="19"/>
<out where="oracle" dir="" dbname="/root/home" table=""/>
</rule>
<rule>
<cond key="21" value="22" relation="23"/>
<cond key="24" value="25" relation="26"/>
<cond key="27" value="28" relation="29"/>
<out where="mysql" dir="" dbname="" table="/root/home/liu"/>
</rule>
</Output>
</root>
#include <iostream>
#include <boost/property_tree/ptree.hpp>
#include <boost/property_tree/xml_parser.hpp>
#include <boost/typeof/typeof.hpp>
#include <boost/foreach.hpp>
#include <string>
#include <vector>
#include <exception>
std::string CaptureFillter;
struct AnalysisSoInfo {
std::string desc;
std::string path;
std::string version;
};
typedef std::vector<AnalysisSoInfo> AnalysisSetting;
struct AtomCondition {
std::string key;
std::string value;
std::string relation;
};
typedef std::vector<AtomCondition> OutputCondition;
struct OutputWhere {
std::string _where;
std::string _dir;
std::string _dbname;
std::string _table;
};
struct OutputRule {
OutputCondition _outputCondition;
OutputWhere _outputWhere;
};
typedef std::vector<OutputRule> OutPutSetting;
void fun(std::vector<OutputRule> v_output) {
std::cout << "size" << v_output.size() << std::endl;
std::vector<OutputRule>::iterator itr;
for (itr = v_output.begin(); itr != v_output.end(); itr++) {
std::cout <<"where=" <<itr->_outputWhere._where ;
std::cout <<" dir="<< itr->_outputWhere._dir ;
std::cout <<" dbname="<< itr->_outputWhere._dbname ;
std::cout <<" table="<< itr->_outputWhere._table <<std::endl;
OutputCondition::iterator itrout;
for (itrout = itr->_outputCondition.begin(); itrout != itr->_outputCondition.end(); itrout++) {
std::cout <<"key="<< itrout->key ;
std::cout <<" value=" <<itrout->value ;
std::cout <<" relation="<< itrout->relation << std::endl;
}
}
}
int main() {
using namespace boost::property_tree;
char szXmlFile[] = "set.xml";
ptree pt;
read_xml(szXmlFile, pt); // 读取xml文件,并转成property tree
ptree& root = pt.get_child("root"); //定位到root节点
ptree& capture = pt.get_child("root.Capture"); //定位到Capture节点
CaptureFillter = capture.get< std::string>("<xmlattr>.fillter");
std::cout << " Capture fillter =" << CaptureFillter << std::endl;
ptree& analysis = pt.get_child("root.Analysis"); //定位到Analysis节点
AnalysisSetting v_analysissetting;
AnalysisSoInfo temp_soinfo;
BOOST_FOREACH(ptree::value_type &v1, analysis) //遍历analysis节点
{
if (v1.first == "soinfo")
{
temp_soinfo.desc.clear();
temp_soinfo.path.clear();
temp_soinfo.version.clear();
temp_soinfo.desc = v1.second.get<std::string>("<xmlattr>.desc");
temp_soinfo.path = v1.second.get<std::string>("<xmlattr>.path");
temp_soinfo.version = v1.second.get<std::string>("<xmlattr>.version");
if ((temp_soinfo.desc.empty()) || (temp_soinfo.path.empty()) || (temp_soinfo.version.empty())) {
std::cout << "one of the temp_soinfo is empty" << std::endl;
return -1;
}
}
v_analysissetting.push_back(temp_soinfo);
std::cout << "desc=" << temp_soinfo.desc;
std::cout << " path=" << temp_soinfo.path;
std::cout << " version=" << temp_soinfo.version << std::endl;
}
ptree& output = pt.get_child("root.Output"); 定位到Output节点
OutPutSetting v_outputsetting;
AtomCondition temp_condition;
OutputWhere temp_where;
OutputRule temp_rule;
for (ptree::iterator itr = output.begin(); itr != output.end(); itr++) {
OutputCondition v_outputcondition; //一个rule节点,一个vector
ptree rule = itr->second;
BOOST_FOREACH(ptree::value_type &v2, rule)
{
if (v2.first == "cond") {
temp_condition.key.clear();
temp_condition.value.clear();
temp_condition.relation.clear();
temp_condition.key = v2.second.get<std::string>("<xmlattr>.key");
temp_condition.value = v2.second.get<std::string>("<xmlattr>.value");
temp_condition.relation = v2.second.get<std::string>("<xmlattr>.relation");
if ((temp_condition.key.empty()) || (temp_condition.value.empty()) || (temp_condition.relation.empty())) {
std::cout << "one of the temp_condition is empty" << std::endl;
return -1;
} //此处判空,未获取到,则退出
v_outputcondition.push_back(temp_condition);
}
if (v2.first == "out") {
temp_where._where.clear();
temp_where._dir.clear();
temp_where._dbname.clear();
temp_where._table.clear();
temp_where._where = v2.second.get<std::string>("<xmlattr>.where");
temp_where._dbname = v2.second.get<std::string>("<xmlattr>.dbname");
temp_where._dir = v2.second.get<std::string>("<xmlattr>.dir");
temp_where._table = v2.second.get<std::string>("<xmlattr>.table");
if (temp_where._where.empty()) {
std::cout << "temp_where._where is empty" << std::endl;
return -1;
}
if (temp_where._dbname.empty() && temp_where._dir.empty() && temp_where._table.empty()) {
std::cout << "the all of temp_where is empty" << std::endl;
return -1;
}
temp_rule._outputWhere = temp_where;
}
}
temp_rule._outputCondition = v_outputcondition;
v_outputsetting.push_back(temp_rule);
}
fun(v_outputsetting);
}