1. 程式人生 > >C++通過TinyXML類庫讀寫XML檔案

C++通過TinyXML類庫讀寫XML檔案

TinyXML是一個開源的解析XML的解析庫,能夠用於C++,能夠在Windows或Linux中編譯。這個解析庫的模型通過解析XML檔案,然後在記憶體中生成DOM模型,從而讓我們很方便的遍歷這棵XML樹。

DOM模型即文件物件模型,是將整個文件分成多個元素(如書、章、節、段等),並利用樹型結構表示這些元素之間的順序關係以及巢狀包含關係。

然後解壓縮TinyXML後,將這六個檔案新增到你的c++工程中,分別是tinystr.h、tinystr.cpp、tinyxml.h、tinyxml.cpp、tinyxmlerror.cpp、tinyxmlparser.cpp。


如本示例中,只有 main.cpp 才是測試程式碼:


編寫程式碼時,只需要包含 tinyxml.h 標頭檔案即可,但是,編譯時卻需要把所有.cpp 檔案都加上

示例程式碼如下:

#include <stdio.h>
#include "tinyxml.h"
#include <iostream>
#include <cstring>
using namespace std;

/*
	TiXmlDocument:文件類,它代表了整個xml檔案
	TiXmlDeclaration:宣告類,它表示檔案的宣告部分
	TiXmlComment:註釋類,它表示檔案的註釋部分
	TiXmlElement:元素類,它是檔案的主要部分,並且支援巢狀結構,一般使用這種結構來分類的儲存資訊,它可以包含屬性類和文字類
	TiXmlAttribute/TiXmlAttributeSet:元素屬性,它一般巢狀在元素中,用於記錄此元素的一些屬性
	TiXmlText:文字物件,它巢狀在某個元素內部
*/
//建立xml檔案
int writeXmlFile()
{
	TiXmlDocument *writeDoc = new TiXmlDocument; //xml文件指標
	
	//文件格式宣告
	TiXmlDeclaration *decl = new TiXmlDeclaration("1.0", "UTF-8", "yes");
	writeDoc->LinkEndChild(decl); //寫入文件

	int n = 3;	//父節點個數

	TiXmlElement *RootElement = new TiXmlElement("Info");//根元素
	RootElement->SetAttribute("num", n); //屬性
	writeDoc->LinkEndChild(RootElement);
	
	for(int i=0; i<n; i++)//n個父節點
	{
		TiXmlElement *StuElement = new TiXmlElement("Stu");//Stu
		//設定屬性
		StuElement->SetAttribute("class","A");
		if(2 == i)
		{
				StuElement->SetAttribute("class","B");
		}
		
		StuElement->SetAttribute("id",i+1);
		StuElement->SetAttribute("flag", (i+1)*10);
		RootElement->LinkEndChild(StuElement);//父節點寫入文件
	
		//姓名
		TiXmlElement *nameElement = new TiXmlElement("name");
		StuElement->LinkEndChild(nameElement);

		TiXmlText *nameContent = new TiXmlText("mike");
		nameElement->LinkEndChild(nameContent);
		
		//分數
		TiXmlElement *scoreElement = new TiXmlElement("score");
		StuElement->LinkEndChild(scoreElement);

		TiXmlText *scoreContent = new TiXmlText("88");
		scoreElement->LinkEndChild(scoreContent);
		
		//城市
		TiXmlElement *cityElement = new TiXmlElement("city");
		StuElement->LinkEndChild(cityElement);

		TiXmlText *cityContent = new TiXmlText("Shenzhen");
		cityElement->LinkEndChild(cityContent);
		
	}
	
	writeDoc->SaveFile("stu_info.xml");
	delete writeDoc;
	
	return 1;
}

//解析xml檔案
int readXmlFile()
{
	TiXmlDocument mydoc("stu_info.xml");//xml文件物件
	bool loadOk=mydoc.LoadFile();//載入文件
	if(!loadOk)
	{
		cout<<"could not load the test file.Error:"<<mydoc.ErrorDesc()<<endl;
		exit(1);
	}

	TiXmlElement *RootElement=mydoc.RootElement();	//根元素, Info
	cout<< "[root name]" << RootElement->Value() <<"\n";
	
	TiXmlElement *pEle=RootElement;

	//遍歷該結點
	for(TiXmlElement *StuElement = pEle->FirstChildElement();//第一個子元素
		StuElement != NULL;
		StuElement = StuElement->NextSiblingElement())//下一個兄弟元素
	{
		// StuElement->Value() 節點名稱
		cout<< StuElement->Value() <<" ";
		TiXmlAttribute *pAttr=StuElement->FirstAttribute();//第一個屬性
		
		while( NULL != pAttr) //輸出所有屬性
		{
			cout<<pAttr->Name()<<":"<<pAttr->Value()<<" ";
			pAttr=pAttr->Next();
		}
		cout<<endl;
		
		//輸出子元素的值
		for(TiXmlElement *sonElement=StuElement->FirstChildElement();
		sonElement;
		sonElement=sonElement->NextSiblingElement())
		{
			cout<<sonElement->FirstChild()->Value()<<endl;
		}
	}
	
	return 1;
}

int main(int argc, char *argv[])
{
	
	writeXmlFile();
	printf("\nafter write\n");
	
	readXmlFile();

	return 0;
}

編譯執行結果如下:


生成的xml檔案內容如下:

<?xml version="1.0" encoding="UTF-8" standalone="yes" ?>
<Info num="3">
    <Stu class="A" id="1" flag="10">
        <name>mike</name>
        <score>88</score>
        <city>Shenzhen</city>
    </Stu>
    <Stu class="A" id="2" flag="20">
        <name>mike</name>
        <score>88</score>
        <city>Shenzhen</city>
    </Stu>
    <Stu class="B" id="3" flag="30">
        <name>mike</name>
        <score>88</score>
        <city>Shenzhen</city>
    </Stu>
</Info>