Skip to content

一个轻量级的XML接口封装 #7

Open
@coneo

Description

@coneo

最近对libxml2的C++访问接口做了一层浅浅的封装,使得实际用起来比较方便。
测试用例

#include "xmlparser.h"
#include <string>
#include <iostream>
#include <sstream>
#include <map>

using namespace std;

class stFoo
{
public:
    stFoo()
    {
        itemList.clear();
    }
    std::string toStr()
    {
        std::ostringstream os;
        os << "index=" << index << std::endl;
        os << "index2=" << index2 << std::endl;
        for (const auto& item : itemList)
        {
            os << "item: id=" << item.first << " name=" << item.second << std::endl;
        }
        return os.str();
    }
    int32_t index {0};
    float index2 {0.0};
    std::map<int32_t,std::string> itemList;
};

bool loadConfig()
{
    stFoo foo;

    XmlParser xml;
    if (!xml.initFile("test.xml")) return false;

    XmlNode root = xml.getRootNode("config");
    if (!root.valid())
    {
        printf("parse config failed\n");
        return false;
    }

    std::string configname = "";
    root.getStr("name", configname);
    cout << configname << endl;

    //parse node_a
    XmlNode nodeA = root.getChild("node_a");
    if (!nodeA.valid())
        return false;

    nodeA.getNum("index", foo.index);
    nodeA.getNum("index2", foo.index2);
    for (XmlNode item = nodeA.getChild("item"); item.valid(); ++item)
    {
        int id = 0;
        item.getNum("id", id);
        std::string name = "";
        item.getStr("name", name);
        foo.itemList[id] = name;
    }
    cout << foo.toStr() << endl;

    return true;
}

int main()
{
    loadConfig();
}

这里实际上主要把xmlNodePtr封装在XmlNode里,我们获取节点信息可以直接通过XmlNode。

获取指定名字的子节点: XmlNode.getChild(str);

获取相同名字的兄弟节点: ++XmlNode;

可以发现,我们要遍历节点的话可以通过父节点调用getChild(),配置++XmlNode实现。

在解析XmlNode属性的时候,我们通过传引用的方式去获取值:

xml.getNum("id", int_value);

xml.getNum("tax", double_value);

之前考虑过另外一种取值方式:

int_value = xml.getNum<int>("id");

double_value = xml.getNum<double>("tax");

其实两种方式内部实现都一样,都是用模板实现,之所以采用按引用取值(方法一),其一是因为按引用取值省去了临时变量以及赋值过程,一定程度上提高效率(虽然这种基本类型的开销并不大);其二是为了减少取值与类型的耦合,试想如果int_value由int类型改变为float,那么方法一的取值过程可以不变,但方法二的解析代码就得变为:

xml.getNum<float>("id", int_value);

恩,如果你改变了int_value的类型,而忘了该这里的解析代码呢,其结果可能就不是你想要的了。

注意

这个轻量级的解析接口实际上只有xml解析功能,不能生成xml,不支持解析Time(可以根据需要定制),不过使用起来还算方便。代码放在这里

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions