下面介紹的是libxml主要的數據類型,對於應用編程來說,這些數據類型是需要了解和掌握的。
1.內部字符類型xmlChar
xmlChar是libxml2中的字符類型,庫中所有字符、字符串都是基於這個數據類型。它的定義在xmlstring.h中,定義說明如下:
typedef unsigned char xmlChar;
使用unsigned char作爲內部字符格式是考慮到它能很好適應UTF-8編碼,而UTF-8編碼正是libxml2的內部編碼,其他格式的編碼要轉換爲這個編碼才能在libxml2中使用。
xmlChar *常在libxml2中作爲字符串指針類型,很多函數會返回一個動態分配內存的xmlChar *變量,使用這樣的函數時需要手工刪除內存。
2.xmlChar相關函數
如同標準C中的char類型一樣,xmlChar也有動態內存分配、字符串操作等相關函數。例如xmlMalloc是動態分配內存的函數,xmlFree是配套的釋放內存函數,xmlStrcmp是字符串比較函數等。基本上xmlChar字符串相關函數都在xmlstring.h中定義,而動態內存分配函數在xmlmemory.h頭文件中定義。
3.xmlChar*與其他類型之間的轉換
在實際編程中,總是需要在xmlChar *和char *之間進行強制類型轉換,所以定義了一個宏BAD_CAST,其定義如下:
#define BAD_CAST (xmlChar *)
4.XML中常用到的重定義
在XML程序中,會經常看到xmlChildrenNode這個名稱,其實這個名稱是定義在tree.h中的重定義。其重定義如下:
#define xmlChildrenNode children
5.文檔類型xmlDoc、指針xmlDocPtr
xmlDoc是一個struct,保存了一個xml的相關信息,例如文件名、文檔類型、子節點等,xmlDocPtr等於xmlDoc * 。與文檔指針相關函數有如下幾個。
xmlNewDoc函數創建一個新的文檔指針。
xmlParseFile函數以默認方式讀入一個UTF-8格式的文檔,並返回文檔指針。
xmlReadFile函數讀入一個帶有某種編碼的xml文檔,並返回文檔指針。
xmlFreeDoc釋放文檔指針。
特別注意,當調用xmlFreeDoc時,該文檔所有包含的節點內存都會被釋放,所以一般來說不需要手工調用xmlFreeNode或者xmlFreeNodeList來釋放動態分配的節點內存,除非把該節點從文檔中移除了。一般來說,一個文檔中所有節點都應該動態分配,然後加入文檔,最後調用xmlFreeDoc一次釋放所有節點申請的動態內存,這也是爲什麼我們在程序中很少看見xmlNodeFree的原因。
xmlSaveFile將文檔以默認方式存入一個文件。
xmlSaveFormatFileEnc可將文檔以某種編碼格式存入一個文件中。
6.節點類型xmlNode、指針xmlNodePtr
節點是XML中最重要的元素,xmlNode代表XML文檔中的一個節點,實現爲一個struct,此結構內容很豐富也很重要,其定義在tree.h中,具體說明如下:
typedef struct _xmlNode xmlNode;
typedef xmlNode *xmlNodePtr;
struct _xmlNode {
void *_private; /* application data */
xmlElementType type; /* type number, must be second ! */
const xmlChar *name; /* the name of the node, or the entity */
struct _xmlNode *children; /* parent->childs link */
struct _xmlNode *last; /* last child link */
struct _xmlNode *parent; /* child->parent link */
struct _xmlNode *next; /* next sibling link */
struct _xmlNode *prev; /* previous sibling link */
struct _xmlDoc *doc; /* the containing document */
/* End of common part */
xmlNs *ns; /* pointer to the associated namespace */
xmlChar *content; /* the content */
struct _xmlAttr *properties;/* properties list */
xmlNs *nsDef; /* namespace definitions on this node */
void *psvi; /* for type/PSVI informations */
unsigned short line; /* line number */
unsigned short extra; /* extra data for XPath/XSLT */
};
可以看到,節點之間是以鏈表和樹兩種方式同時組織起來的,next和prev指針可以組成鏈表,而parent和children可以組織爲樹。同時此結構還有以下重要成員:
content:節點中的文字內容。
doc:節點所屬文檔。
name:節點名字。
ns:節點的名字空間。
properties:節點屬性列表。
XML文檔的操作其根本原理就是在節點之間移動、查詢節點的各項信息,並進行增加、刪除、修改等操作。
xmlDocSetRootElement函數可以將一個節點設置爲某個文檔的根節點,這是將文檔與節點連接起來的重要手段,當有了根結點以後,所有子節點就可以依次連接上根節點,從而組織成爲一個XML樹。
7.XML屬性
XML屬性也是編程中經常用到的結構,其定義如下:
<span style="font-weight: normal;">struct _xmlAttr {
void * _private; /* application data */
xmlElementType type; /* XML_ATTRIBUTE_NODE, must be second ! */
const xmlChar * name ; /*the name of the property */
struct _xmlNode * children; /*the value of the property */
struct _xmlNode * last; /*NULL */
struct _xmlNode * parent; /*child->parent link */
struct _xmlAttr * next; /*next sibling link */
struct _xmlAttr * prev; /*previous sibling link */
struct _xmlDoc * doc; /*the containing document */
xmlNs * ns; /*pointer to the associated namespace */
xmlAttributeType atype; /*the attribute type if validating */
void * psvi; /*for type/PSVI informations */
}</span>
8.節點集合類型xmlNodeSet、指針類型xmlNodeSetPtr
節點集合代表一個由節點組成的變量,節點集合只作爲XPath的查詢結果而出現,因此被定義在xpath.h中,其定義如下:
/* A node-set (an unordered collection of nodes without duplicates). */
typedef struct _xmlNodeSet xmlNodeSet;
typedef xmlNodeSet *xmlNodeSetPtr;
struct _xmlNodeSet {
int nodeNr; /* number of nodes in the set */
int nodeMax; /* size of the array as allocated */
xmlNodePtr *nodeTab; /* array of nodes in no particular order */
/* @@ with_ns to check wether namespace nodes should be looked at @@ */
};
可以看出,節點集合有三個成員,分別是節點集合的節點數、最大可容納的節點數,以及節點數組頭指針。對節點集合中各個節點的訪問方法如下:
xmlNodeSetPtr nodeset = XPath
for (int i = 0; i < nodeset->nodeNr; i++)
{
nodeset->nodeTab[i];
}