c语言读取xml文件数据(如何使用C语言解析xml文件)
XML文件作为最常使用的存储层次结构数据的文件类型,被广泛应用于三维模型的存储表示。其文件一般是层次化的,用于描述层次化数据,如图1所示。一般地,可以将其结构理解为一颗树,最开始的树根,如图1中的<story>,被称为“根节点”,找到树根之后,继续找到第一个根节点,...,依次能够找到XML文件中所有的数据。
图1 XML的层次结构示例
所以,我们要想在程序中读取和处理XML文件,就需要根据XML文件的结构,解析XML文件的所有信息,从而能够处理XML文件中的信息。
由于C语言比较底层,从最基本的文件读写开始写解析XML文件的程序极其困难,并且存在操作不方便,难以扩展和缺乏鲁棒性等问题,所以,在实际开发领域,工程师们一般会找成熟的XML解析库来使用,如本文所要讲的libxml库,使用这些成熟的代码库,能够基本保证程序的稳定性和鲁棒性,并且由于libxml有公开的文档,团队协作就有标准可依。
libxml库需要下载,你可以从官网和github下载,也可以从微云下载,下载地址:https://share.weiyun.com/omPVXlss
下载下来之后,我们需要分别编译三个文件,三个文件分别解压,分别编译。编译之后将生成的lib文件配置到你的工程文件中(这里我们的工程文件使用Visual Studio创建的项目)。
图2 需编译的三个文件
环境配置成功之后,那么如何解析XML文件呢?
解析文档时只需要文档名和一个函数调用,再加上错误处理。下面代码查找keyword节点并打印节点下的文本内容,如下:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <libxml/xmlmemory.h>
#include <libxml/parser.h>
static int parseXMLDoc(const char* docname) {
xmlDocPtr doc;//XML文件指针
xmlNodePtr cur;//当前节点
xmlNodePtr subcur;//子节点
xmlKeepBlanksDefault(0);
doc = xmlParseFile(docname);
if (doc == NULL) {
fprintf(stderr, "doc error!\n");
return 0;
}
cur = xmlDocGetRootElement(doc);//获取根节点
if (cur == NULL) {
fprintf(stderr, "root error!\n");
xmlFreeDoc(doc);
return 0;
}
//根节点如果不是“xml”,则返回
if (xmlStrcmp(cur->name, (const xmlChar*)"xml")) {
printf("end\n");
return 0;
}
//获取子节点,获取名称为"coefs"的子节点,xml->Geometry->coefs
cur = cur->children;
while (cur != NULL) {
subcur= cur->xmlChildrenNode;
while (subcur != NULL) {
if (strcmp(subcur->name, "coefs") == 0){//查找名称为coefs的子节点
char* str = (char*)xmlNodeGetContent(subcur);
}
subcur = subcur->next;
}
cur = cur->next;
}
xmlFreeDoc(doc);
return 0;
}
int main(int argc, char **argv){
char *docname;
if(argc <= 1){
printf("Usage: %s docname\n", argv[0]);
return 0;
}
docname=argv[1];
parseXMLDoc(docname);
return 1;
}
解析XML文档的基本流程如下:
(1)定义文档指针、节点和子节点指针。子节点是指节点的节点。这里有个父子关系。
(2)调用xmlParseFile()解析文档。如果不成功,返回一个错误提示“"doc error!\n"”并停止。
(3)调用xmlDocGetRootElement()获取文档根节点,若无根节点则输出错误提示“root error!\n”,释放文档,停止。
(4)确认文档是否正确的类型,通过检查根节点名称来判断。
(5)检索节点的内容,这需要遍历文档树。对每个节点,遍历其子节点都需要一个循环。先用cur = cur->xmlChildrenNode获取第一个子节点,然后通过cur = cur->next不断向前遍历,直到cur==NULL。查找找指定节点时使用xmlStrcmp()函数,如果你指定的名称相同,就找到了你要的节点。通常把查找某个子节点的过程封装成函数。
(6)获取节点中的内容。查找到指定节点后,调用xmlNodeListGetString()获取节点下的文本。注意在XML中,包含在节点中的文本是这个节点的子节点,因此获取的是cur->xmlChildrenNode中的字符串。xmlNodeListGetString()会为返回的字符串分配内存,因此记得要用xmlFree()来释放它。
(7)调用xmlFreeDoc()释放文档指针。
,免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com