美文网首页C/C++
(三十七)XML编程

(三十七)XML编程

作者: RGiskard | 来源:发表于2018-11-13 14:00 被阅读1次

    XML

    XML(EXtensible Markup Language)可扩展标记语言。本想设计为取代HTML

    实际上应用较为简单,够不上语言的级别

    XML是一个数据格式,比如下面

    <?xml version="1.0" encoding="GBK"?>
    <root>
        <host> afanihao.cn </host>
        <port> 8080  </port>
    </root>
    

    传入了两个数据,一个是域名,一个是端口号

    • 优点:可读性强
    • 缺点:解析费时,占用空间大,效率低

    XML文件的格式

    • 声明

      <?xml version="1.0" encoding="GBK"?>
      
    • DTD(经常省略,用于验证)

      <!DOCTYPE...xxx.dtd...>
      
    • 内容

      <root>
        <host> afanihao.cn </host>
        <port> 8080  </port>
      </root>
      

    XML文档是一个由元素构成的树形结构,root,host,port都是元素,必须配对

    <name> dadada </name>
    <Name> dadada </Name>
    

    直接用浏览器打开,能打开没显示问题就是正确的

    元素的属性
    <note id = "110" page = "1">
        <time> 2018/11/11 </time>
    </note>
    
    文档结构

    必须有一个唯一的根元素<root></root>,名字可以随意改

    处于同一级别下的元素为兄弟元素,比如<host>和<port>就是兄弟元素

    兄弟元素可以同名

    <phone> 110 </phone>
    <phone> 119 </phone>
    
    形式良好的与内容合法的

    语法检查没有问题,就是形式良好的。但不一定内容合法(由DTD来检验)

    <?xml version = "1.0" encoding = "GBK"?>
    <root>
        <host> afanihao.cn </host>
        <port> ha ha ha </port>
    </root>
    

    生成XML文档

    tinyxml库:一个小巧的xml库,可以生成和解析XML文档,可以直接将源代码加载到项目中

    #include "tinyxml/tinyxml.h"
    //#include "..tinyxml/tinyxml.h"表示先到向上的文件夹,再进入tinyxml文件夹
    //XML文件对象
    TiXmlDocument xml_doc
    
    //添加声明和元素
    //方法1直接保存到文件
    xml_doc.SaveFile("test.xml");
    
    //方法2转成string
    string text;
    text << xml_doc;
    
    #include <stdio.h>
    #include <string>
    using namespace std;
    
    #include "tinyxml/tinyxml.h"
    
    int test1()
    {
        TiXmlDocument xml_doc;
    
        // 添加XML声明
        xml_doc.LinkEndChild(new TiXmlDeclaration( "1.0", "GBK", "" ));
    
        // 添加根元素
        TiXmlElement * xml_root = new TiXmlElement("root");
        xml_doc.LinkEndChild(xml_root);
    
        // 在根元素下添加其他子元素
        if(1)
        {
            // 添加host
            TiXmlElement* xml_child = new TiXmlElement("host"); 
            xml_root->LinkEndChild(xml_child );
            // 添加文档内容
            xml_child->LinkEndChild( new TiXmlText("afanihao.cn"));
    
            // 设置属性
            xml_child->SetAttribute("checked", "true");
            xml_child->SetAttribute("station", 1001);
        }
    
        if(1)
        {
            // 嵌套子元素
            TiXmlElement* xml_client = new TiXmlElement("client"); 
            xml_root->LinkEndChild(xml_client );
    
            TiXmlElement* xml_clientName = new TiXmlElement("name"); 
            xml_clientName->LinkEndChild( new TiXmlText("shaofa"));
            xml_client->LinkEndChild(xml_clientName);
    
            TiXmlElement* xml_clientId = new TiXmlElement("id"); 
            xml_clientId->LinkEndChild( new TiXmlText("200501"));
            xml_client->LinkEndChild(xml_clientId);
        }
    
        // 保存到文件    
        xml_doc.SaveFile("example02a.xml");
    
        // 或者转成string,调试状态下可见
        string text ;
        text << xml_doc;
        return 0;
    }
    
    int main()
    {
        test1();
        return 0;
    }
    
    元素列表

    全为一样名称的兄弟元素

    <?xml version="1.0" encoding="GBK" ?>
    <root>
        <NoteList>
            <Note>
                <id>1</id>
                <when>2016-1-23 10:00</when>
                <who>Wang</who>
                <what>吃饭</what>
            </Note>
            <Note>
                <id>2</id>
                <when>2016-1-21 20:00</when>
                <who>Jiang</who>
                <what>看电影</what>
            </Note>
            <Note>
                <id>3</id>
                <when>2016-1-20 9:00</when>
                <who>Li</who>
                <what>去博物馆</what>
            </Note>
        </NoteList>
    </root>
    
    #include <stdio.h>
    #include <vector>
    using namespace std;
    
    #include "tinyxml/AfTinyXml.h"
    
    struct Note
    {
        int id;
        char when[32];
        char who[32];
        char what[128];
    };
    
    vector<Note> notes;
    
    int save()
    {
        TiXmlDocument xml_doc;
        xml_doc.LinkEndChild(new TiXmlDeclaration( "1.0", "GBK", "" ));
    
        TiXmlElement * xml_root = new TiXmlElement("root");
        xml_doc.LinkEndChild(xml_root);
    
        TiXmlElement* xml_NoteList = new TiXmlElement("NoteList");
        xml_root->LinkEndChild(xml_NoteList);
    
        // 添加host元素
        for(int i=0; i<notes.size(); i++)
        {
            Note& r = notes[i];
    
            TiXmlElement* xml_Note = new TiXmlElement("Note");
            xml_NoteList->LinkEndChild(xml_Note);
    
            AfTinyXml::addChild(xml_Note, "id", r.id);
            AfTinyXml::addChild(xml_Note, "when", r.when);
            AfTinyXml::addChild(xml_Note, "who", r.who);
            AfTinyXml::addChild(xml_Note, "what", r.what);
        }
    
        xml_doc.SaveFile("example02b.xml");
    
        return 0;
    }
    
    void addNote(int id, const char* when, const char* who, const char* what)
    {
        Note n;
        n.id = id;
        strcpy(n.when, when);
        strcpy(n.who, who);
        strcpy(n.what, what);
        notes.push_back(n);
    }
    
    int main()
    {
        addNote(1, "2016-1-23 10:00", "Wang", "吃饭");
        addNote(2, "2016-1-21 20:00", "Jiang", "看电影");
        addNote(3, "2016-1-20 9:00", "Li", "去博物馆");
    
        save();
        return 0;
    }
    

    解析XML文档

    TiXmlDocument xml_doc;
    xml_doc.LoadFile("test.xml");
    //或者
    //xml_doc.Parse("test.xml");
    
    TiXmlElement* xml_root = xml_doc.RootElement;
    
    #include <stdio.h>
    #include "../tinyxml/tinyxml.h"
    
    int main()
    {
        // 解析xml
        TiXmlDocument xml_doc;
        if(!xml_doc.LoadFile("example02a.xml"))
        {
            return -1;
        }
        
    
        // 根节点
        TiXmlElement* xml_root = xml_doc.RootElement();
        if (NULL == xml_root)
        {
            return -1;
        }
    
        // 获取元素的文本与属性
        if(1)
        {
            TiXmlElement* xml_host = xml_root->FirstChildElement("host");
            const char* text = xml_host->GetText();
            const char* aChecked = xml_host->Attribute("checked");
            const char* aStation = xml_host->Attribute("station");
            printf("text:%s, check:%s, station:%s\n", text, aChecked, aStation);
        }
    
        //
        if(1)
        {
            TiXmlElement* xml_client = xml_root->FirstChildElement("client");
    
            TiXmlElement* xml_clientId = xml_client->FirstChildElement("id");
            TiXmlElement* xml_clientName = xml_client->FirstChildElement("name");
    
            // ...取得id和name的文本 ...
        }
        return 0;
    }
    
    同名称的元素列表
    #include <stdio.h>
    #include <vector>
    #include <string>
    using namespace std;
    
    
    #include "../tinyxml/AfTinyXml.h"
    
    struct Note
    {
        int id;
        char when[32];
        char who[32];
        char what[128];
    };
    
    vector<Note> notes;
    
    int main()
    {
        // 解析xml
        TiXmlDocument xml_doc;
        if(!xml_doc.LoadFile("example02b.xml"))
        {
            return -1;
        }
    
        // 根节点
        TiXmlElement* xml_root = xml_doc.RootElement();
        if (NULL == xml_root)
        {
            return -1;
        }
    
        // 获取元素的文本与属性
    
        TiXmlElement* xml_NoteList = xml_root->FirstChildElement("NoteList");
        if(xml_NoteList)
        {
            TiXmlElement* xml_Note = xml_NoteList->FirstChildElement("Note");
            while(xml_Note)
            {
                // 取得子元素的文本
                int id = AfTinyXml::childAsInt(xml_Note, "id");
                string when = AfTinyXml::childAsText(xml_Note, "when");
                string who = AfTinyXml::childAsText(xml_Note, "who");           
                string what = AfTinyXml::childAsText(xml_Note, "what");
                
                // 保存到列表
                Note r;
                r.id = id;
                strcpy(r.when, when.c_str());
                strcpy(r.who, who.c_str());
                strcpy(r.what, what.c_str());
                notes.push_back(r);
    
                // 下一个兄弟元素
                xml_Note = xml_Note->NextSiblingElement("Note");
            }
        }
    
        return 0;
    }
    

    XML应用实例-配置文件

    应用场景

    • 保存配置文件:将用户的配置保存到xml文件里
    • 服务器的RESTful接口(如亚马逊的云服务接口)
    • WebService接口

    示例:一个用于Qt实现的GUI应用程序

    照着视频自学

    相关文章

      网友评论

        本文标题:(三十七)XML编程

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