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类型的解析

程序的运行效果如下:

C语言中解析XML格式字符串_字符串

 

作者:手心的阳光

时间:2021年9月11日

随手记录一下学习C语言过程中遇到的小坑,难免有错,欢迎指正,感谢感谢!!