c语言解析xml

来源:互联网 发布:h5即时聊天室源码下载 编辑:程序博客网 时间:2024/05/09 00:38

根据导师的要求,要用c语言解析一个xml文件,用于对升级文件进行合法性判断,进而对软件进行升级。

上网搜了一些关于这方面的资料,发现有一些是用C++或java等语言写的,当然也可以直接下载开源的代码,也可以下载库文件直接使用。但考虑到对xml文件解析其实用不到那么多功能,也考虑到硬件方面无法支持这么大的库文件。因此,决定自己写一段代码用于解析简单的xml文件。

看了一些源代码,发现他们主要使用树型结构来实现对xml 的解析,由于能力有限吧,感觉很麻烦,可能占用内存也会很大,所以我苦苦思索了好久,决定使用递归的方法解析xml文件,每当解析出相应的数值时,可以立即对这些数值进行判定是否合法,如果合法的话,可以继续解析;如果不合法的话,就可以直接跳出。

对这个xml文件,我做了很严格的定义:

<!-- 注释-->

<主标签 属性值1>

<子标签> 属性值2 </子标签>

<子标签>

<下级子标签>属性值3</下级子标签>

</子标签>

</主标签>

在这里,可以在标签间的任何地方进行注释,但禁止在标签内部进行注释;标签可以有多层嵌套,但必须保证标签有结束标志,嵌套必须合法。

属性值的规定方面,可以正确的解析属性值2和属性值3,但不会解析属性值1,属性值1可以起到注释的作用。

下面贴出一些主要的代码:

首先读取xml文件:

 fp = fopen("update.xml","r");
 if(fp == NULL) return 0;
 while((c = getc(fp)) != EOF)
 {
  data[i++] = c;
 }
然后对data数组进行相应的处理,如下:

int xml_takecell(char *data, int start, int end, char *name)
{
 int flag = 0;
 int j = 0;
 int nowstart = 0;
 int nowend = 0;
 char value[45] = {0};
 int keywords = 0;
 int isok = 0;

 if(update == 1) return 1;

 nowstart = xml_getnamestart(data,start,end,name);
 nowend = xml_getnameend(data,nowstart,end,name); 
 keywords = iskeywords(name);
 
 switch(keywords)
 {
 case KEY_UPDATELIST:
  xml_getvalue(data,nowstart,nowend,value);
  node_name = keywords;
  flag = 0;
  break;
 case KEY_ENABLE:
  xml_getvalue(data,nowstart,nowend,value);
  flag = 0;
  break;
 case KEY_START:
  xml_getvalue(data,nowstart,nowend,value);
  flag = 0;
  break;
 case KEY_END:
  xml_getvalue(data,nowstart,nowend,value);
  flag = 0;
  break;
 case KEY_ID:
  node_name = keywords;
  flag = 1;
  break;
 case KEY_SWVERSION:
  node_name = keywords;
  flag = 1;
  break;
 case KEY_CONFIG:
  node_name = keywords;
  flag = 1;
  break;

  ……
 default:
  flag = 1;
  node_name = 0;
  break;
 } 

 isok = checkupdate(node_name,keywords,value);
 if(isok == 1) return 0;

 if(flag == 1 && nowend <end)
 {
  cleanstring(name, 15);
  xml_takecell(data,nowstart,nowend,name);
 }
 if(nowend <end) 
 {
  cleanstring(name, 15);
  xml_takecell(data,nowend,end,name); 
 }

 return 0;
}

这是实现递归的核心代码,其中,函数xml_getnamestart()、xml_getnameend()是对同一个标签的开始处和结尾处进行查询,返回值是所在数组的位置,然后可以在此标签内部进行递归查询,直到找到最低一级的标签,并利用 xml_getvalue()获取标签的属性值。函数checkupdate()是对获取的属性值合法性做判断,如果是非法的,可以直接跳出此次处理。KEY_UPDATELIST、KEY_SWVERSION这些是自己事先定义的标签名。

各函数如下:

函数xml_getnamestart:

