一:摘要
1.XML全称EXtensible Markup Language,翻译为可扩展标记语言,XML文件通常就是一个文本文件,可以使用任何编码
2.TinyXML是一个开源的C++用来处理XML的第三方库
二:说明
1.本篇博客下载的是tinyxml_2_6_2版本,tinyxml_2_6_2下载地址:http://download.csdn.net/download/yzf279533105/9924003
2. 博客内容及所有代码均是在该版本下编译,运行,测试通过的,示例代码下载地址
windows下示例代码:http://download.csdn.net/download/yzf279533105/9942336
Linux下示例代码:(内有介绍文档,请按照文档步骤操作,保证可以运行成功)
使用静态库的示例代码:http://download.csdn.net/download/yzf279533105/9942600
使用动态库的示例代码:http://download.csdn.net/download/yzf279533105/9942605
三.Windows下的编译
1.从上面的地址下载得到tinyxml_2_6_2.zip文件,解压得到tinyxml_2_6_2文件夹
2.进入目录tinyxml_2_6_2/tinyxml,可以看到源代码一共2个头文件,4个源文件,分别是tinyxml.h,tinystr.h,tinyxml.cpp,tinystr.cpp,tinyxmlerror.cpp,tinyxmlparse.cpp
3.由于tinyxml库很小,没必要编译成静态库或者动态库,把上面列举的6个文件拷贝到示例工程目录下即可直接使用
四.Windows下的使用
1.建立一个空的win32控制台工程,类似HellowWorld的工程即可,我这里工程命名为tinyxmlExample
2.在本示例工程根目录添加tinyxml文件夹,把上述列举的6个tinyxml文件拷贝到该目录下,在属性页 配置属性 -> C/C++ -> 常规 -> 附加包含目录 中设置该工程的头文件目录,即“../”,表示附加了根目录
3. 在工程中添加源文件,把整个tinyxml包含进来,这样所有的代码就包含进来了
4. 添加一个源文件main.cpp,代码如下:
#include
#include "tinyxml/tinyxml.h"
using namespace std;
int main()
{
// 新建的xml文件名字
string filename = "example.xml";
//////////////////////////////////////////////////// 新建一个xml文件 ////////////////////////////////////////////////
// 定义一个TiXmlDocument类指针
TiXmlDocument* pWriteDoc = new TiXmlDocument();
// xml的声明(三个属性:版本,编码格式,独立文件声明)
TiXmlDeclaration* pDeclare = new TiXmlDeclaration("1.0", "UTF-8", "yes");
pWriteDoc->LinkEndChild(pDeclare); // 连接到最后
// 根节点
TiXmlElement* pRootElement = new TiXmlElement("telephonebook");
pWriteDoc->LinkEndChild(pRootElement); // 把根节点连接到最后
// 二级节点
TiXmlElement* pPersonElement = new TiXmlElement("person"); //通讯录节点
pRootElement->LinkEndChild(pPersonElement); // 连接到根节点下
// 三级节点
TiXmlElement* pNameElement = new TiXmlElement("name");
// 文本
TiXmlText* nameContent = new TiXmlText("xiaoming"); // 通讯录名字
pNameElement->LinkEndChild(nameContent); // 给三级节点添加文本
pPersonElement->LinkEndChild(pNameElement); // 把三级节点连接到二级节点下
// 三级节点
TiXmlElement* pAddrElement = new TiXmlElement("addr"); // 通讯录地址
// 设置属性
pAddrElement->SetAttribute("addr1","hubei");
pAddrElement->SetAttribute("addr2","wuhan");
pPersonElement->LinkEndChild(pAddrElement); // 把三级节点连接到二级节点下
// 三级节点
TiXmlElement* pEmailElement = new TiXmlElement("email");// 通讯录邮件
// 文本
TiXmlText* emailContent = new TiXmlText("[email protected]");
pEmailElement->LinkEndChild(emailContent); // 给三级节点添加文本
pPersonElement->LinkEndChild(pEmailElement);// 把三级节点连接到二级节点下
/////////////////////////////////////////////////// 保存到文件 ////////////////////////////////////////////////
pWriteDoc->SaveFile(filename.c_str());
printf( "new xml success, file's name is %s\n\n", filename.c_str());
//////////////////////////////////////////////////// 从文件中读取 ////////////////////////////////////////////////
// 定义一个TiXmlDocument类指针
TiXmlDocument* pReadDocument = new TiXmlDocument();
// 读取文件
if (!pReadDocument->LoadFile(filename.c_str()))
{
printf( "Could not load example xml file %s. Error='%s'\n", filename.c_str(),pReadDocument->ErrorDesc() );
return 0;
}
printf("read xml file success, file' name is %s \n\n",filename.c_str());
//读取文档声明信息(第一个子节点转换得到文档声明)
TiXmlDeclaration* pDeclar = pReadDocument->FirstChild()->ToDeclaration();
if (pDeclar != NULL)
{
printf("read declare, version is %s , encoding is %s\n",pDeclar->Version(), pDeclar->Encoding());
}
// 得到文件根节点
pRootElement = pReadDocument->RootElement();
//////////////////////////////////////////////////// 遍历元素,打印 ////////////////////////////////////////////
printf("begin read all xml element \n\n");
// 遍历所有的person
// 函数FirstChildElement() : 找到指定名字的元素
// 函数NextSiblingElement : 在同一级元素中查找下一个指定名字的元素
int i = 0;
for (TiXmlElement* pItem = pRootElement->FirstChildElement("person"); pItem; pItem = pItem->NextSiblingElement("person"))
{
printf("read the %d person \n",++i);
// 名字
TiXmlElement* pName = pItem->FirstChildElement("name");
if (pName != NULL)
{
printf("the %d person's name = %s \n", i, pName->GetText());
}
// 地址
TiXmlElement* pAddr = pItem->FirstChildElement("addr");
if (pAddr != NULL)
{
// 第一个属性
TiXmlAttribute* pAddr1 = pAddr->FirstAttribute();
if (pAddr1 != NULL)
{
printf("the %d person's addr1 = %s \n", i, pAddr1->Value());
// 下一个属性
TiXmlAttribute* pAddr2 = pAddr1->Next();
if (pAddr2 != NULL)
{
printf("the %d person's addr2 = %s \n", i, pAddr2->Value());
}
}
}
printf("\n\n");
}
//////////////////////////////////////////////////// 删除元素,属性 ////////////////////////////////////////////
TiXmlElement* pPerson = pRootElement->FirstChildElement("person");
if (pPerson != NULL)
{
// 这里演示删除"email"元素,删除其他节点也是一样的办法
TiXmlElement* pEmail = pPerson->FirstChildElement("email");
if (pEmail != NULL)
{
pPerson->RemoveChild(pEmail);
}
// 这里演示修改"addr"元素
TiXmlElement* pAddr = pPerson->FirstChildElement("addr");
if (pAddr != NULL)
{
pAddr->SetAttribute("addr2", "huanggang"); // 修改属性值
// 删除属性
//pAddr->RemoveAttribute("addr1");
}
}
////////////////////////////////////////////////////// 增加元素 ////////////////////////////////////////////////
// 新建一个元素,名字:person
TiXmlElement* pNewElement = new TiXmlElement("person");
// 给新建的元素创建子元素并连接到最后
TiXmlElement* pNameElementAdd = new TiXmlElement("name"); // 元素:name
TiXmlText* pNameText = new TiXmlText("zhangsan");
pNameElementAdd->LinkEndChild(pNameText); // 该元素下添加文本内容
TiXmlElement* pAddrElementAdd = new TiXmlElement("addr"); // 元素:addr
pAddrElementAdd->SetAttribute("addr1","guangdong");
pAddrElementAdd->SetAttribute("addr2","shenzhen"); // 该元素下添加属性
TiXmlElement* pEmailElementAdd = new TiXmlElement("email"); // 元素:email
TiXmlText* pEmailText = new TiXmlText("[email protected]");
pEmailElementAdd->LinkEndChild(pEmailText); // 该元素下添加文本内容
// 都挂接到新建元素下
pNewElement->LinkEndChild(pNameElementAdd);
pNewElement->LinkEndChild(pAddrElementAdd);
pNewElement->LinkEndChild(pEmailElementAdd);
// 把这个新建元素挂在根节点最后
pRootElement->LinkEndChild(pNewElement);
printf("add new element success\n");
/////////////////////////////////////////////////// 再次保存到文件 ////////////////////////////////////////////////
if (pReadDocument->SaveFile(filename.c_str()))
{
printf("save file success\n");
}
getchar();
return 0;
}
五.Linux下的编译
1. 从上面的地址下载得到tinyxml_2_6_2.zip文件,执行解压命令 unzip tinyxml_2_6_2.zip 得到文件夹tinyxml
2. 编译成静态库
2.1 进入目录tinyxml,用vim命令打开Makefile文件
2.2 将其中一行 OUTPUT := xmltest 修改为 OUTPUT := libtinyxml.a 表示编译出的静态库文件名字为 libtinyxml.a
2.3 将其中一行 SRCS :=tinyxml.cpp tinyxml-parser.cpp xmltest.cpp tinyxmlerror.cpp tinystr.cpp 中的xmltest.cpp删掉 因为不需要编译该测试文件
2.4 将其中一行 ${LD} -o $@ ${LDFLAGS} ${OBJS} ${LIBS} ${EXTRA_LIBS} 修改为 ${AR} $@ ${LDFLAGS} ${OBJS} ${LIBS} ${EXTRA_LIBS} 表示链接成静态库
2.5 将其中一行 xmltest.o:tinyxml.h tinystr.h 删除,因为不需要编译测试文件
2.6 保存Makefile文件
2.7 回退到上一层目录即目录tinyxml中,执行make命令,即可在该目录得到编译出来的静态库文件libtinyxml.a
3. 编译成动态库
3.1 进入目录tinyxml,用vim命令打开Makefile文件
3.2 在其中一行 DEBUG_CFLAGS := -Wall -Wno-format -g -DDEBUG -fPIC 的末尾添加上 -fPIC 表示编译与位置无关的代码,PIC的意思即 Position Independent Code,
3.3 在其中一行 RELEASE_CFLAGS := -Wall -Wno-unknown-pragmas -Wno-format -O3 的末尾添加上 -fPIC 原因同上
3.4 将其中一行 OUTPUT := xmltest 修改为 OUTPUT := libtinyxml.so 表示编译出的动态库文件名字为 libtinyxml.so
3.5 将其中一行 SRCS :=tinyxml.cpp tinyxml-parser.cpp xmltest.cpp tinyxmlerror.cpp tinystr.cpp 中的xmltest.cpp删掉 因为不需要编译该测试文件
3.6 将其中一行 ${LD} -o $@ ${LDFLAGS} ${OBJS} ${LIBS} ${EXTRA_LIBS} 修改为 ${LD} -shared -o $@ ${LDFLAGS} ${OBJS} ${LIBS} ${EXTRA_LIBS} 表示链接成动态库
3.7 将其中一行 xmltest.o:tinyxml.h tinystr.h 删除,因为不需要编译测试文件
3.8 保存Makefile文件
3.9 回退到上一层目录即目录tinyxml中,执行make命令,即可在该目录得到编译出来的动态库文件libtinyxml.so
六.Linux下的使用
1. 代码与步骤四中windows下的代码完全相同,需编写makefile,示例代码中有
2. linux下示例代码下载地址:(内有介绍文档,请按照文档步骤操作,保证可以运行成功)
使用静态库的示例代码:http://download.csdn.net/download/yzf279533105/9942600
使用动态库的示例代码:http://download.csdn.net/download/yzf279533105/9942605