之前写了个小程序,想要使用xml进行数据的收发,所以需要学习下XML的处理。
了解到对xml的处理有两种常见的库,libxml和tinyxml。
考虑到tinyxml是C++的api,而我使用纯C写的程序,所以放弃tinyxml,使用libxml来对XML进行操作。
主要变量
xmlChar
xmlstring.h : typedef unsigned char xmlChar;
该变量一般使用在xmlNodePtr->name等需要使用字符串的地方。
xmlDocPtr
该变量是一个结构体,可以简单理解为指向xml文档的文件描述符。
xmlNodePtr
该变量是一个结构体。
- typedef struct _xmlNode xmlNode;
- typedef xmlNode *xmlNodePtr;
- struct _xmlNode {
- void *_private; // 应用数据
- xmlElementType type; // 元素类型
- const xmlChar *name; // 节点名称
- struct _xmlNode *children; // 指向自己的第一个孩子节点
- struct _xmlNode *last; // 指向自己的最后一个孩子节点
- struct _xmlNode *parent; // 指向自己的父节点
- struct _xmlNode *next; // 指向下一个兄弟节点
- struct _xmlNode *prev; // 指向前一个兄弟节点
- struct _xmlDoc *doc; // 包含文件
- /* 以上是通用模块 */
- xmlNs *ns; // 指向关联的命名空间
- xmlChar *content; // 内容
- struct _xmlAttr *properties;// 属性列表
- xmlNs *nsDef; // 定义在该节点上的命名空间
- void *psvi; // /PSVI 信息
- unsigned short line; // 行数
- unsigned short extra; // XPath/XSLT的额外信息
主要函数
xmlReadFile( )
【打开目标XML文档,并返回指向该文件的描述符】
xmlReadFile( char * xmlFileName,"UTF-8",XML_PARSER_RECOVER);
返回值为xmlDocPtr类型,为目标xml文档的文件描述符。
xmlParseMemory( )
【获取内存中的xml信息,并返回指向该信息的描述符】
xmlParseMemory( const char * buffer,int size);
返回值为xmlDocOtr类型,为目标xml信息的描述符。
xmlDocGetRootElement( )
【返回XML文档的root节点】
xmlDocGetRootElement( xmlDocPtr )
参数是xmlReadFile函数获取的xml文件描述符,将root节点返回给一个xmlNodePtr类型。
xmlStrcmp( )
【XML字符串比较函数】
xmlStrcmp(xmlNodePtr, BAD_CAST "nodeName" )
对一个xml节点的名字和字符串进行比较,如果相同,返回true;不同,返回false。
------------------------------------------------------------------------
【注意】:BAD_CAST用来做显示的转换。
libxml的api使用 const unsigned char* 。
而string literal 只能隐式转换到 const char*。
所以libxml提供一个BAD_CAST用来作显示转换。
——《libxml2中的"BAD_CAST"》 by dotnetsong
xmlNodeGetContent( )
xmlNodeGetContent( xmlNodePtr )
参数是xml的节点,返回值是该节点包含的信息。
------------------------------------------------------------------------
【注意】还有另外一个很相似的获取内容函数:xmlNodeListGetString( ),两者的区别如下:
xmlNodeListGetString只取当前节点链表类型TEXT或者ENTITY_REF节点内容;
xmlNodeGetContent获取子孙节点类型TEXT或者ENTITY_REF节点内容拼接字符串。
其他函数
xmlKeepBlankDefault(0) :解析xml时忽视空白行,不显示text空节点;
xmlFreeDoc( xmlDocPtr ):释放指向XML文档的描述符;
xmlCleanupParser( ):释放占用的系统资源;
常用宏命令
BAD_CAST
#define BAD_CAST (xmlChar *)
这个宏的作用是将字符串强制转换成xmlChar * 类型,也就是前面说到的unsigned char * 类型。
举个栗子
输出结果:
- /*
- * Author: xusongqi@live.com
- *
- * Created Time: 2014年05月31日 星期六 11时21分55秒
- *
- * FileName: xml_analyse.c
- *
- * Description:
- *
- */
- #include <libgen.h>
- #include <libxml/parser.h>
- #include <libxml/tree.h>
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- int main(void)
- {
- char * xml_filename;
- char n = 0;
- xmlDocPtr pdoc = NULL;
- xmlNodePtr proot = NULL,curNode = NULL;
- xml_filename = "b.xml";
- xmlKeepBlanksDefault(0);
- pdoc = xmlReadFile(xml_filename,"UTF_8",XML_PARSE_RECOVER);
- if(pdoc == NULL)
- {
- printf("open file error\n");
- exit(1);
- }
- proot = xmlDocGetRootElement(pdoc);
- if(proot == NULL)
- {
- printf("get element error\n");
- exit(1);
- }
- if(xmlStrcmp(proot->name,BAD_CAST "html") != 0)
- {
- printf("file info error\n");
- exit(1);
- }printf("root node : %s\n",proot->name);
- curNode = proot->xmlChildrenNode;
- while(curNode != NULL)
- {
- //if(xmlStrcmp(curNode->name,BAD_CAST "text") != 0)
- if(curNode->name)
- {
- printf("child node%d: %s : ",n++,curNode->name);
- printf("%s\n",xmlNodeGetContent(curNode));
- }
- curNode = curNode->next;
- }
- xmlFreeDoc(pdoc);
- xmlCleanupParser();
- return 0;
- }
child node0: head : Welcome to Nginx!
child node1: body : Welcome to Nginx!xusongqi