libxml2 的一些用法

时间:2021-02-08 20:16:07

0. libxml2 是个跨平台的C库,用于操作xml文件。API Reference

1. 结构体:

 1     /*文档结构体*/
 2     typedef xmlDoc *xmlDocPtr;
 3 
 4     /*节点结构体*/
 5     typedef struct _xmlNode xmlNode;
 6     typedef xmlNode *xmlNodePtr;
 7     struct _xmlNode {
 8         void           *_private;    /* application data */
 9         xmlElementType   type;    /* type number, must be second ! */
10         const xmlChar   *name;      /* the name of the node, or the entity */
11         struct _xmlNode *children;    /* parent->childs link */
12         struct _xmlNode *last;    /* last child link */
13         struct _xmlNode *parent;    /* child->parent link */
14         struct _xmlNode *next;    /* next sibling link  */
15         struct _xmlNode *prev;    /* previous sibling link  */
16         struct _xmlDoc  *doc;    /* the containing document */
17 
18         /* End of common part */
19         xmlNs           *ns;        /* pointer to the associated namespace */
20         xmlChar         *content;   /* the content */
21         struct _xmlAttr *properties;/* properties list */
22         xmlNs           *nsDef;     /* namespace definitions on this node */
23         void            *psvi;    /* for type/PSVI informations */
24         unsigned short   line;    /* line number */
25         unsigned short   extra;    /* extra data for XPath/XSLT */
26     };
27 
28     其他API:
29     xmlChildElementCount/*获取节点的子节点个数*/
30     /*转码API*/
31     #include "iconv.h"
32     int iConvert(const char *from_code, const char *to_code, const char *from_str, size_t f_len, char * to_str, size_t t_len )
33     {
34         iconv_t cd;
35         size_t ret;
36         cd = iconv_open( to_code, from_code);
37         if ( cd == (iconv_t)-1 ) {
38             perror("iconv open error\n");
39             return -1;
40         }
41         ret = iconv( cd, &from_str, &f_len, &to_str, &t_len );
42         if ( ret == (size_t)-1 )
43         {
44             perror("iconv error\n");
45             iconv_close(cd);
46             return -1;
47         }
48         iconv_close(cd);
49         return ret;
50     }

2.读取:

1     xmlDocPtr doc = xmlReadFile("file.xml", NULL, 0)
2     /*or*/
3     xmlDocPtr doc = xmlParseFile("file.xml");

3. 遍历:

 1     /*各层兄弟节点的保存顺序与文件的排列顺序不能确保一致*/
 2     /*libxml的内部字节编码是utf-8,所以如果节点内容是gbk中文,获取时需要用iconv进行转码*/
 3     /* root */
 4     xmlNodePtr cur = xmlDocGetRootElement(doc);
 5     /* children & sibling */
 6     cur = cur->children; /*or xmlFirstElementChild 可以跳过text节点*/
 7     while( cur ) {
 8         if ( xmlStrcmp(cur->name, BAD_CAST("nodename")) == 0 ) {
 9             /*read property*/
10             char* p_value = xmlGetProp(cur, BAD_CAST("propername"));
11             /*read content*/
12             char* n_value = xmlNodeGetContent(cur);
13             /*convert encode if needed*/
14             ret = iConvert( "utf-8", "GBK", n_value, xmlStrlen(n_value), outbuffer, outlen);
15             ...
16             /*free is needed*/
17             xmlFree(p_value);
18             xmlFree(n_value);
19         }
20         cur = cur->next; /*or xmlNextElementSibling*/
21     }
22     xmlFree(doc);

4. 查找:

  1. 如果只查找结果项只有一个,可以通过自行遍历进行查找节点;
  2. 有多个节点匹配,可以通过 xmlXPathEval* 查找节点集;

5. 修改与保存:以后用到再补充……