int xml_getnamestart(char *data, int start, int end, char *name)
{
 int now = start;
 int i = 0;
 int flag = 0;

 while(now < end)
 {
  now++;
 /*在这里,可以忽略<!--注释 -->形式的注释*/ 

 if(data[now-1] == '<' && data[now] != '!' && data[now] != '/')
   flag = 1; 
  else if((data[now] == '>' || data[now] == ' ') && flag == 1)
  {
   flag = 0;
//   printf("xml_getnamestart---->name is %s now is %d\n",name,now);
   break;
  }
  if(flag == 1)
  {
   name[i] = data[now];
   i++;
  }

 }
 return now;
}

函数xml_getnameend:

int xml_getnameend(char *data, int start, int end, char *name)
{
 int now = start;
 int i = 0;
 int flag = 0;
 char value[15] = {0};
 int ok = 0;

 while(now < end)
 {
  now++;
  if(data[now-1] == '<' && data[now] == '/')
  {
   flag = 1; 
   i = 0;
   ok = 0;
   now++;  
  }
 /*这里表示标签以空格或>结尾,也解释了属性值1为什么不能解析*/

 else if((data[now] == '>' || data[now] == ' ') && flag == 1)
  {
   flag = 0;
  }
  if(flag == 1)
  {
   if(name[i] == data[now])
   {
    i++;
    ok++; 
   }
   else if(name[i] != data[now])
   {
    i = 0;
    ok = 0;
    flag = 0;
   }
   
  }
  
  if(ok == strlen(name)) break;
 }
// printf("xml_getnameend---->name is %s now is %d \n",name,now);
 return now;
}

函数xml_getvalue:

/*在 > 和 < 之间为属性值*/

int xml_getvalue(char *data, int start, int end, char *value)
{
 int i = 0;
// char value[45] = {0};
 cleanstring(value,45);
 if(data[i+start] == '>') start++;
 for(i = 0; i+start< end; i++)
 {
  if(data[i+start] == '<') break;
  value[i] = data[start+i]; 
 }

 return 0;
}

这些代码写的比较业余,以后还要多多锻炼一下代码的编写规范。

这些参考资料是利用树型结构解析xml文件的思想,现在看的不是很明白,供以后修炼:

http://dangle2046.blog.163.com/blog/static/832104472008929101736243/

http://www.oschina.net/p/mini-xml

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 苹果手机和平板电脑共享怎么办 ipad被锁定了停用了怎么办 word文档被锁定不能编辑怎么办 苹果平板id忘了怎么办 ipad有id锁怎么办换主板 ipad刷机后忘记id密码怎么办 网购买东西手机号错了怎么办? 淘宝卖家虚假交易违规怎么办 好朋友问我借身份证开网店怎么办 为什么淘宝点开就跳过打不开怎么办 刹车油进眼睛里怎么办 眼睛被uv灯刺伤怎么办 眼睛被uv灯伤了怎么办 洗手台靠不到墙怎么办 加盟天猫优品不想干了怎么办 口袋侦探点开始就闪退怎么办 淘宝号被监控了怎么办 excel表格中把字体变细怎么办 wps方框中打字打不上怎么办 蘑菇街里面买东西受骗了怎么办? 淘宝买家号账户体检中心违规怎么办 支付宝充错手机账号怎么办 美团恶意差评怎么办 买家好评后追加差评怎么办 宝贝吃了一个金币怎么办 店铺微淘等级l1怎么办 淘宝占内存2个g怎么办 淘宝太占空间了怎么办 支付宝占内存大怎么办 苹果手机储存空间不足怎么办 小米平板电脑储存空间不足怎么办 ipad2很卡反应慢怎么办 ipadmini很卡反应慢怎么办 手机酷狗音乐文件不支持怎么办 2018款ipad闪退怎么办 ipad开不了机了怎么办 淘宝盖楼上限了怎么办 交了学费做微淘客却加不到人怎么办 微淘客交首付不想做了怎么办 蚂蚁微客二维码推广怎么办 游拍主播申请手机号被注册怎么办