今天看啥  ›  专栏  ›  Zbertj

XML解析

Zbertj  · 简书  ·  · 2019-01-08 18:31

  C++对xml的支持是有很多方法的,比如libxml2,tinyxml等等,但是有那么一种时候,我们懒得安装库,也不想弄的那么复杂,只是想简单的读写一个简单的xml配置文件,这里提供一个使用fstream进行读写的简单接口。

#ifndef MYXMLPARSER_H
#define MYXMLPARSER_H
#include <iostream>
#include <string>
#include <fstream>

//只适合单层的xml
namespace MyXmlParser
{
    const std::string xml_path_file = "/mnt/hgfs/MyWork/Template/wmbaseinfo.conf";  //配置文件路径
    const std::string end_root_node = "</DBaseInfo>";   //根节点的结束标签

    //获取xml文件的值 label: <label>
    std::string getXmlValue(const std::string& label);
    bool setXmlValue(const std::string& label, const std::string& value);
    
};

#endif // MYXMLPARSER_H
#include "MyXmlParser.h"


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 "";
}

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<char*>(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;
}

  以下为测试使用接口实例

#include <iostream>
#include <string>
#include "tools/MyXmlParser.h"

int main(int argc, char const *argv[])
{
    std::string a = MyXmlParser::getXmlValue("<ooo>");
    std::cout <<"ooo: "<< a <<std::endl;
    MyXmlParser::setXmlValue("<test222>", "hahahha");
    MyXmlParser::setXmlValue("<ooo>", "rrrrrrr");
    return 0;
}



原文地址:访问原文地址
快照地址: 访问文章快照