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应用程序
照着视频自学
网友评论