【关键字】XML解析;IPTV;C语言编程;Linux嵌入式操作系统
【出 处】 2018年 1期
【收 录】中文学术期刊网
【作 者】 杜源,张永安,周剑超
【单 位】
【摘 要】 摘要:通过实际要求设计了一种可以在嵌入式操作系统中运行的XML解析器,详细分析了其设计过程,给出基于C语言编程实现过程,通过实际检测,证明了其可行性和有效性并以成功应用于
摘要:通过实际要求设计了一种可以在嵌入式操作系统中运行的XML解析器,详细分析了其设计过程,给出基于C语言编程实现过程,通过实际检测,证明了其可行性和有效性并以成功应用于IPTV机顶盒
关键词:XML解析;IPTV;C语言编程;Linux嵌入式操作系统
1:xml解析技术概述
XML是extensible markup language的缩写。XML是一种简单的数据存储语言,使用一系列简单的标记描述数据,然后可以很容易加载XML数据到程序中并分析他,并以XML格式输出结果。XML (可扩展标识语言)是通用标识语言标准(SGML)的一个子集,它是描述网络上的数据内容和结构的标准。通过解析提取出xml里的数据,再调用相关函数,可以为开发工作节省大量的研发时间,本文应用xml文本在linux系统下设计了IPTV机顶盒界面和里面的流媒体内容,通过解析程序,提取相关数据,最后在普通电视机上播放显示内容,而如要更改界面和流媒体内容,只需更改xml文本文档的内容即可,大大增加可移植性,缩短研发周期。
2:IPTV 概述
IPTV即Interactive Personality TV,中文译文交互式网络电视,是一种利用宽带有线电视网,集互联网、多媒体、通讯等多种技术于一体,向家庭用户提供包括数字电视在内的多种交互式服务的崭新技术。其终端可以是PC、电视、便携、手机、车载等移动设备,播放内容包括图文、音乐、影视、游戏等。用户可以根据喜爱,自定义播放节目,实现节目的广播、点播、下载、录制等功能,并且由于IPTV采用MPEG2、MPEG4 PART2、H.264、WMV9编码方式传输数据,使得使用IPTV的用户可以以小带宽(约2M)获得接近于DVD品质的播放画面,自从2005,中国电信与上海文广集团合作在上海推出了中国大陆第一套IPTV业务后,IPTV业务在中国大陆迅猛发展,出现了多家IPTV机顶盒制造商,其机顶盒内部由嵌入式操作系统(如WinCE、Linux、VxWorks),由制造商自定义内核,本文采用的操作系统是由意法半导体公司提供的ST-Linux系统,开发平台也是由ST公司提供的集成达芬奇方案的arm开发板,本文根据实际要求自定义了一套基于DOM的XML文本,并利用C语言在ST-Linux环境下将其XML的内容解析,达到最后应用的目的,用此方式,当需要更改节目菜单甚至是整个机顶盒界面时,不再需要对程序代码有任何修改,只简单更改XML里面的内容信息即可,大大简化开发流程,缩短开发时间。
3:基于DOM的XML解析器
3.1 XML解析器
XML的数据可以用SAX或者DOM来构建,所谓SAX,它是一个用于处理XML事件驱动的“推”模型,虽然它不是W3C标准,但它却是一个得到了广泛认可的API。SAX解析器不用建立一个完整的文档树,而是在读取文档时激活一系列事件,这些事件被推给事件处理器,然后由事件处理器提供对文档内容的访问。 而DOM即文档对象模型|文件物件模型,是将所有信息写成树状的结构以文档形式储存起来,它必须包含详细的信息,因为如此,DOM并不适合大规模高数据量的解析工作,只适用于小型的解析器,所以,这也成为了困扰DOM解析器的技术瓶颈,本文所解析的单页XML文档,定义所包含内容最多不能超过128项,也正是出于这种顾虑。其结构的树状结构
如下所示:
图1
本文自定义的基于DOM的XML文档如下:
图2
3.2 XML解析函数
3.2.1 axmlengine.h函数
作为axmlengine.c函数的配置函数,axmlengine.h函数定义了所有axmlengine.c函数需要的结构体,如STGXOBJ_Rectangle_t,BtnInfo,VideoFrameInfo,VideoBtnInfo等,在axmlengine.h也定义了很多在axmlengine.c并未应用的结构体,如BckInfo,evt_param_t,GuiType_t结构体等,之所以这样做,是为了给后续开发留出接口,方便后续开发工作,在编写所有有关XML解析的程序时,都只用包含axmlengine.h即可,可简化编程工作量,结构体结构示例如下:(VideoFrameInfo结构体)
typedef struct
{
char Type[NODE_VALUE_MAXLEN];
BYTE TextSize[2];
char PreXml[NODE_VALUE_MAXLEN];
char CurrentXml[NODE_VALUE_MAXLEN];
char NxtXml[NODE_VALUE_MAXLEN];
char Cnumber;
}VideoFrameInfo;
3.2.2 VideoFrame 函数
由于设定的显示页面一页最多显示16个菜单节目,为了解决多页节目菜单能按正确的顺序显示的问题,在xml文档中,每一页都加入了上一页及下一页信息,也就是xml文档中的pre_xml和nxt_xml,在成功解析的基础上,当机顶盒检测到红外遥控器发出按键值为“0x1A08”即遥控器向上按键时,主程序调用显示函数打开pre_xml中的文本,当遥控器发出按键值为“0x1A1B”即向下按键时,再调用显示函数打开nxt_xml中的文本,这样就完成了翻页操作。解析代码如下:
src=strstr(src,"pre_xml=");
src=strstr(src,"\"");
end=strstr(src+1,"\"");
strncpy(pVideoFrame->PreXml,src+1,end-src);
*(pVideoFrame->PreXml+(end-src)-1)='\0';
src=strstr(src,"nxt_xml=");
src=strstr(src,"\"");
end=strstr(src+1,"\"");
strncpy(pVideoFrame->NxtXml,src+1,end-src);
*(pVideoFrame->NxtXml+(end-src)-1)='\0';
3.2.3 VideoButton函数
在解决了翻页问题后,需要解决的问题就是当前页中的各个子元素包含的信息,在设计xml文档规范时,规定节目子元素包含的信息有流媒体名称StreamName,显示的位置pos,流媒体类型NetStreamType,流媒体网络地址href,音频ID,视频ID,当规定好文本后,按照格式规范,逐行解析出相关内容,最后放入数据库保持,供其他API函数调用其解析代码如下:(pos的解析代码)如下:
//read sub_pos
src=strstr(src,"pos=");
if(src==NULL) return ST_NO_ERROR+1;
src=strstr(src,"\"");
if(src==NULL) return ST_NO_ERROR+1;
//ascii to int
pVideoButton->Rect.PositionX=atoi(src+1);
src=strstr(src,",");
pVideoButton->Rect.PositionY=atoi(src+1);
src=strstr(src+1,",");
pVideoButton->Rect.Width=atoi(src+1);
src=strstr(src+1,",");
pVideoButton->Rect.Height=atoi(src+1);
3.2.4 GetVideoXmlInfo函数
由于解析出来的数据都统一放入相应的结构体内,而在解析函数中为防止内存泄露,并未给结构体申明内存空间,所以在成功解析XML的基础上,为了能让IPTV机顶盒设计中存在的多种API函数调用解析数据,又设计了GetVideoXmlInfo函数,其作用就是读取外部XML文件,并统一分配内存空间和大小,在调用结束后,释放使用的内存,避免XML数据过大时,导致系统崩溃事件的发生,其部分代码如下:
int file;
char *buf,*tempbuf;
int buflen=0,ret=0;
int i=0,counter=0;
file=open(src,O_RDWR);
if (file<0)
{
printf("open file failed!,src=%s\n",src);
return ST_NO_ERROR+1;
}
buflen=lseek(file,0,SEEK_END);
buf=malloc(buflen);
if(buf==NULL) return ST_NO_ERROR+1;
tempbuf=buf;
ret=lseek(file,0,SEEK_SET);
ret=read(file,buf,buflen);
IsVideoXml(tempbuf);
tempbuf=strstr(tempbuf,"
VideoFrame(tempbuf,&xml->VideoFrame);
counter=VideoButton_Count(src);
*Len=counter;
i=counter;
tempbuf=strstr(tempbuf,"
while(i)
{
VideoButton(tempbuf,&xml->VideoBtn[counter-(i--)]);
tempbuf=strstr(tempbuf,"")+7;
}
close(file);
free(buf);
tempbuf=NULL;
return ST_NO_ERROR;
3.3 解析结果及流程
应用axmlengine.C将图2所示的XML文档解析后,其结果如下:
图3
由如上结果对照图2可见,解析结果完全可靠且正确。其解析流程如下图所示:
图4
4: 结论
本文应用C语言编程解决了基于DOM模型的XML解析工作,成功为上层API函数提供了所需要的数据,使得整体IPTV设计工作大大简化,加快了研发进程,缩短了研发周期,使得IPTV机顶盒大规模生产成为了可能。
参考文献:
[1] 谢质文,杨涛. IPTV产品,运营及案例 电子工业出版社 2008
[2] 倪继利. Linux内核分析及编程 电子工业出版社 2005
[3] 李善平,刘文山,王焕龙. Linux与嵌入式系统 清华大学出版社 2006
[4] Kurt Wall,Mark Watson,Markwhitis. GNU-Linux编程指南,自由软件基金会 1991
[5] 勤研工作室. U-boot 运行机制 http://www.kiyi.com.cn
[6] Peter Jay salzman,Michael Burian,Oripomerantz . THe Linux kenel module programming Guide 2005
[7] Stephen Prata. C primer plus(第五版)中文版 人民邮电出