1. 程式人生 > >Linux C]利用libxml2解析xml檔案

Linux C]利用libxml2解析xml檔案

為了解析xml,可以使用Linux下預設安裝的libxml2。

  1. /* 
  2.     a.c 
  3.     功能:利用libxml2解析xml檔案 
  4. */
  5. #include <stdio.h>
  6. #include <stdlib.h>
  7. #include <string.h>
  8. #include <unistd.h>
  9. #include <libgen.h>
  10. #include <libxml/xmlmemory.h>
  11. #include <libxml/parser.h>
  12. #include <libxml/xpath.h>
  13. int GetCurFilePath(
    char *lpOut)     // get full path of the executable file
  14. {  
  15.     char chPath[BUFSIZ] = {0};  
  16.     int nRetVal = readlink("/proc/self/exe", chPath, sizeof(chPath)); // get full path of the current-executable file
  17.     if(nRetVal < 0)  
  18.     {  
  19.         strcpy(lpOut, ".");  
  20.         return -1;  
  21.     }  
  22.     else
  23.     {  
  24.         strcpy(lpOut, chPath);  
  25.         return 0;  
  26.     }  
  27. }  
  28. int GetCurDir(char *lpOut)                                  // get directory-path of current executable-file
  29. {  
  30.     char    chPath[BUFSIZ] = { 0 };  
  31.     if( GetCurFilePath(chPath) < 0 )  
  32.         return - 1;  
  33.     dirname(chPath);                                        // dirname will change value of "chPath"(contain result)
  34.     strcpy(lpOut, chPath);                                  // copy result to out-param
  35.     return 0;  
  36. }  
  37. xmlDocPtr getdoc(char *docname)                         // 根據檔名得到文件指標
  38. {  
  39.     xmlDocPtr doc;  
  40.     doc = xmlParseFile(docname);  
  41.     if(doc == NULL)  
  42.     {  
  43.         fprintf(stderr, "Document not parsed successfully.\n");  
  44.         return NULL;  
  45.     }  
  46.     return doc;  
  47. }  
  48. // 在文件doc中解析xpath表示式,返回結果集指標
  49. xmlXPathObjectPtr getnodeset(xmlDocPtr doc, xmlChar *xpath)  
  50. {  
  51.     xmlXPathContextPtr context;  
  52.     xmlXPathObjectPtr result;  
  53.     context = xmlXPathNewContext(doc);  
  54.     if(context == NULL)  
  55.     {  
  56.         printf("Error in xmlXPathNewContent\n");  
  57.         return NULL;  
  58.     }  
  59.     result = xmlXPathEvalExpression(xpath, context);        // 在context中解析表示式xpath
  60.     xmlXPathFreeContext(context);                           // 釋放context
  61.     if(result == NULL)  
  62.     {  
  63.         printf("Error in xmlXPathEvalExpression\n");  
  64.         return NULL;  
  65.     }  
  66.     if(xmlXPathNodeSetIsEmpty(result->nodesetval))           // 解析表示式的結果集為空
  67.     {  
  68.         xmlXPathFreeObject(result);  
  69.         printf("No result\n");  
  70.         return NULL;  
  71.     }  
  72.     return result;  
  73. }  
  74. // 解析xmlPath路徑的結點
  75. void testReadXmlDoc(char *filepath, char *xmlPath)  
  76. {  
  77.     xmlDocPtr doc = getdoc(filepath);  
  78.     if(NULL == doc)  
  79.         return ;  
  80.     xmlChar *xpath = (xmlChar*) xmlPath;  
  81.     xmlXPathObjectPtr result = getnodeset(doc, xpath);          // 獲取結果集
  82.     if(result)  
  83.     {  
  84.         xmlNodeSetPtr nodeset = result->nodesetval;  
  85.         xmlChar *name, *value;  
  86.         printf("nodeset->nodeNr = %d\n", nodeset->nodeNr);        // 列印結果集中結點個數
  87.         for(int i = 0; i < nodeset->nodeNr; i++)  
  88.         {  
  89.             xmlNodePtr cur = nodeset->nodeTab[i];                // products
  90.             printf("cur->name = %s\n", cur->name);  
  91.             cur = cur->xmlChildrenNode;  
  92.             while(cur)  
  93.             {  
  94.                 if(xmlStrcmp(cur->name, (const xmlChar*) "text"))        // cur->name不為"text"
  95.                 {  
  96.                     printf("cur->name = %s\t", cur->name);  
  97.                     name = xmlGetProp(cur, (const xmlChar*) "name");    // 獲取屬性值
  98.                     value = xmlGetProp(cur, (const xmlChar*) "value");  
  99.                     printf("name = %s, value = %s\n", name, value);  
  100.                     xmlFree(name);  
  101.                     xmlFree(value);  
  102.                 }  
  103.                 cur = cur->next;  
  104.             }  
  105.             printf("\n");  
  106.         }  
  107.         xmlXPathFreeObject(result);  
  108.     }  
  109.     xmlFreeDoc(doc);  
  110.     xmlCleanupParser();  
  111. }  
  112. int main(void)  
  113. {  
  114.     char curDir[100] = {0};  
  115.     char docname[100] = {0};  
  116.     GetCurDir(curDir);  
  117.     strcpy(docname, curDir);  
  118.     strcat(docname, "/dprod.xml");  
  119.     testReadXmlDoc(docname, "/allproducts/products");  
  120.     return EXIT_SUCCESS;  
  121. }  

makefile檔案:
  1. CC=gcc  
  2. CFLAGS=  
  3. BIN=a  
  4. INC=/usr/include/libxml2  
  5. $(BIN): $(BIN).c  
  6.     $(CC) $(CFLAGS) -o $(BIN) $(BIN).c -I$(INC) -lxml2 -std=c99  
  7. clean:  
  8.     rm -f *.o $(BIN)  

xml檔案(dprod.xml)內容:
  1. <?xmlversion="1.0"?>
  2. <allproducts>
  3.   <