libxml2库解析xml文档举例

来源:互联网 发布:淘宝上几十块的人参 编辑:程序博客网 时间:2024/06/02 07:28

转自:http://blog.csdn.net/sky_qing/article/details/7165010

          http://blog.chinaunix.net/uid-20680966-id-3475787.html

======================================================================

其实在网上很容易能找到使用libxml2来对xml文档进行创建、解析、修改等。我着这里主要是就自己学习的libxml2修改xml文档的节点进行一个简单的总结,方便自己以后回顾。

 

下面给出我写的一个例子:

[cpp] view plaincopyprint?
  1. /**********************************************************************  
  2.  
  3.                 Copyright, 2011, **** Tech. Co., Ltd.  
  4.  
  5.                             All Rights Reserved  
  6.  
  7. -----------------------------------------------------------------------  
  8.  
  9. Project Code   : wlan  
  10.  
  11. File name      : modify_node.cpp  
  12.  
  13. Author         : Sky_qing  
  14.  
  15. Description    : 使用libxml2修改xml文档的节点 
  16.  
  17. Function List:  
  18.  
  19. -----------------------------------------------------------------------  
  20.  
  21. History:   
  22.  
  23. Date            Author                 Modification  
  24.  
  25. 2011-12-27     Sky_qing                created file 
  26.  
  27. **********************************************************************/  
  28. #include <stdio.h>  
  29. #include "libxml/parser.h"  
  30. #include "libxml/tree.h"  
  31.   
  32. int main(int argc, char* argv[])  
  33. {  
  34.     xmlDocPtr doc;              //定义解析文档指针  
  35.     xmlNodePtr curNode;         //定义节点指针(在各个节点之间移动)  
  36.     char* szDocName = argv[1];  //保存xml文档名,该文档名在运行程序到时候输入。  
  37.     //例如:编译格式为g++ modify_node.cpp -o modify_node -I /usr/local/include/libxml2/  -L /usr/local/lib -lxml2,生成可执行文件modify_node,运行时:./modify_node log4crc(此处log4crc为要修改的xml文档)  
  38.   
  39.     printf("........start........\n");  
  40.     doc = xmlReadFile(szDocName, "utf-8", XML_PARSE_RECOVER);   //解析文档  
  41.     if (NULL == doc)  
  42.     {  
  43.         fprintf(stderr, "Document not parsed successfully.\n");  
  44.           
  45.         return -1;  
  46.     }  
  47.   
  48.     curNode = xmlDocGetRootElement(doc);        //确定文档根元素  
  49.     if (NULL == curNode)  
  50.     {  
  51.         fprintf(stderr, "Empty Document.\n");  
  52.         xmlFreeDoc(doc);        //释放文件  
  53.   
  54.         return -1;  
  55.     }  
  56.   
  57.     if (xmlStrcmp(curNode->name, (const xmlChar*)"log4c"))   //确认根元素是否为“log4c”  
  58.     {  
  59.         fprintf(stderr, "Document of wrong type. root node != log4c");  
  60.         xmlFreeDoc(doc);  
  61.   
  62.         return -1;  
  63.     }  
  64.   
  65.     curNode = curNode->xmlChildrenNode;  
  66.     xmlNodePtr propNode = curNode;  
  67.     while (NULL != curNode)     //遍历所有节点  
  68.     {  
  69.         //获取名称为category的节点  
  70.         if (!xmlStrcmp(curNode->name, (const xmlChar*)"category"))  
  71.         {  
  72.             //查找带有属性name的节点  
  73.             if (xmlHasProp(curNode, BAD_CAST "name"))  
  74.             {  
  75.                 propNode = curNode;  
  76.             }  
  77.   
  78.             //查找属性name为WLAN_Console的节点  
  79.             xmlAttrPtr attrPtr = propNode->properties;  
  80.             while (NULL != attrPtr)     //遍历所有名称为category的节点  
  81.             {  
  82.                 if (!xmlStrcmp(attrPtr->name, (const xmlChar*)"name"))   //找到有name属性到节点  
  83.                 {  
  84.                     //查找属性为name的值的节点  
  85.                     xmlChar* szPropity = xmlGetProp(propNode, (const xmlChar*)"name");  
  86.                     if (!xmlStrcmp((const xmlChar*)szPropity, (const xmlChar*)"WLAN_Console"))  
  87.                     {  
  88.                         xmlAttrPtr setAttrPtr = propNode->properties;  
  89.                         while (NULL != setAttrPtr)  
  90.                         {  
  91.                             //设置属性priority的值  
  92.                             xmlSetProp(propNode, (const xmlChar*)"priority", (const xmlChar*)"debug");  
  93.               
  94.                             setAttrPtr = setAttrPtr->next;  
  95.                         }  
  96.                     }  
  97.                 }  
  98.                 attrPtr = attrPtr->next;  
  99.             }     
  100.         }  
  101.         curNode = curNode->next;  
  102.     }  
  103.       
  104.     //保存文档到原文档中  
  105.     xmlSaveFile("log4crc", doc);  
  106.   
  107.     printf("...........OK............\n");  
  108.   
  109.     return 0;  
  110. }  

  1. xml version="1.0" encoding="UTF-8"?>  
  2. <radios>  
  3.     <radio>  
  4.         <name>Bayernname>  
  5.         <url>http://mp3.webradio.antenne.de:80url>  
  6.         <classification>  
  7.             <area>usaarea>  
  8.             <style>musicstyle>  
  9.         classification>  
  10.     radio>  
  11.     <radio>  
  12.         <name>DEU-Antenne Bayernname>  
  13.         <url>http://mp3.webradio.antenne.de:80url>  
  14.     radio>  
  15.     <radio>  
  16.         <name>DEU-Antenne Bayernname>  
  17.         <url>http://testurl>  
  18.     radio>  
  19. radios>  
