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.否则会有惨痛的调试经历...

<wbr></wbr>

xmlDocPtr xmlReadFile (const char * filename)//分析一个xml文件,并返回一个文档对象指针

//xml操作的基础结构提及其指针类型

<wbr></wbr>

xmlDoc, xmlDocPtr 文档对象的结构体及其指针 xmlNode xmlNodePtr节点对象的结构体及其指针 xmlAttr xmlAttrPtr 节点属性的结构体及其指针 xmlNs xmlNsPtr节点命名空间的结构及其指针

<wbr></wbr>

<wbr></wbr>

//根节点相关函数

xmlNodePtr xmlDocGetRootElement (xmlDocPtr doc) //获取文档根节点xmlNodePtr xmlDocSetRootElement (xmlDocPtr doc, xmlNodePtr root)//设置文档根节点

<wbr></wbr>

<wbr></wbr>

//创建子节点相关函数

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)//复制当前节点

<wbr></wbr>

<wbr></wbr>

//添加子节点相关函数<wbr></wbr>

xmlNodePtr xmlAddChild (xmlNodePtr parent, xmlNodePtrcur) //给指定节点添加子节点 xmlNodePtr xmlAddNextSibling (xmlNodePtr cur,xmlNodePtr elem) //添加后一个兄弟节点 xmlNodePtr xmlAddPrevSibling(xmlNodePtr cur, xmlNodePtr elem) //添加前一个兄弟节点 xmlNodePtrxmlAddSibling (xmlNodePtr cur, xmlNodePtr elem)//添加兄弟节点

<wbr></wbr>

//属性相关函数

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


  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值