XML解析 簡單讀寫

  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;
}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章