上代码
[cpp] view plaincopy
  1. static xmlXPathObjectPtr getNodeset(xmlDocPtr doc, const xmlChar *xpath)  
  2. {  
  3.     xmlXPathContextPtr context;  
  4.     xmlXPathObjectPtr result;  
  5.     context = xmlXPathNewContext(doc);  
  6.   
  7.     if (context == NULL) {  
  8.         printf("context is NULL\n");  
  9.         return NULL;  
  10.     }  
  11.   
  12.     result = xmlXPathEvalExpression(xpath, context);  
  13.     xmlXPathFreeContext(context);  
  14.     if (result == NULL) {  
  15.         printf("xmlXPathEvalExpression return NULL\n");  
  16.         return NULL;  
  17.     }  
  18.   
  19.     if (xmlXPathNodeSetIsEmpty(result->nodesetval)) {  
  20.         xmlXPathFreeObject(result);  
  21.         printf("nodeset is empty\n");  
  22.         return NULL;  
  23.     }  
  24.   
  25.     return result;  
  26. }  

playlistDoc 为 xmlDocPtr类型.

[cpp] view plaincopy
  1. xmlChar *xpath = BAD_CAST("/radios/radio[name='DEU-Antenne Bayern']");   //关键在这行  
  2. xmlXPathObjectPtr app_result = getNodeset(playlistDoc, xpath);  
  3. if (app_result == NULL)  
  4. {  
  5.     printf("app_result is NULL\n");  
  6.     return;  
  7. }  
  8.   
  9. int i = 0;  
  10. xmlChar *value;  
  11. if(app_result)  
  12. {  
  13.     xmlNodeSetPtr nodeset = app_result->nodesetval;  
  14.     xmlNodePtr cur;  
  15.   
  16.     for (i=0; i < nodeset->nodeNr; i++)  
  17.     {  
  18.         cur = nodeset->nodeTab[i];     
  19.         cur = cur->xmlChildrenNode;  
  20.   
  21.         while (cur != NULL)  
  22.         {  
  23.             if (!xmlStrcmp(cur->name, (const xmlChar *)"name"))  
  24.                 printf("%s\n", ((char*)XML_GET_CONTENT(cur->xmlChildrenNode)));  
  25.             else if (!xmlStrcmp(cur->name, (const xmlChar *)"url"))  
  26.                 printf("%s\n", ((char*)XML_GET_CONTENT(cur->xmlChildrenNode)));  
  27.   
  28.             cur = cur->next;  
  29.         }  
  30.     }  
  31.   
  32.     xmlXPathFreeObject(app_result);  
  33. }  

输出:

DEU-Antenne Bayern
http://mp3.webradio.antenne.de:80
DEU-Antenne Bayern
http://test


[cpp] view plaincopy
  1. xmlChar *xpath = BAD_CAST("/radios/radio[name='DEU-Antenne Bayern']");   
改成
[cpp] view plaincopy
  1. xmlChar *xpath = BAD_CAST("/radios/radio[name='DEU-Antenne Bayern' and url='http://mp3.webradio.antenne.de:80']");  
  2. EU-Antenne Bayern  

输出:

http://mp3.webradio.antenne.de:80


0 0
原创粉丝点击