<span style="font-size:24px;"> 很久没有碰xml这种东西了,今天有一朋友问如何解析一个xml文档,并获取每个节点对应的节点值,于是在网上找了一番,虽然有很多方法可以实现,但总觉得不如我所愿,于是自己用C语言写个简单的程序来实现此功能,仅供参考。</span>在ubuntu15.04系统下进行测试的,首先得安装libxml2库 apt-get install libxml2;安装完成后,就开始写代码getXml.c,包含两个函数,其完成功能是:传给它一个xml文档,函数进行解析,提取每个节点的节点名和相对应的节点值分别保存在nodeName和nodeValue这两个指针数组里,从而可以获得所需的节点名和对应的节点值。其代码如下:
#include <stdio.h> #include <libxml/parser.h> #include <libxml/tree.h> #include <libxml/xpath.h> #include <string.h> #define MAXSIZE 1024 int count; char *nodeName[MAXSIZE]; /* save xmlNode name */ char *nodeValue[MAXSIZE]; /* save xmlNode value */
/* get xml node name and value */
int getNameValue(xmlNodePtr rootNode,char *saveName[],char *saveValue[]) { xmlNodePtr curNode = NULL; xmlChar *szkey = NULL; if(rootNode == NULL) { return -1; } curNode = rootNode; curNode = curNode->xmlChildrenNode; while(curNode != NULL) { /* ignore xmlNode name is "text" node */
if(strcmp(curNode->name,"text") != 0) { saveName[count] = (char *)curNode->name; if(curNode->xmlChildrenNode->next == NULL) { szkey = xmlNodeGetContent(curNode); saveValue[count] = (char *)szkey; } else saveValue[count] = ""; count ++; } if(curNode->xmlChildrenNode != NULL) { getNameValue(curNode,saveName,saveValue); } curNode = curNode->next; } return 0; }
/* parsing xml file */
int readfile(char *file) { xmlDocPtr doc = NULL; xmlNodePtr rootNode = NULL; count = 0; doc = xmlReadFile(file,"UTF-8",XML_PARSE_RECOVER); if(doc == NULL) { perror("xmlReadFile() error !\n"); return -1; } //doc = xmlParseMemory(buff,strlen(buf)+1);//xml字符串解析 rootNode = xmlDocGetRootElement(doc);//xml文件解析 if(NULL == rootNode) { printf("doc is empty\n"); xmlFreeDoc(doc); return -1; } getNameValue(rootNode,nodeName,nodeValue); return 0; }
下面是main 函数:
<pre name="code" class="objc">int main(int argc,char *argv[]) { int ret; int i; int j; if(argv[1] == NULL) { printf("eg: ./xxx.exe [xxx.xml] \n"); return 0; } ret = readfile(argv[1]); if(ret == -1) { printf("error !\n"); return 0; } printf("%d\n",count); printf("***********************************************************\n"); for(i = 0; i < count ; i++) { printf("%s: %s\n",nodeName[i],nodeValue[i]); } return 0; }
代码写好之后就是编译,如下:
gcc -o test getXml.c -lxml2 -I/usr/include/libxml2
编写一个标准的xml文档Network.xml内容如下:
<?xml version="1.0" encoding="utf-8"?> <NetworkInterfaceList version="1.0"> <NetworkInterface version="1.0"> <id>0</id> <IPAddress> <ipVersion>v4</ipVersion> <addressingType>static</addressingType> <ipAddress>192.168.1.124</ipAddress> <subnetMask>255.255.255.0</subnetMask> <ipv6Address>xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx</ipv6Address> <bitMast>2</bitMast> <DefaultGateway> <ipAddress>192.168.1.0</ipAddress> <ipv6Address>xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx</ipv6Address> </DefaultGateway> <PrimaryDNS> <ipAddress>192.168.1.22</ipAddress> <ipv6Address>xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx</ipv6Address> </PrimaryDNS> <SecondaryDNS> <ipAddress>192.168.1.11</ipAddress> <ipv6Address>xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx</ipv6Address> </SecondaryDNS> </IPAddress> </NetworkInterface> </NetworkInterfaceList>