这里提供一个稍微复杂点的xml解析过程,只涉及到读取,和修改,一般读取什么简单的配置文件已经足够了,只为了不想用xml的库。
头文件需要事先配置好配置文件路径和根节点结束标签,多层解析里面的可以不需要结束标签,使用方法可以看注释,很简单。
#ifndef MYXMLPARSER_H
#define MYXMLPARSER_H
#include
#include
#include
#include
//只适合单层的xml
namespace MyXmlParser
{
const std::string xml_path_file = "/mnt/hgfs/MyWork/Template/wmbaseinfo.conf"; //配置文件路径
const std::string end_root_node = ""; //根节点的结束标签
// std::string a = MyXmlParser::getXmlValue("");
std::string getXmlValue(const std::string& label);
// std::string a = MyXmlParser::getXmlValue2(" :2 ", " ");
std::string getXmlValue2(std::string label, const std::string& tag); //单行
std::string getXmlValue3(std::string label, const std::string& tag); //整个文件
//auto a = MyXmlParser::setXmlValue("", "ppppp");
bool setXmlValue(const std::string& label, const std::string& value);
// auto a = MyXmlParser::setXmlValue2(" :2 ", " ", "ppppp");
bool setXmlValue2(std::string label, const std::string& tag, const std::string& value);
};
#endif // MYXMLPARSER_H
/*
#include
#include
#include "tools/MyXmlParser.h"
int main(int argc, char const *argv[])
{
std::string a = MyXmlParser::getXmlValue("");
std::cout <<"ooo: "<< a <", "hahahha");
MyXmlParser::setXmlValue("", "rrrrrrr");
return 0;
}
*/
#include "MyXmlParser.h"
// :2 tag = " "
// <77>
static std::vector strSplit(const std::string& str, const std::string& tag)
{
std::string str_tmp = str + tag;
std::vector str_v;
int index = 0;
while(str_tmp.find(tag, index) != std::string::npos )
{
auto pos = str_tmp.find(tag, index);
// std::cout << "pos:" << pos << std::endl;
std::string a = str_tmp.substr(index, pos - index);
// std::cout << "a:" << a << std::endl;
str_v.push_back(a);
index = pos + 1;
}
return str_v;
}
//转换传进来的字符串格式: :2 =====> :3
static void change_format(std::string& label, const std::string& tag)
{
auto off = 0;
std::string ltag = ":";
while(true)
{
std::string new_str = ""; //
auto pos1 = label.find(ltag, off); //冒号的起始位置
if(pos1 != std::string::npos)
{
auto pos0 = label.rfind(tag, pos1); // 冒号前第一个空格的起始位置
if(pos0 != std::string::npos)
{
new_str = label.substr(pos0, pos1 - pos0); //new_str=" "
}
auto pos2 = label.find(tag, pos1); //冒号后第一个空格的起始位置
if(pos2 != std::string::npos)
{
auto count = std::stoi(label.substr(pos1 + ltag.length(), pos2 - pos1 - ltag.length())); //个数=空格开始位置-冒号结束位置
std::string insert_str = "";
while(count--)
{
insert_str += new_str;
}
// std::cout << "insert_str:" << insert_str << std::endl;//insert_str为覆盖冒号对应标签的字符串
label.replace(pos0, pos2 - pos0, insert_str);
}
off = pos1 + ltag.length();
}
else
{
break;
}
}
}
std::string MyXmlParser::getXmlValue(const std::string& label)
{
if(label.empty())
{
return "";
}
std::ifstream xmlin(MyXmlParser::xml_path_file, std::ios::in);
if(xmlin.is_open())
{
std::string line = "";
while(getline(xmlin, line))
{
if(line.find(label) != std::string::npos && line.find("") != std::string::npos)
{
line = line.substr(line.find(label) + label.length(), std::string::npos);
xmlin.close();
return line.substr(0, line.find(""));
}
}
}
else
{
std::cout << "open "<< MyXmlParser::xml_path_file << " error" << std::endl;
}
return "";
}
//
//一行行匹配
std::string MyXmlParser::getXmlValue2(std::string label, const std::string& tag)
{
if(label.empty())
{
return "";
}
//改变字符串格式
change_format(label, tag);
// std::cout << "label: " << label << std::endl;
std::ifstream xmlin(MyXmlParser::xml_path_file, std::ios::in);
if(xmlin.is_open())
{
std::vector label_v;
label_v = strSplit(label, tag);
std::string line = "";
while(getline(xmlin, line))
{
std::string label_name = "";
if(label_v.size() > 0)
{
label_name = label_v.front();
}
if((label_name != "") && (line.find(label_name) != std::string::npos))
{
auto k = label_v.begin();
label_v.erase(k); // 删除第一个元素
// std::cout << "label_name:" << label_name << std::endl;
if(label_v.size() == 0)
{
line = line.substr(line.find(label_name) + label_name.length(), std::string::npos);
xmlin.close();
return line.substr(0, line.find(""));
}
}
}
xmlin.close();
return "";
}
else
{
std::cout << "open "<< MyXmlParser::xml_path_file << " error" << std::endl;
return "";
}
}
//整个文件匹配
std::string MyXmlParser::getXmlValue3(std::string label, const std::string& tag)
{
if(label.empty())
{
return "";
}
//改变字符串格式
change_format(label, tag);
// std::cout << "label: " << label << std::endl;
std::ifstream xmlin(MyXmlParser::xml_path_file, std::ios::in);
if(xmlin.is_open())
{
std::string content((std::istreambuf_iterator(xmlin)), std::istreambuf_iterator());
// std::cout << content << std::endl;
std::vector label_v;
label_v = strSplit(label, tag);
auto offset = 0;
for(auto label_name :label_v)
{
auto label_pos = content.find(label_name, offset); //标签的位置
if (label_pos != std::string::npos)
{
offset = label_pos + label_name.length();
}
else
{
std::cout << "Not Found" << std::endl;
xmlin.close();
return "";
}
}
auto label_end_pos = content.find("", offset); //最后一个结束标签的位置
std::string tmp = content.substr(offset, label_end_pos - offset);
xmlin.close();
return tmp;
}
else
{
std::cout << "open "<< MyXmlParser::xml_path_file << " error" << std::endl;
return "";
}
}
bool MyXmlParser::setXmlValue(const std::string& label, const std::string& value)
{
if(label.empty() || value.empty())
{
return false;
}
bool write = false;
std::ifstream xmlin(MyXmlParser::xml_path_file, std::ios::in);
if(xmlin.is_open())
{
xmlin.seekg(0, std::ios::end); //基于文件开始位置偏移文件大小的这么多
int length = xmlin.tellg();
xmlin.seekg(0, std::ios::beg);
std::string content(length, 0);
xmlin.read(const_cast(content.c_str()), length);
auto pos = content.find(label);
if(pos != std::string::npos) //有相应标签就修改
{
std::string end_label = "" + label.substr(1, std::string::npos);
auto beg_pos = pos + label.length();
auto end_pos = content.find(end_label);
if(end_pos != std::string::npos)
{
content.replace(beg_pos, end_pos - beg_pos,value);
write = true;
}
}
else //没有就添加
{
std::string new_line = label + value + "" + label.substr(1, std::string::npos);
if(content.find(MyXmlParser::end_root_node) != std::string::npos)
{
content.insert(content.find(MyXmlParser::end_root_node), "\t" + new_line + "\n");
write = true;
}
}
xmlin.close();
if(write)
{
std::ofstream outfile (MyXmlParser::xml_path_file, std::ios::out);
if(outfile.is_open())
{
outfile.write(content.c_str(), content.length());
}
else
{
write = false;
}
}
}
return write;
}
//只支持单个修改不支持添加
bool MyXmlParser::setXmlValue2(std::string label, const std::string& tag, const std::string& value)
{
if(label.empty() || value.empty() || tag.empty())
{
return false;
}
change_format(label, tag);
bool write = false;
std::ifstream xmlin(MyXmlParser::xml_path_file, std::ios::in);
if(xmlin.is_open())
{
xmlin.seekg(0, std::ios::end); //基于文件开始位置偏移文件大小的这么多
int length = xmlin.tellg();
xmlin.seekg(0, std::ios::beg);
std::string content(length, 0);
xmlin.read(const_cast(content.c_str()), length);
std::vector label_v;
label_v = strSplit(label, tag);
auto offset = 0;
std::string last_label = "";
for(auto label_name :label_v)
{
// std::cout << "label_name:" << label_name << std::endl;
auto label_pos = content.find(label_name, offset); //标签的位置
if (label_pos != std::string::npos)
{
offset = label_pos + label_name.length();
}
else
{
std::cout << "Not Found" << std::endl;
xmlin.close();
return false;
}
last_label = label_name;
}
std::string end_label = "" + last_label.substr(1, std::string::npos);
auto beg_pos = offset; //offset = label_pos + label_name.length();
auto end_pos = content.find(end_label, offset);
if(end_pos != std::string::npos)
{
content.replace(beg_pos, end_pos - beg_pos,value);
// std::cout << "test:" << content.substr(beg_pos, end_pos - beg_pos) << std::endl;
write = true;
}
xmlin.close();
if(write)
{
std::ofstream outfile (MyXmlParser::xml_path_file, std::ios::out);
if(outfile.is_open())
{
outfile.write(content.c_str(), content.length());
}
else
{
write = false;
}
}
}
return write;
}