Ubuntu下C語言使用libxml2庫解析xml檔案
在C語言中解析XML檔案,需要先安裝libxml2的開發包,使用下面命令安裝
sudo apt-get install libxml++1.0-dev
sudo apt-get install libxml++1.0-doc
安裝完之後包含標頭檔案<libxml/parser.h>就可以在C裡面使用libxml2庫了。
int xmlKeepBlanksDefault (int val)//設定是否忽略空白節點,比如空格,在分析前必須呼叫,預設值是0,最好設定成1.否則會有慘痛的除錯經歷...
xmlDocPtr xmlReadFile (const char * filename)//分析一個xml檔案,並返回一個文件物件指標
//xml操作的基礎結構提及其指標型別
xmlDoc, xmlDocPtr 文件物件的結構體及其指標 xmlNode xmlNodePtr節點物件的結構體及其指標 xmlAttr xmlAttrPtr 節點屬性的結構體及其指標 xmlNs xmlNsPtr節點名稱空間的結構及其指標
//根節點相關函式
xmlNodePtr xmlDocGetRootElement (xmlDocPtr doc) //獲取文件根節點xmlNodePtr xmlDocSetRootElement (xmlDocPtr doc, xmlNodePtr root)//設定文件根節點
//建立子節點相關函式
xmlNodePtr xmlNewNode (xmlNsPtr ns, const xmlChar * name)//建立新節點 xmlNodePtr xmlNewChild (xmlNodePtr parent, xmlNsPtr ns,const xmlChar * name, const xmlChar * content) //建立新的子節點 xmlNodePtrxmlCopyNode
(const xmlNodePtr node, int extended)//複製當前節點
//新增子節點相關函式
xmlNodePtr xmlAddChild (xmlNodePtr parent, xmlNodePtrcur) //給指定節點新增子節點 xmlNodePtr xmlAddNextSibling (xmlNodePtr cur,xmlNodePtr elem) //新增後一個兄弟節點 xmlNodePtr xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) //新增前一個兄弟節點 xmlNodePtrxmlAddSibling (xmlNodePtr cur, xmlNodePtr elem)//新增兄弟節點
//屬性相關函式
xmlAttrPtr xmlNewProp (xmlNodePtr node, const xmlChar *name, const xmlChar * value) //建立新節點屬性 xmlChar * xmlGetProp(xmlNodePtr node, const xmlChar * name) //讀取節點屬性 xmlAttrPtrxmlSetProp
(xmlNodePtr node, const xmlChar * name, const xmlChar *value) //設定節點屬性
在文件解析完之後,需要呼叫xmlFreeDoc(xmlDocPtr)去釋放資源,
而通過xmlNodeGetContent(), xmlGetProp()所讀到的內容跟屬性在用完之後,需要呼叫xmlFree()去釋放所當用的資源。
libxml自定義了一個字元型別xmlChar,其本質是 unsigned char.
另外,libxml提供了一個巨集來將char*轉換成xmlChar*, 名字很有趣,叫 BAD_CAST 它的本質其實是unsigned char*.
為了方便對xmlChar型別字串的操作,libxml提供了自己的函式,它們的定義於標準c函式庫中的字串函式很像.
xmlChar* xmlStrcat (xmlChar *cur, const xmlChar * add)
const xmlChar *xmlStrchr(const xmlChar * str, xmlChar val)
int xmlStrcmp (const xmlChar * str1, const xmlChar * str2)
int xmlStrlen (const xmlChar * str)
xmlChar *xmlStrncat (xmlChar * cur, const xmlChar * add, intlen)
int xmlStrncmp (const xmlChar * str1, const xmlChar * str2, intlen)
const xmlChar *xmlStrstr (const xmlChar * str, const xmlChar *val)
相信這些函式大家都看得眼熟,這裡就不一一解釋了.
更多函式大家可以參考
http://xmlsoft.org/html/libxml-xmlstring.html
下面是一個讀出所有屬性跟內容的例子,
編譯命令(需要加入庫跟標頭檔案目錄):gcc test.c -o test -lxml2 -I/usr/include/libxml2
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <libxml/parser.h>
#include <libxml/xmlmemory.h>
/////////////////////////////////////////////////
int main(int argc, char **argv) {
xmlDocPtr doc;
xmlNodePtr curNode;
xmlChar *szKey, *szAttr;
xmlAttrPtr attrPtr;
int count = 0;
char szFile[512], szBuf[1024], key[256];
sprintf(szFile, "./test.xml");
doc = xmlReadFile(szFile, "UTF-8", XML_PARSE_RECOVER);
if (NULL == doc) {
fprintf(stderr, "open file failed!\n");
return -1;
}
curNode = xmlDocGetRootElement(doc);
if (NULL == curNode) {
fprintf(stderr, "Document not parsed sucessfully!\n");
xmlFreeDoc(doc);
return -1;
}
printf("root name: %s\n", curNode->name);
curNode = curNode->xmlChildrenNode;
while (curNode != NULL) {
count++;
szKey = xmlNodeGetContent(curNode); // get the content
printf("%s\t", curNode->name);
attrPtr = curNode->properties;
while (attrPtr != NULL) {
szAttr = xmlGetProp(curNode, BAD_CAST attrPtr->name);
printf("%s:%s\t", attrPtr->name, szAttr);
strcpy(key, szAttr);
xmlFree(szAttr);
attrPtr = attrPtr->next;
}
printf("%s\t", szKey);
xmlFree(szKey);
curNode = curNode->next;
}
xmlFreeDoc(doc);
return 0;
}