C语言中解析XML格式字符串
学习C语言过程中,有时候会有这样的需求,给你一个XML格式的字符串,例如:
<name>张三</name><age>23</age><height>175</height><weight>120</weight>
现在让我们把这个字符串中每个字段标签解析出来,可以把它存放到一个struct st_boy的结构体中。
首先,第一步我们需要先定义好结构体,其中包括,姓名name,可以用char name[]定义;年龄age,可以是int类型,身高height,也是int类型,体重weight,一般用double比较合适。结构体定义如下:
struct st_boy
{
char name[21]; //姓名
int age; //年龄
int height; //身高
double weight; //体重
};
第二步,假如我们要解析的是name这个标签,那我们就可以考虑使用字符串的一些函数,因为这个XML格式的字符串不方便我们操作,这里可以利用C语言本身提供的库函数snprintf将这个XML格式的字符串写进一个字符数组中,严格来讲字符串并不是C语言中的基本数据类型,所以这里我们要将拿到的这个XML格式的字符串写进数组中,这样才更好操作。
第三步,编写函数GetXMLBuffer_Str(char *in_XMLBuffer,char *in_FiledName,char *out_Value)对字符串完成解析
#include<stdio.h>
#include<string.h>
int GetXMLBuffer_Str(char *in_XMLBuffer,char *in_FiledName,char *out_Value);
int GetXMLBuffer_Int(char *in_XMLBuffer,char *in_FiledName,int *out_Value);
int GetXMLBuffer_Double(char *in_XMLBuffer,char *in_FiledName,double *out_Value);
struct st_girl
{
char name[20];
int age;
double weight;
char sc[10];
};
int main()
{
struct st_girl girl;
memset(&girl,0,sizeof(struct st_girl));//初始化结构体
char str[301]; //存放XML格式字符串
memset(str,0,sizeof(str));
strcpy(girl.name,"西施");
girl.age = 18;
//girl.height = 168;
girl.weight = 45.5;
strcpy(girl.sc,"火辣");
sprintf(str,"<name>%s</name><age>%d</age><weight>%lf</weight><sc>%s</sc>",\
girl.name,girl.age,girl.weight,girl.sc);
printf("=%s=\n",str);
memset(&girl,0,sizeof(struct st_girl));
GetXMLBuffer_Str(str,"name",girl.name);
GetXMLBuffer_Int(str,"age",&girl.age);
GetXMLBuffer_Double(str,"weight",&girl.weight);
printf("name = %s,age = %d,weight = %lf\n",girl.name,girl.age,girl.weight);
}
int GetXMLBuffer_Str(char *in_XMLBuffer,char *in_FiledName,char *out_Value)
{
if( out_Value == 0 ) return -1; //如果out_Value是空地址,直接返回
int m_NameLen = strlen(in_FiledName); //记录字段标签的长度
char *start = 0; //用于记录开始标签的位置
char *end = 0; //用于记录结束标签的位置
char m_SFiledName[51],m_EFiledName[51]; //字段的开始标签和结束标签
memset(m_SFiledName,0,sizeof(m_SFiledName));
memset(m_EFiledName,0,sizeof(m_EFiledName));
snprintf(m_SFiledName,50,"<%s>",in_FiledName); //利用snprintf将name写入开始标签中<name>
snprintf(m_EFiledName,50,"</%s>",in_FiledName); //利用snprintf将name写入结束标签中</name>
start = 0,end = 0; //将寻找开始标签和结束标签的开始位置和结束位置置位0
start = (char *)strstr(in_XMLBuffer,m_SFiledName); //利用strstr函数找到start的位置
if ( start != 0 )
{
/* 如果start不为0,再根据strstr函数找end位置,这里strstr的第一个参数用start就可以,不用再传入in_XMLBuffer从头再找,直接从sta
rt位置找更加省时间
*/
end = (char *)strstr(start,m_EFiledName);
}
if( (start == 0)||(end == 0) ) return -1;//判断start和end的值 若为0直接返回
int m_ValueLen = end - start - m_NameLen - 2; //记录要解析的字段的位置
strncpy(out_Value,start + m_NameLen + 2,m_ValueLen);//调用strncpy函数开始拷贝字段到out_Value
out_Value[m_ValueLen] = 0; //拷贝结束后 在out_Value指针所指向的最后一位 置位0
return 0;
}
int GetXMLBuffer_Int(char *in_XMLBuffer,char *in_FiledName,int *out_Value)
{
char strvalue[51];
memset(strvalue,0,sizeof(strvalue));
if (GetXMLBuffer_Str(in_XMLBuffer,in_FiledName,strvalue) != 0) return -1;
(*out_Value) = atoi(strvalue);
return 0;
}
int GetXMLBuffer_Double(char *in_XMLBuffer,char *in_FiledName,double *out_Value)
{
char strvalue[51];
memset(strvalue,0,sizeof(strvalue));
if(GetXMLBuffer_Str(in_XMLBuffer,in_FiledName,strvalue) != 0) return -1;
(*out_Value) = atof(strvalue);
return 0;
}
这里还写了另外两个函数,分别支持对int和double类型的解析
程序的运行效果如下:
作者:手心的阳光
时间:2021年9月11日
随手记录一下学习C语言过程中遇到的小坑,难免有错,欢迎指正,感谢感谢!!