libxml教程(圖文詳解)
緣起
我的CloudBox需要一個跨平臺的方案來解決iOS上以及Android上的xml檔案讀取問題
因為游戲總是需要儲存一些設定值,或是過關存檔之類的
但又不能輕易的使用iOS內(nèi)建提供的或著是Java內(nèi)建提供的函數(shù),這樣整起來會很麻煩
而且思考到以后增加新的平臺,會有不小的困擾,最后決定就用libxml
libxml又是可以在windows環(huán)境下使用的,因此直接用visual studio也可以輕易嘗試學習API如何使用
環(huán)境簡介
操作系統(tǒng): Windows XP
IDE工具: Visual Studio 2008
工程類型: Visual C++ Win32 Console Application
下載鏈接
lib及.h檔下載鏈接
http://xmlsoft.org/sources/win32/
dll下載連結
http://www.dll-files.com/dllindex/dll-files.shtml?iconv
http://www.dll-files.com/dllindex/dll-files.shtml?zlib1
http://www.dll-files.com/dllindex/dll-files.shtml?libxml2
設定說明圖解
如圖所示,我在工程目錄中創(chuàng)建了兩個文件夾,在libxml中放了iconv跟libxml的.h文檔
另外也創(chuàng)建了lib檔,將所有的lib都放進去
然后再項目工程中設定libaray的文件路經(jīng)跟include的文件路徑
代碼說明
1. 讀取XML文檔
xmlDocPtr doc;
xmlNodePtr root;
// load an exist xml file.
doc = xmlParseFile("test.xml");
if (doc == NULL )
{
fprintf(stderr,"Document not parsed successfully. \n");
return 0;
}
// get root
root = xmlDocGetRootElement(doc);
if (root == NULL)
{
fprintf(stderr,"empty document\n");
xmlFreeDoc(doc);
return 0;
}
xmlDoc是一個struct,保存了一個xml的相關信息,例如文件名、文檔類型、子節(jié)點等等;xmlDocPtr等于xmlDoc*,它搞成這個樣子總讓人以為是智能指針,其實不是,要手動刪除的。
xmlParseFile函數(shù)以默認方式讀入一個UTF-8格式的文檔,并返回文檔指針。
xmlReadFile函數(shù)讀入一個帶有某種編碼的xml文檔,并返回文檔指針;細節(jié)見libxml2參考手冊。
xmlFreeDoc釋放文檔指針。
xmlDocGetRootElement函數(shù)得到根節(jié)點curNode
2.建立XML文檔
void CreateNewXMLDemo()
{
// create xml document
xmlDocPtr doc = xmlNewDoc(BAD_CAST"1.0");
xmlNodePtr root = xmlNewNode(NULL,BAD_CAST"root");
//set root
xmlDocSetRootElement(doc,root);
//add node
xmlNewTextChild(root, NULL, BAD_CAST "newNode1", BAD_CAST "newNode1 content");
xmlNewTextChild(root, NULL, BAD_CAST "newNode2", BAD_CAST "newNode2 content");
xmlNewTextChild(root, NULL, BAD_CAST "newNode3", BAD_CAST "newNode3 content");
//create node and add content
xmlNodePtr node = xmlNewNode(NULL,BAD_CAST"node2");
xmlNodePtr content = xmlNewText(BAD_CAST"NODE CONTENT");
xmlAddChild(root,node);
xmlAddChild(node,content);
// add attribute
xmlNewProp(node,BAD_CAST"attribute",BAD_CAST "yes");
//create son and grandson
node = xmlNewNode(NULL, BAD_CAST "son");
xmlAddChild(root,node);
xmlNewTextChild(node, NULL, BAD_CAST "grandson", BAD_CAST "grandson content");
xmlNodePtr grandson = xmlNewNode(NULL, BAD_CAST "grandson2");
xmlAddChild(node,grandson);
xmlAddChild(grandson, xmlNewText(BAD_CAST "This is a grandson2 node"));
//save xml
int nRel = xmlSaveFile("test3.xml",doc);
if (nRel != -1)
{
cout<<"create a xml:"<<nRel<<"bytes"<<endl;
}
//release
xmlFreeDoc(doc);
}

xmlChar是Libxml2中的字符類型,庫中所有字符、字符串都是基于這個數(shù)據(jù)類型。事實上它的定義是:xmlstring.h
xmlNewDoc函數(shù)創(chuàng)建一個新的文檔指針。
xmlNewNode可以創(chuàng)建一個新的節(jié)點
xmlDocSetRootElement可以將該節(jié)點設為根節(jié)點
xmlNewTextChild直接添加一個文本子節(jié)點
第二創(chuàng)建節(jié)點的方式是先創(chuàng)建新節(jié)點,然后用xmlAddChild將新節(jié)點加入上層節(jié)點。
xmlNewProp可以創(chuàng)建節(jié)點的屬性
xmlSaveFile可以將xml存檔
因為總是要在xmlChar*和char*之間進行類型轉(zhuǎn)換,所以定義了一個宏BAD_CAST,其定義如下:xmlstring.h
#define BAD_CAST (xmlChar *)
3.遍歷節(jié)點,修改與刪除
xmlNodePtr head = root->children->next;
while(head != NULL)
{
if(head->type == XML_ELEMENT_NODE)
{
cout<<"Name:"<<head->name<<endl;
cout<<"Content:"<<xmlNodeGetContent(head->children)<<endl;
// update test05
if ((!xmlStrcmp(head->name, (const xmlChar *)"test05")))
{
xmlNodeSetContent(head->children,(const xmlChar *)"orz05");
}
// remove node
if (!xmlStrcmp(head->name, BAD_CAST "test07"))
{
xmlNodePtr tempNode;
tempNode = head->next;
xmlUnlinkNode(head);
xmlFreeNode(head);
head = tempNode;
continue;
}
}
head = head->next;
}
在libxml中只需要針對XML_ELEMENT_NODE型態(tài)的節(jié)點進行搜索即可
xmlNodeGetContent可以取得節(jié)點的內(nèi)文
xmlNodeSetContent可以設定節(jié)點的內(nèi)文
可以透過xmlStrcmp來比較是否為要找的節(jié)點,xmlNodePtr的name屬性則是節(jié)點名稱,children則為內(nèi)文節(jié)點
xmlUnlinkNode可以刪除節(jié)點

點擊下載完整工程
相關文章
C語言光標信息CONSOLE_CURSOR_INFO類型詳解
本文詳細講解了C語言光標信息CONSOLE_CURSOR_INFO類型,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2021-12-12c++容器list、vector、map、set區(qū)別與用法詳解
這篇文章主要介紹了c++容器list、vector、map、set區(qū)別與用法詳解,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧2020-05-05