折腾了好些天的基本的还是懂.今天分配了一个小任务.解析一个C语言头文件如下:struct items_service{ char name[128]; char mif[128]; char expip[128]; unsigned int update_period; unsigned int sample_number; struct media_servers_{ struct in_addr *ip; unsigned int nip; }media_servers; struct items_service *next;};struct items{ char config[FILENAME_MAX]; struct items_service *head;};OK. 完成这项任务我分为了两个部分.一个部分是负责用XPATH来获取节点集并返回给调用着. 第二部分是使用这个返回的节点集来初始化字段.这样划分我觉得比较好....第一部分代码如下:parse_conf.h 声明和对外接口.#ifndef _PARSE_CONF_H_#define _PARSE_CONF_H_#include #include #include #include void void #endif实现部分: parse_conf.c#include #include #include "parse_conf.h"static static static void { doc = NULL; XPathCtx = NULL; doc = if (NULL == doc) { fprintf(stderr, "Failed to parse %s\n", uri); exit(-1); } XPathCtx = if (NULL == XPathCtx) { fprintf(stderr, "Failed to create XPath context!\n"); exit(-1); }}{ XPathObj = NULL; if (NULL == XPathExpr) return NULL; XPathObj = if (NULL == XPathObj) { fprintf(stderr, "cannot Evaluate the XPath Expression:%s\n", XPathExpr); return NULL; } nodeSet = XPathObj->nodesetval; /* *just return it.don't bother to check it, *let the caller handle it. */ return nodeSet;}void { if (NULL != XPathObj) if (NULL != XPathCtx) if (NULL != doc) }第二部分的代码如下: build_from_conf.c#include #include #include #include #include #include #include "parse_conf.h"#include "def.h"#define USE_TESTconst char *const char *SERVICE_XPATH = "/conf/service";const char *NAME_XPATH = "/conf/service/name";const char *MONITOR_INTERFACE_XPATH = "/conf/service/monitor_interface";const char *EXPROBE_IP_XPATH = "/conf/service/exprobe_ip";const char *UPDATE_PERIOD_XPATH = "/conf/service/update_period";const char *SAMPLE_NUMBER_XPATH = "/conf/service/sample_number";const char *MEDIA_SERVERS_XPATH = "/conf/service/media_servers";const char *IP_XPATH = "/conf/service/media_servers/ip";/* * allocate memory for all the items appeared in the */static struct items_service *build_struct_init(void){ struct items_service *item = NULL; struct items_service *head = NULL; struct items_service *next = NULL; int i; nodeSet = if (NULL == nodeSet) { fprintf(stderr, "Oops, %s have no nodeSet!\n", SERVICE_XPATH); return NULL; } for(i = 0; i nodeNr; i++) { item = (struct items_service *)malloc(sizeof(struct items_service)); if (NULL == item) { while (NULL != head) { next = head->next; free(head); head = next; } return NULL; } memset(item, 0, sizeof(struct items_service)); item->next = NULL; if (NULL == head) { head = item; next = head; } else { next->next = item; } } return head;}static void build_name(struct items_service *item){ struct items_service *tmp; const char *string; int i; nodeSet = if (NULL == nodeSet) return; tmp = item; for (i = 0; i nodeNr; i++) { if (nodeSet->nodeTab[i]->type != continue; string = nodeTab[i]); strncpy(tmp->name, string, 127); tmp->name[127] = '\0'; tmp = tmp->next; if (NULL == tmp) break; }}static void build_mif(struct items_service *item){ struct items_service *tmp; const char *string; int i; nodeSet = if (NULL == nodeSet) return; tmp = item; for (i = 0; i nodeNr; i++) { if(nodeSet->nodeTab[i]->type != continue; string = nodeTab[i]); strncpy(tmp->mif, string, 127); tmp->mif[127] = '\0'; tmp = tmp->next; if (NULL == tmp) break; }}static void build_expip(struct items_service *item){ struct items_service *tmp; const char *string; int i; nodeSet = if (NULL == nodeSet) return; tmp = item; for (i = 0; i nodeNr; i++) { if(nodeSet->nodeTab[i]->type != continue; string = nodeTab[i]); strncpy(tmp->expip, string, 127); tmp->expip[127] = '\0'; tmp = tmp->next; if (NULL == tmp) break; }}static void build_update_period(struct items_service *item){ struct items_service *tmp; const char *string; int i; nodeSet = if (NULL == nodeSet) return; tmp = item; for (i = 0; i nodeNr; i++) { if(nodeSet->nodeTab[i]->type != continue; string = nodeTab[i]); //printf("update: %s\n", string); tmp->update_period = atoi(string); tmp = tmp->next; if (NULL == tmp) break; }}static void build_sample_number(struct items_service *item){ struct items_service *tmp; const char *string; int i; nodeSet = if (NULL == nodeSet) return; tmp = item; for (i = 0; i nodeNr; i++) { if(nodeSet->nodeTab[i]->type != continue; string = nodeTab[i]); tmp->sample_number = atoi(string); tmp = tmp->next; if (NULL == tmp) break; }}static void build_media_servers(struct items_service *item){ struct items_service *tmp; const char *ip; int i, j, res; nodeSet = if (NULL == nodeSet) return; tmp = item; for (i = 0; i nodeNr; i++) { parent = nodeSet->nodeTab[i]; if (NULL == parent) break;; child = parent->children; if (NULL == child) break; /* count how may ips thers are */ tmp->media_servers.nip = 0; while (NULL != child) { if (child->type == tmp->media_servers.nip++; child = child->next; } tmp->media_servers.ip = (struct in_addr *) malloc(sizeof(struct in_addr) * tmp->media_servers.nip); if (NULL == tmp->media_servers.ip) { fprintf(stderr, "Failed to alloc memory for ip.OOM!\n"); break; } /* fill the string format ip into in_addr */ child = parent->children; j = 0; while(NULL != child) { if (child->type == ip = res = inet_pton(AF_INET, ip, &tmp->media_servers.ip[j]); if (res fprintf(stderr,"transforming string ip to in_addr goes wrong...!\n"); j--; tmp->media_servers.nip--; } j++; } child = child->next; } tmp = tmp->next; if (NULL == tmp) break; } } #ifdef USE_TESTstatic void dump_struct(struct items_service *item){ int i = 1; int j; char ip[INET6_ADDRSTRLEN + 1]; printf("dump struct:\n"); while (NULL != item) { printf("Item %d\n", i); printf("name:%s mif:%s expip:%s update_period:%d\nsample_number:%d", item->name, item->mif, item->expip, item->update_period, item->sample_number); for (j = 0; j media_servers.nip; j++) { printf("ip-%d:%s ", j + 1, inet_ntop(AF_INET, &item->media_servers.ip[j], ip, INET6_ADDRSTRLEN)); } printf("\n"); item= item->next; i++; }}/*static void dump_file(struct items_service *item){ char ip[1024]; int i, j; FILE *fp = fopen("abcdefg.txt", "w"); while (NULL != item) { fprintf(fp, "Item %d\n", i); fprintf(fp,"name:%s mif:%s expip:%s update_period:%d\nsample_number:%d", item->name, item->mif, item->expip, item->update_period, item->sample_number); for (j = 0; j media_servers.nip; j++) { fprintf(fp,"ip-%d:%s ", j + 1, inet_ntop(AF_INET, &item->media_servers.ip[j], ip, INET6_ADDRSTRLEN)); } fprintf(fp, "\n"); item= item->next; i++; }}*/#endif/* build around head. 0 means success, otherwise something goes wrong */int build_struct(struct items *head){ struct items_service *item = head->head; item = build_struct_init(); if (NULL == item) { fprintf(stderr, "Ooops...build_struct_init returns NULL,may OOM!\n"); return -1; } build_name(item); build_mif(item); build_expip(item); build_update_period(item); build_sample_number(item); build_media_servers(item); head->head = item;#ifdef USE_TEST dump_struct(item);#endif return 0;}#ifdef USE_TESTint main(void){ struct items head; struct items_service *items; int res; memset(&head, 0, sizeof(head)); strncpy(head.config, res = build_struct(&head); if (res == -1) { fprintf(stderr, "Build_struct failed!\n"); return -1; } return 0;}#endif以上就是全部代码...运行结果如下,当然只是打印到终端.dump struct:Item 1name:service_1 mif:eth0 expip:192.168.8.201 update_period:5sample_number:10ip-1:10.0.0.1 ip-2:10.0.0.2 ip-3:10.0.0.3 Item 2name:service_2 mif:eth1 expip:192.168.8.202 update_period:5sample_number:10ip-1:10.1.0.1 ip-2:10.1.0.2 12-27 09:07