<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>