Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
coneo opened this issue Oct 26, 2014 · 0 comments
Open

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

coneo opened this issue Oct 26, 2014 · 0 comments
Labels

Comments

@coneo
Copy link
Owner

coneo commented Oct 26, 2014

最近对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(可以根据需要定制),不过使用起来还算方便。代码放在这里

@coneo coneo added the xml label Oct 26, 2014
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant