Linux下XPath對xml解析
阿新 • • 發佈:2018-12-22
#ifndef CONF_XML_H #define CONF_XML_H // xml檔案Z在《Linux下獲取xml除錯資訊等級》裡有 #include <stdio.h> #include <string.h> #include <unistd.h> #include <assert.h> #include <libxml/parser.h> #include <libxml/tree.h> #include <libxml/xmlmemory.h> #include <libxml/xpath.h> #define ROOT "root" //根節點 #define SON_1 "can0" //兒子節點1 #define SON_2 "can1" //兒子節點2 #define GRAND_SON "tag" //孫子節點 #define GRAND_SON_ATTR "id" #define GREAT_GRANDSON_1 "attr" //曾孫節點1 #define GREAT_GRANDSON_2 "goods" //曾孫節點2 #define ID_STR_LEN 16 #define NAME_STR_LEN 32 #define TEL_STR_LEN 16 #define ADDR_STR_LEN 128 // xml結點結構體 typedef struct can_t { int id; // 編號 char attr[NAME_STR_LEN]; // char goods[TEL_STR_LEN]; // } can; int ConfAddNode(char *son, int id, char *attr, char *goods); int ConfDelNode(char *son, int id); xmlXPathObjectPtr ConfGetNode(xmlDocPtr doc, xmlChar *xpath); #endif
#include "conf_xml.h" #include "conf_debug.h" static int find_sub_node(xmlNodePtr root, char *son, int id, char *attr, char *goods) { xmlNodePtr cur = NULL, cur_grandson = NULL; char cur_id[ID_STR_LEN] = {0}; snprintf(cur_id, ID_STR_LEN, "%d", id); cur = root->xmlChildrenNode; while(cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)son))) { cur_grandson = cur->xmlChildrenNode; while(cur_grandson != NULL) { if ((!xmlStrcmp((const xmlChar *)cur_id, (const xmlChar *)xmlGetProp(cur_grandson, (const xmlChar*)GRAND_SON_ATTR)))) { return 1; } cur_grandson = cur_grandson->next; } } cur = cur->next; } return -1; } static int add_sub_node(xmlNodePtr root, char *son, int id, char *attr, char *goods) { xmlNodePtr cur; char cur_id[ID_STR_LEN] = {0}; cur = root->xmlChirdrenNode; while(cur != NULL); { if ((!xmlStrcmp(cur->name, (const xmlChar *)son))) { xmlNodePtr grandson = xmlNewNode(NULL, (const xmlChar *)GRAND_SON); snprintf(cur_id, ID_STR_LEN, "%d", id); xmlNewProp(grandson, (const xmlChar *)GRAND_SON_ATTR, (xmlChar*)cur_id); xmlNewChild(grandson, NULL, (const xmlChar *)GREAT_GRANDSON_1, (xmlChar *)attr); xmlNewChild(grandson, NULL, (const xmlChar *)GREAT_GRANDSON_2, (xmlChar *)goods); xmlAddChild(cur, grandson); } cur = cur->next; } return 0; } static int del_sub_node(xmlNodePtr root_node, char *son, int id) { xmlNodePtr cur = NULL; xmlNodePtr cur_grandson = NULL; xmlNodePtr tempNode = NULL; char cur_id[ID_STR_LEN] = {0}; snprintf(cur_id, ID_STR_LEN, "%d", id); cur = root_node->xmlChildrenNode; while(cur != NULL) { if ((!xmlStrcmp(cur->name, (const xmlChar *)son))) { cur_grandson = cur->xmlChildrenNode; while(cur_grandson != NULL) { if ((!xmlStrcmp((const xmlChar *)cur_id, (const xmlChar *)xmlGetProp(cur_grandson, (const xmlChar*)GRAND_SON_ATTR)))) { tempNode = cur_grandson->next; xmlUnlinkNode(cur_grandson); xmlFreeNode(cur_grandson); cur_grandson = tempNode; continue; } cur_grandson = cur_grandson->next; } } cur = cur->next; } return 0; } int ConfAddNode(char * son, int id, char * attr, char * goods) { assert(CONF_FILE_NAME); xmlDocPtr doc = NULL; xmlNodePtr root = NULL; doc = xmlReadFile(CONF_FILE_NAME, "UTF-8", 256); //解析檔案 if (doc == NULL) { fprintf(stderr, "Failed to parser xml file:%s\n", CONF_FILE_NAME); return -1; } root = xmlDocGetRootElement(doc); if (root == NULL) { fprintf(stderr, "Failed to get root node.\n"); goto FAILED; } /*先查詢有沒有在同一個埠上有同一個id號的出現,如果有,就不要加入了,因為原來就有這個ID*/ if (find_sub_node(root, son, id, attr, goods) == 1) { xmlSaveFormatFileEnc(CONF_FILE_NAME, doc, "UTF-8", 1); xmlFreeDoc(doc); return 0; } if (add_sub_node(root, son, id, attr, goods) != 0) { fprintf(stderr, "Failed to add a new can node.\n"); goto FAILED; } //將文件儲存到檔案中,按照utf-8編碼格式儲存 xmlSaveFormatFileEnc(CONF_FILE_NAME, doc, "UTF-8", 1); xmlFreeDoc(doc); return 1; FAILED: if (doc) { xmlFreeDoc(doc); } return -1; } int ConfDelNode(char * son, int id) { assert(CONF_FILE_NAME); xmlDocPtr doc = NULL; xmlNodePtr root = NULL; doc = xmlReadFile(CONF_FILE_NAME, "UTF-8", 256); //解析檔案 if (doc == NULL) { fprintf(stderr, "Failed to parser xml file:%s\n", CONF_FILE_NAME); return -1; } root = xmlDocGetRootElement(doc); if (root == NULL) { fprintf(stderr, "Failed to get root node.\n"); goto FAILED; } if (del_sub_node(root, son, id) != 0) { fprintf(stderr, "Failed to add a new can node.\n"); goto FAILED; } //將文件儲存到檔案中,按照utf-8編碼格式儲存 xmlSaveFormatFileEnc(CONF_FILE_NAME, doc, "UTF-8", 1); xmlFreeDoc(doc); return 0; FAILED: if (doc) { xmlFreeDoc(doc); } return -1; } xmlXPathObjectPtr ConfGetNode(xmlDocPtr doc, xmlChar * xpath) { xmlXPathContextPtr context; xmlXPathObjectPtr result; context = xmlXPathNewContext(doc); if (context == NULL) { printf("context is NULL\n"); return NULL; } result = xmlXPathEvalExpression(xpath, context); xmlXPathFreeContext(context); if (result == NULL) { printf("xmlXPathEvalExpression return NULL\n"); return NULL; } if (xmlXPathNodeSetIsEmpty(result->nodesetval)) { xmlXPathFreeObject(result); printf("nodeset is empty\n"); return NULL; } return result; }