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;
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章