关于配置xml的读写以及使用

来源:互联网 发布:手机网络被劫持怎么办 编辑:程序博客网 时间:2024/05/21 19:44
         xml的读写是服务器开发必须要有的一个坑了,xml说白了就是文本内容的一种格式。将文本内容分为不同的节点,每个节点可以由自己的子节点以及属性项。这样当我们读取以及使用的时候就能读取不同的节点,以及加载其相应的属性项。
xml的文本内容多种多样,但说白了就是让程序运行的某些内容可修改。例如你们服务器开通会员有时候是60,搞活动了就做成35块。那你就可以用这个xml作为各种商品价格的文本存储,然后从xml读入商品价格到服务器,当你这个价格需要更改时,你在服务器提供一个接口,用作重新读取xml配置的。这就是服务器热更的一种形式。 客户端读取服务器传来的内容,而服务器读取xml的文本内容,xml可更新重读。
这里主要提c++对于xml的读写,常见的xml读写有好几个库。其中最为知名的大概就是tinyxml以及rapidxml。rapidxml的读入速度非常快,因此作为读入的库最好不过,但是写入的语法稍微复杂一点,tinyxml的读写速度步入rapidxmnl,不过写的语句要规范一点。这两个在项目里面一个作为写(xls生成xml)一个作为读,倒是一个不错选择。
下面先来介绍rpaidxml的用法:
       首先,在需要读到xml的地方,需要加入以下上个头文件:

#include "NFComm/RapidXML/rapidxml.hpp"
#include "NFComm/RapidXML/rapidxml_print.hpp"
#include "NFComm/RapidXML/rapidxml_utils.hpp"

2.使用ReadConfig()初始化所有装xml内容的容器,调用读入xml相应的函数使用。当需要热更配置时直接调用ReadConfig。

bool NFCAuctionModule::ReadConfig()
{
    numericalValue.clear();
    SpecialValue.clear();
    permitSellEquip.clear();
    timeLimt.clear();
    mxEquipConfig.clear();

    std::string strEquipPath = pPluginManager->GetConfigPath();
    strEquipPath += "./Ini/Common/abc.xml";
    LoadAbcConfig(strEquipPath);

    strEquipPath = pPluginManager->GetConfigPath();
    strEquipPath += "./Ini/Common/Shop.xml";
    LoadEquipConfig(strEquipPath);
    return true;
}

3.使用函数读取xml。
    rapidxml::file<> xFileSource(strPath.c_str());  //读入文件地址,如果文件不存在会在此处报错
    rapidxml::xml_document<>  xFileDoc;//文件结构体
    xFileDoc.parse<0>(xFileSource.data());  //解析所传入地址的xml,如果xml语法有错会在此处报错
    rapidxml::xml_node<>* root = xFileDoc.first_node();  //指向xml的第一个节点,即根节点
    rapidxml::xml_node<>* fNode = root->first_node("AuctionLimt");
                       //指向根结点的第一个子节点,填入string后则读取特有节点

//循环读取fNode下面的子节点,其中next_sibling()指向下一个兄弟节点,若fNodeEX空则不读取。
for (rapidxml::xml_node<>* fNodeEX = fNode->first_node(); fNodeEX; fNodeEX = fNodeEX->next_sibling())
    {
        std::string strId = fNodeEX->first_attribute("TimeLimt")->value(); 
                        //读入特定节点的属性TimeLimt      提出属性的值,注意返回值均为string
        timeLimt.push_back(lexical_cast<int>(strId));
    }

4.上面便是一个完整的xml读写流程,其中,可以看出来,rapidxml对节点和属性都以指针的方式操作,并且节点以及属性都是一个相应的结构体,有相应的函数。下面再来浅谈一下其它函数的使用。
先从node来说:
->append_attribute(追加加入属性 rapidxml::xml_attribute<>*);
->insert_attribute(插入属性节点,where前 rapidxml::xml_attribute<>* whererapidxml::xml_attribute<>* attribute);
->append_node(加入子节点!! rapidxml::xml_node<>* );
->insert_attribute(用法同上)

//last_node与last_attribute的用法与first相近,这里不介绍了。
prepend_attribute,prepend_node,previous_sibling
//上一个属性节点,上一个子节点,上一个兄弟节点。可以看出node的容器是一个双端队列,并且储存了父亲节点的指针。

->name(返回节点名字,name_size可知道名字大小)
->parent()返回父亲节点。

->remove_node(rapidxml::xml_node<>* ),->remove_attribute(rapidxml::xml_attribute<>*)
->remove_first_attribute(),->remove_all_attributes()
->remove_first_node(), ->remove_all_node()
//上面这些均为删除的函数

attribute节点:
->parent() //属性对应的父节点
->value_size() //值大小

->name()  //属性名字

->next_attribute(),->previous_attribute()  //前后的属性节点