Linux C]利用libxml2解析xml檔案
阿新 • • 發佈:2019-02-11
為了解析xml,可以使用Linux下預設安裝的libxml2。
- /*
- a.c
- 功能:利用libxml2解析xml檔案
- */
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
- #include <unistd.h>
- #include <libgen.h>
- #include <libxml/xmlmemory.h>
- #include <libxml/parser.h>
- #include <libxml/xpath.h>
- int GetCurFilePath(
- {
- char chPath[BUFSIZ] = {0};
- int nRetVal = readlink("/proc/self/exe", chPath, sizeof(chPath)); // get full path of the current-executable file
- if(nRetVal < 0)
- {
- strcpy(lpOut, ".");
- return -1;
- }
- else
- {
- strcpy(lpOut, chPath);
- return 0;
- }
- }
- int GetCurDir(char *lpOut) // get directory-path of current executable-file
- {
- char chPath[BUFSIZ] = { 0 };
- if( GetCurFilePath(chPath) < 0 )
- return - 1;
- dirname(chPath); // dirname will change value of "chPath"(contain result)
- strcpy(lpOut, chPath); // copy result to out-param
- return 0;
- }
- xmlDocPtr getdoc(char *docname) // 根據檔名得到文件指標
- {
- xmlDocPtr doc;
- doc = xmlParseFile(docname);
- if(doc == NULL)
- {
- fprintf(stderr, "Document not parsed successfully.\n");
- return NULL;
- }
- return doc;
- }
- // 在文件doc中解析xpath表示式,返回結果集指標
- xmlXPathObjectPtr getnodeset(xmlDocPtr doc, xmlChar *xpath)
- {
- xmlXPathContextPtr context;
- xmlXPathObjectPtr result;
- context = xmlXPathNewContext(doc);
- if(context == NULL)
- {
- printf("Error in xmlXPathNewContent\n");
- return NULL;
- }
- result = xmlXPathEvalExpression(xpath, context); // 在context中解析表示式xpath
- xmlXPathFreeContext(context); // 釋放context
- if(result == NULL)
- {
- printf("Error in xmlXPathEvalExpression\n");
- return NULL;
- }
- if(xmlXPathNodeSetIsEmpty(result->nodesetval)) // 解析表示式的結果集為空
- {
- xmlXPathFreeObject(result);
- printf("No result\n");
- return NULL;
- }
- return result;
- }
- // 解析xmlPath路徑的結點
- void testReadXmlDoc(char *filepath, char *xmlPath)
- {
- xmlDocPtr doc = getdoc(filepath);
- if(NULL == doc)
- return ;
- xmlChar *xpath = (xmlChar*) xmlPath;
- xmlXPathObjectPtr result = getnodeset(doc, xpath); // 獲取結果集
- if(result)
- {
- xmlNodeSetPtr nodeset = result->nodesetval;
- xmlChar *name, *value;
- printf("nodeset->nodeNr = %d\n", nodeset->nodeNr); // 列印結果集中結點個數
- for(int i = 0; i < nodeset->nodeNr; i++)
- {
- xmlNodePtr cur = nodeset->nodeTab[i]; // products
- printf("cur->name = %s\n", cur->name);
- cur = cur->xmlChildrenNode;
- while(cur)
- {
- if(xmlStrcmp(cur->name, (const xmlChar*) "text")) // cur->name不為"text"
- {
- printf("cur->name = %s\t", cur->name);
- name = xmlGetProp(cur, (const xmlChar*) "name"); // 獲取屬性值
- value = xmlGetProp(cur, (const xmlChar*) "value");
- printf("name = %s, value = %s\n", name, value);
- xmlFree(name);
- xmlFree(value);
- }
- cur = cur->next;
- }
- printf("\n");
- }
- xmlXPathFreeObject(result);
- }
- xmlFreeDoc(doc);
- xmlCleanupParser();
- }
- int main(void)
- {
- char curDir[100] = {0};
- char docname[100] = {0};
- GetCurDir(curDir);
- strcpy(docname, curDir);
- strcat(docname, "/dprod.xml");
- testReadXmlDoc(docname, "/allproducts/products");
- return EXIT_SUCCESS;
- }
makefile檔案:
- CC=gcc
- CFLAGS=
- BIN=a
- INC=/usr/include/libxml2
- $(BIN): $(BIN).c
- $(CC) $(CFLAGS) -o $(BIN) $(BIN).c -I$(INC) -lxml2 -std=c99
- clean:
- rm -f *.o $(BIN)
xml檔案(dprod.xml)內容:
- <?xmlversion="1.0"?>
- <allproducts>
- <