MTK 自带的 XML 解析
现在大多数软件都用 xml 作为配置文件, MTK 本身也带了 XML 文件的解析,在此我不评说自带 XML 的解析效率,我只是想说怎么简单的应用:
先给出一个简单的 XML 文件的内容,我们以此文件为例子来学习 MTk 平台怎么解析 XML 文件,不妨设文件名为 sample.xml, 其内容如下:
<?xml version="1.0" encoding="utf-8" ?>
< l i =" 1 " d =" 240x320 " c =" 1 " a =" http://192.168.8.26:9090/ ">
< t i =" 1 " d =" 美女 " c =" 2 ">
< g i =" g1 " n =" 自拍美女 " c =" 10 " e =" jpg ">
< s > 289 </ s >
< s > 467 </ s >
< s > 773 </ s >
< s > 030 </ s >
< s > 264 </ s >
< s > 889 </ s >
< s > 245 </ s >
< s > 300 </ s >
< s > 175 </ s >
< s > 777 </ s >
</ g >
< g i =" g2 " n =" 泳装美女 " c =" 10 " e =" jpg ">
< s > 514 </ s >
< s > 166 </ s >
< s > 506 </ s >
< s > 338 </ s >
< s > 390 </ s >
< s > 031 </ s >
< s > 012 </ s >
< s > 030 </ s >
< s > 030 </ s >
< s > 889 </ s >
</ g >
</ t >
</ l >
MTK 自带的 XML 解析的函数声明在 xml_def.h 中。其中几个关键的是:
/* external API */
extern kal_int32 xml_new_parser(XML_PARSER_STRUCT *parser);
extern void xml_close_parser(XML_PARSER_STRUCT *parser);
extern void xml_register_element_handler(
XML_PARSER_STRUCT *parser,
XML_start_elem_hdlr start_hdlr,
XML_end_elem_hdlr end_hdlr);
extern void xml_register_data_handler(XML_PARSER_STRUCT *parser, XML_data_hdlr data_hdlr);
extern kal_int32 xml_parse(XML_PARSER_STRUCT *parser, kal_wchar *file_name);
几个关键的处理函数:
typedef void (*XML_start_elem_hdlr) (void *data, const kal_char *el, const kal_char **attr, kal_int32 error);
typedef void (*XML_end_elem_hdlr) (void *data, const kal_char *el, kal_int32 error);
typedef void (*XML_data_hdlr) (void *resv, const kal_char *el, const kal_char *data, kal_int32 len, kal_int32 error);
我们使用的方式如下:
WCHAR filename[]=L” sample.xml”;
首先定义一个 XML_PARSER_STRUCT xml_app_parser ;
xml_new_parser(&xml_app_parser);
// 注册读取 xml 内容的函数,为的是将处理读出来的 xml 内容 ( 默认的只是打印出来而已 )
xml_register_element_handler(&xml_app_parser,xml_app_read_start_element,xml_app_read_end_element);
xml_register_data_handler(&xml_app_parser, xml_app_read_data_element);
xml_parse(&xml_app_parser,(kal_wchar*) filename);
xml_stop_parse(&xml_app_parser);// 释放用于分析的 buffer 等资源
xml_close_parser(&xml_app_parser);
void xml_app_read_start_element(void *no_used, const char *el, const char **attr, S32 error)
{
}
Void xml_app_read_end_element(void *data, const kal_char *el, kal_int32 error)
{
}
Void xml_app_read_data_element(void *resv, const kal_char *el, const kal_char *data, kal_int32 len, kal_int32 error)
{
}
对于 XML 的解析是一行一行的解析的,对于本例来说,当注册了后,解析 xml, 当遇到 ”<” 号后会调用 xml_app_read_start_element ,将此行的内容读到 attr 中,其中 el=” l”,atr 中是 l 标签的属性,其组织方式是 attr[0]=”i”,attr[1]=”1”; attr[2]=”d”,attr[3]=”240x320”; attr[4]=”c”,attr[5]=”1”;attr[6]=”a”,attr[7]=” http://192.168.8.26:9090/”; 你可以在此函数里先一些对读到的信息进行保存,等等你需要的操作,其第一个参数 void *no_used 是没有使用的。
当读到某一行是 /> 时就调用用户注册的标签结束处理函数 xml_app_read_end_element ,其中的 data 没有使用, el 是表示结束的标签的名称, error 是错误代码,
读取内容的是 xml_app_read_data_element ,它被调用的时机是在 <> 之外的内容,例如此例中的 <s>289</s>, 当在 > 符号后有内容时便调用 xml_app_read_data_element ,其参数表示:第一个 resv 是没有使用, el 仍然是表示标签的,比如此处是 s,data 中存储的就是字符串 289 , len 表示 data 的长度。
此处我写一个处理函数给大家参照下,比如我想读取的是 l 标签的 a 属性和第一个 t 标签下的第二组 g 下的第 3 个 s 的大小(此例是 506 )
则我们写出如下的函数
Char netIp30];
void xml_app_read_start_element(void *no_used, const char *el, const char **attr, S32 error)
{
If(!strcmp(el,”a”))// 标签是 l
{
Strcpy(netIp,attr[7]);// 获取了 a 属性的值 http://192.168.8.26:9090/
}
}