美文网首页
任意xml的序列化和反序列化

任意xml的序列化和反序列化

作者: 爱吃花栗鼠的猫 | 来源:发表于2017-12-18 17:46 被阅读47次

    我用递归的方法,实现了任意xml数据反序列化到一个类中,然后在序列化出来。用来撸onvif协议,好用极了。
    当然,有很多序列化的工具,比如boost的serial, cereal等,但是这些工具的共同缺点就是你需要事先知道节点是什么,有一个先知的前提。

    当然用递归的方式的一个隐患就是栈空间溢出,要小心点。

    //
    // Created by yangkai on 12/18/17.
    //
    
    #ifndef ONVIF_XMLNODE_H
    #define ONVIF_XMLNODE_H
    
    
    #include <string>
    #include <map>
    #include <vector>
    #include <rapidxml.hpp>
    
    class NodeInfo {
    public:
        NodeInfo() {}
    
        ~NodeInfo() {}
    
    public:
        std::string _name;
        std::map<std::string, std::string> _attributes;
        std::string value;
    
        std::vector<NodeInfo *> _child;
    };
    
    void scan_xml_node(const rapidxml::xml_node<> *node, NodeInfo *pnode);
    void free_node(NodeInfo *pnode);
    void serial_xml_node(NodeInfo *pnode, rapidxml::xml_document<> &doc, rapidxml::xml_node<> *father);
    
    
    #endif //ONVIF_XMLNODE_H
    
    

    实现:

    //
    // Created by yangkai on 12/18/17.
    //
    
    #include <cstring>
    #include "XmlNode.h"
    
    void scan_xml_node(const rapidxml::xml_node<> *node, NodeInfo *pnode) {
    
        if (NULL == node || NULL == pnode) {
            return;
        }
    
        //name
        pnode->_name = node->name();
    
        //attribute
        for (rapidxml::xml_attribute<> *attr = node->first_attribute(); attr; attr = attr->next_attribute()) {
            pnode->_attributes.insert(std::make_pair(attr->name(), attr->value()));
        }
    
        //value
        if (strlen(node->value()) > 0) { //no child node
            pnode->value = node->value();
        } else {
            for (rapidxml::xml_node<> *n = node->first_node(); n; n = n->next_sibling()) {
    
                NodeInfo *child = new NodeInfo();
                pnode->_child.push_back(child);
    
                scan_xml_node(n, child);
            }
        }
    }
    
    void free_node(NodeInfo *pnode) {
        if (NULL == pnode) {
            return;
        }
    
        if (pnode->_child.empty()) {
            delete pnode;
            pnode = NULL;
            return;
        }
    
        if (pnode->_child.size() > 0) {
            for (std::vector<NodeInfo *>::iterator it = pnode->_child.begin();
                 it != pnode->_child.end();
                 ++it) {
                NodeInfo *ptmp = *it;
                free_node(ptmp);
            }
        }
    
        delete pnode;
        pnode = NULL;
    }
    
    void serial_xml_node(NodeInfo *pnode, rapidxml::xml_document<> &doc, rapidxml::xml_node<> *father) {
        if (NULL == pnode) {
            return;
        }
    
        rapidxml::xml_node<> *mount = doc.allocate_node(rapidxml::node_element, pnode->_name.c_str(),
                                                        pnode->value.empty() ? NULL : pnode->value.c_str());
        for (std::map<std::string, std::string>::iterator it = pnode->_attributes.begin();
             it != pnode->_attributes.end();
             ++it) {
            mount->append_attribute(doc.allocate_attribute((it->first).c_str(), (it->second).c_str()));
        }
    
        if (NULL == father) {
            doc.append_node(mount);
        } else {
            father->append_node(mount);
        }
    
        for (std::vector<NodeInfo *>::iterator it = pnode->_child.begin();
             it != pnode->_child.end();
             ++it) {
            serial_xml_node(*it, doc, mount);
        }
    }
    
    

    相关文章

      网友评论

          本文标题:任意xml的序列化和反序列化

          本文链接:https://www.haomeiwen.com/subject/yzbmwxtx.html