• TinyXML2 的使用


    TinyXML是一个开源的解析XML的解析库,能够用于C++,能够在Windows或Linux中编译。这个解析库的模型通过解析XML文件,然后在内存中生成DOM模型,从而让我们很方便的遍历这棵XML树。
    DOM模型即文档对象模型,是将整个文档分成多个元素(如书、章、节、段等),并利用树型结构表示这些元素之间的顺序关系以及嵌套包含关系。 

    在TinyXML中,根据XML的各种元素来定义了一些类:
      XmlNode:对应于DOM结构中的节点的基类,定义了节点转换,节点遍历及节点操作(增,删,查,改)

    class XMLNode
    {
        //转换接口
        virtual XMLElement*    ToElement();
        virtual XMLText*        ToText();
        virtual XMLComment*    ToComment();
        virtual XMLDocument*    ToDocument();
        virtual XMLDeclaration*    ToDeclaration();
        virtual XMLUnknown*    ToUnknown();
        
        const char* Value() const;        //获取元素名称
        void SetValue( const char* val, bool staticMem=false );    //修改元素名称
    
        XMLNode* Parent();
        bool NoChildren() const;
        
        XMLNode*    FirstChild();
        XMLNode*    LastChild();
        const XMLElement* FirstChildElement( const char* name = 0 ) const;
        const XMLElement* LastChildElement( const char* name = 0 ) const;
    
        XMLNode*    PreviousSibling();
        XMLNode*    NextSibling();
        const XMLElement*    PreviousSiblingElement( const char* name = 0 ) const ;    //获取上一个元素
        const XMLElement*    NextSiblingElement( const char* name = 0 ) const;        //获取下一个元素
        
        XMLNode* InsertEndChild( XMLNode* addThis );
        XMLNode* InsertFirstChild( XMLNode* addThis );
        XMLNode* InsertAfterChild( XMLNode* afterThis, XMLNode* addThis );
    
        void DeleteChildren();            //删除所有节点
        void DeleteChild( XMLNode* node );    //删除指定节点
    }
    View Code

      XmlDeclaration:public XMLNode    对应于XML中的申明部分,即<?versiong="1.0" ?>
      XmlDocument:public XMLNode     对应于XML的整个文档,定义了XML文件(加载,保存)及创建元素(Declaration,Element,Comment,Text)的操作

    class TINYXML2_LIB XMLDocument : public XMLNode
    {
    public:
        XMLError LoadFile( const char* filename );
        XMLError SaveFile( const char* filename, bool compact = false );
    
        bool HasBOM() const;            //检测是否含BOM
        void SetBOM( bool useBOM );
    
        XMLElement* RootElement() {        //获取根节点元素
            return FirstChildElement();
        }
        
        //没有提供XMLPrinter,则输出至stdout,提供XMLPrinter则可以输出至内存或文件(见XmlPrinter操作)
        void Print( XMLPrinter* streamer=0 ) const;
    
        XMLElement* NewElement( const char* name );
        XMLComment* NewComment( const char* comment );
        XMLText* NewText( const char* text );
        XMLDeclaration* NewDeclaration( const char* text=0 );
        XMLUnknown* NewUnknown( const char* text );
    }
    View Code

      XmlElement:public XMLNode        对应于XML的元素,封装了对元素名称和元素属性及Text操作

    class TINYXML2_LIB XMLElement : public XMLNode
    {
    public:
        const char* Name() const;                //获取元素名称
        void SetName( const char* str, bool staticMem=false );//设置元素名称
        const char* GetText() const;            //获取Text内容
        void SetText( const T* text );        //设置Text内容
        XMLError QueryTText( T* ival ) const;    //以T类型的方式获取Text内容
        
        //属性name存在则修改属性值,不存在则增加属性和值
        const char* Attribute( const char* name, const char* value=0 ) const;
        T TAttribute( const char* name ) const;    //以T类型的方式获取属性的值
        XMLError QueryTAttribute( const char* name, T* value ) const;    //以T类型的方式获取属性的值
        T QueryAttribute( const char* name, T* value ) const;            //以T类型的方式获取属性的值
        void DeleteAttribute( const char* name );        //删除属性
    
        const XMLAttribute* FirstAttribute() const;        //获取第一个属性
        const XMLAttribute* FindAttribute( const char* name ) const;//查找第一个属性
    }
    View Code

      XmlComment:public XMLNode  对应于XML中的注释
      XmlText:public XMLNode      对应于XML的文字部分
      XmlAttribute               对应于XML中的元素的属性,定义了属性查询和修改接口

    class TINYXML2_LIB XMLAttribute
    {
        const char* Name() const;        //获取属性名称
        const char* Value() const;        //获取属性值
    
        const XMLAttribute* Next() const;    //获取下一个属性
    
        int         IntValue() const;            //将属性值转换为int类型
        unsigned UnsignedValue() const;
        bool     BoolValue() const;
        double      DoubleValue() const;
        float     FloatValue() const;
    
        XMLError QueryIntValue( int* value ) const;        //以指定的类型获取属性值
        XMLError QueryUnsignedValue( unsigned int* value ) const;
        XMLError QueryBoolValue( bool* value ) const;
        XMLError QueryDoubleValue( double* value ) const;
        XMLError QueryFloatValue( float* value ) const;
    
        void SetAttribute( const char* value );
        void SetAttribute( int value );
        void SetAttribute( unsigned value );
        void SetAttribute( bool value );
        void SetAttribute( double value );
        void SetAttribute( float value );
    }
    View Code

      XmlUnknown    对应于XML的未知部分
      XmlHandler        定义了针对XML节点指针判断是否为nullptr操作
      XMLPrinter         定义了XML打印操作,将XmlDocument内容打印到内存或文件,无需经XmlDocument构建简单的XML文件

    XmlPrinter功能:
    //1.打印到内存
    XMLPrinter printer;
    doc.Print(&printer);
    SomeFunction(printer.CStr());
    
    //2.打印输出到文件
    XMLPrinter printer(fp);
    doc.Print(&printer);
    
    //3.无需经XMLDocument创建一个简单的XML
    XMLPrinter printer(fp);
    printer.OpenElement("foo");
    printer.PushAttribute("foo", "bar");
    printer.CloseElement();
    View Code

    例如:

    <xml version="1.0" standalone=no>
    <!– Our to do list data –>
    <ToDo>
    <Item priority="1"> Go to the <bold>Toy store!</bold></Item>
    <Item priority="2"> Do bills</Item>
    </ToDo> 

    整个对象树:
      TiXmlDocument "demo.xml"
      TiXmlDeclaration "version=’1.0′" "standalone=no"
      TiXmlComment " Our to do list data"
      TiXmlElement "ToDo"
      TiXmlElement "Item" Attribtutes: priority = 1
      TiXmlText "Go to the "
      TiXmlElement "bold"
      TiXmlText "Toy store!"
      TiXmlElement "Item" Attributes: priority=2
      TiXmlText "Do bills"

     举例:

    #include <iostream>
    #include <array>
    #include <vector>
    
    #include "tinyxml2.h"
    
    using namespace tinyxml2;
    
    void read_xml()
    {
        XMLDocument doc;
        doc.LoadFile("class.xml");
    
        auto root_elec = doc.RootElement();            //等同于不指定参数的FirstChildElement()
        auto root_ele_attr = root_elec->FirstAttribute();
    
        std::cout << root_ele_attr->Name() << ":" << root_ele_attr->Value() << std::endl;
        root_elec->SetAttribute("classid", "188");    //键相同则覆盖,不同则增加
        std::cout << root_ele_attr->Name() << ":" << root_ele_attr->Value() << std::endl;
    
        std::cout << "---------------------teacher-----------------------" << std::endl;
        auto child_elec = root_elec->FirstChildElement()->FirstChildElement();
        while (child_elec) {
            std::cout << child_elec->Name() << ":" << child_elec->GetText();
            auto sex = child_elec->IntAttribute("sex") ? "" : "";
            auto super = child_elec->IntAttribute("super") ? "特级老师" : "普通老师";
            std::cout << "    " << sex << "    " << super;
            std::cout << std::endl;
    
            child_elec = child_elec->NextSiblingElement();
        }
    
        std::cout << "---------------------student-----------------------" << std::endl;
        auto student_elec = root_elec->FirstChildElement("student")->FirstChildElement();
        while (student_elec) {
            auto server_ele_attr = student_elec->FirstAttribute();
            while (server_ele_attr) {
                std::cout << server_ele_attr->Name() << ":" << server_ele_attr->Value() << "    ";
                server_ele_attr = server_ele_attr->Next();
            }
            
            std::cout << std::endl;
    
            auto score_elec = student_elec->FirstChildElement();
            while (score_elec) {
                std::cout << score_elec->Name() << ":" << score_elec->GetText() << "    ";
                score_elec = score_elec->NextSiblingElement();
            }
    
            std::cout << std::endl;
            std::cout << "-----------------------------------------------" << std::endl;
    
            student_elec = student_elec->NextSiblingElement();
        }
    
        //xmlhandler封装了对节点指针判断null的操作,可以安全的执行下面的操作
        XMLHandle docHandle(&doc);
        auto node = doc.FirstChildElement()->FirstChildElement()->FirstChildElement();
        std::cout << node->Name() << "    " << node->GetText() << std::endl;
    }
    
    void write_xml()
    {
        XMLDocument doc;
        auto decl_elec = doc.NewDeclaration();    //不传参会添加默认XML头信息
        doc.InsertFirstChild(decl_elec);
    
        auto class_elec = doc.NewElement("class");
        doc.InsertAfterChild(decl_elec, class_elec);
        class_elec->SetAttribute("classid", 176);
    
        auto teacher_elec = doc.NewElement("teacher");
        class_elec->InsertEndChild(teacher_elec);
    
        std::array<std::string, 2> elec_name = { "chinese", "math" };
        std::array<std::string, 2> teacher_name = { "张三", "李四" };
        std::array<std::string, 2> attr_name = { "sex", "super"};
        for (int i = 0; i < elec_name.size(); i++) {
            auto elec = doc.NewElement(elec_name[i].c_str());
            elec->SetText(teacher_name[i].c_str());
            teacher_elec->InsertEndChild(elec);
            for (int m = 0; m < attr_name.size(); m++) {
                elec->SetAttribute(attr_name[i].c_str(), m);
            }
        }
    
        auto student_elec = doc.NewElement("student");
        class_elec->InsertEndChild(student_elec);
    
        std::array<std::string, 3> stu_attr_name = { "name", "age", "address" };
        std::vector<std::array<std::string, 3>> stu_attr_vec = {{ "张一", "15", "北京" },{ "王二", "17", "天津" },{ "谭三", "15", "河北" },{ "横四", "16", "广州" },{ "蒋五", "15", "北京" }};
        std::vector<std::array<int, 2>> stu_score_vec = { {98, 88}, {56, 61}, {85, 76}, {91, 95}, {77, 64} };
        for (int i = 0; i < 5; i++) {
            auto node_elec = doc.NewElement("node");
            for (int m = 0; m < stu_attr_name.size(); m++) {
                node_elec->SetAttribute(stu_attr_name[m].c_str(), stu_attr_vec[i][m].c_str());
            }
    
            for (int n = 0; n < stu_score_vec[0].size(); n++) {
                auto elec_name = n == 0 ? "chinese_score" : "math_score";
                auto score_node_elec = doc.NewElement(elec_name);
                score_node_elec->SetText(stu_score_vec[i][n]);
                node_elec->InsertEndChild(score_node_elec);
            }
            student_elec->InsertEndChild(node_elec);
        }
    
        doc.SaveFile("class.xml");
    }
    
    int main( int argc, const char ** argv )
    {
        write_xml();
        read_xml();
    }

    打印输出为:

    classid:176
    classid:188
    ---------------------teacher-----------------------
    chinese:张三    男      普通老师
    math:李四       女      特级老师
    ---------------------student-----------------------
    name:张一       age:15  address:北京
    chinese_score:98        math_score:88
    -----------------------------------------------
    name:王二       age:17  address:天津
    chinese_score:56        math_score:61
    -----------------------------------------------
    name:谭三       age:15  address:河北
    chinese_score:85        math_score:76
    -----------------------------------------------
    name:横四       age:16  address:广州
    chinese_score:91        math_score:95
    -----------------------------------------------
    name:蒋五       age:15  address:北京
    chinese_score:77        math_score:64
    -----------------------------------------------
    chinese 张三
    View Code
  • 相关阅读:
    关于数据库的alter table操作和索引概念
    mysql_fetch_array()和 mysql_fetch_array()的区别
    left 截取
    学会设置五大类MySQL参数
    MySQL性能优化的最佳20+条经验
    varchar to int error
    2003服务器重启
    缺少注释的结尾标记 '*/'。 '*' 附近有语法错误。
    2003的服务器终端服务器超出最大连接数的解决办法转载
    电脑报警音解读转载
  • 原文地址:https://www.cnblogs.com/DswCnblog/p/6689979.html
Copyright © 2020-2023  润新知