-- 作者:BetonArmEE
-- 发布时间:4/30/2007 6:26:00 PM
-- xmlp预处理器及iXML函数库文档
xmlp预处理器及iXML函数库文档 作者 : BetonArmEE 最新版本 : 1.0.1.20070430 >>> 目录 1.关于 1.1.功能概述 1.2.兼容平台列表 1.3.版本历史 2.知识手册 2.1.XML-c映射结构 2.2.XML-c映射结构读写函数 2.3.iXML函数库 2.4.xml结构定义文件及类型定义 3.使用指南 3.1.开发流程 3.2.一个完整的例子 4.参考列表 (无) >>> 正文 1.关于 1.1.功能概述 XML预处理器xmlp是xml的自动化工具,它处理xml结构定义文档,生成可包含、编译的标准c源代码(一个XML-c映射结构、一对XML-c映射结构读写函数),应用程序员使用自动生成的c源代码以及iXML函数库可以非常方便的处理XML文档。 1.2.兼容平台列表 Windows UNIX Linux ------------------------------------- CGIUrl Y Y Y 1.3.版本历史 2007-04-19 创建 xmlp v1.0.0.20070419 iXML v1.0.0.20070419 2007-04-30 创建 文档 v1.0.0.20070430 2.知识手册 2.1.XML-c映射结构 每一个XML都由若干个同一层次的XML标记组成,其中的每个XML标记可重复、递归的嵌套下一层XML标记,这和c语言结构体非常类似,我们不妨把某一XML标记结构映射成c语言结构体,下面是一个简单的例子: <userinfo> <id>1</id> <username>u</username> <nickname>n</nickname> <password> <cryptmode>cm</cryptmode> <cryptograph>cg</cryptograph> </password> <email>e</email> </userinfo> 映射成c语言结构体就是: struct userinfo { long id ; char username[ 32 + 1 ] ; char nickname[ 64 + 1 ] ; struct { char cryptmode[ 8 + 1 ] ; char cryptograph[ 48 + 1 ] ; } password ; char email[ 64 + 1 ] ; } ; 2.2.XML-c映射结构读写函数 如果一个XML文档由若干个平行的<userinfo>...</userinfo>结构组成,那么只要提供以结构为单元的读写函数就可以处理XML文档了。需要应用程序员写的应用伪代码类似如下: 声明userinfo映射结构变量 初始化userinfo映射结构变量 ; 填充userinfo映射结构变量 ; 通过userinfo映射结构写函数把userinfo映射结构数据以结构变量为单元以xml格式写入.xml文件 或者 声明userinfo映射结构变量 初始化userinfo映射结构变量 ; 通过userinfo映射结构读函数以结构为单元以xml格式从.xml文件读入数据到userinfo映射结构变量 处理应用逻辑 2.3.iXML函数库 XML-c映射结构读写函数并没有直接实现到底层,所需底层函数都被封装在iXML函数库中,以便于和xmlp预处理器分享目标代码。应用程序员在完成应用代码后不仅需要包含xmlp生成的自动化源代码,还需要链接iXML函数库才能完整的组装成可执行程序。 2.4.xml结构定义文件及类型定义 xml结构定义文件是被xmlp预处理器处理以生成自动化代码的格式来源。xml结构定义文件格式与应用要处理的xml文件格式基本相同,所不同的是在xml标记属性和标记值中填写标记属性和标记值的数据类型。比如应用要处理的xml格式如下: <userinfo2> <username language="l" postid="2">u</username> <nickname>&<n></nickname> <password device="d"> <cryptmode age="3">cm</cryptmode> <cryptograph>cg cg2cg3cg4</cryptograph> </password> <email url="e" /> </userinfo2> 所对应的xml结构定义文件内容可以是这样: <userinfo2> <username language="char*16" postid=long>char*32</username> <nickname>char*64</nickname> <password device="char*10"> <cryptmode age=long>char*8</cryptmode> <cryptograph>char*48</cryptograph> </password> <email url="char*64" /> </userinfo2> 类型定义非常简单,目前支持的类型如下: “char*n” 字符串型,最长n个字符(不包含'\0') “int” 整型(字长由编译器决定) “long” 长整型(字长由编译器决定) “float” 浮点型(字长由编译器决定) “double” 长浮点型(字长由编译器决定) 3.使用指南 3.1.开发流程 对于应用程序员来说,需要增加对xml结构定义文件的预处理过程,推荐放在makefile或者批处理文件中运行。 3.1.1.预处理xml结构定义文件 $ xmlp xml结构定义文件 xmlp读入xml结构定义文件处理之,生成XML-c映射结构c定义头文件“xml结构定义文件主文件名.XMLSTRUCT.h”、XML-c映射结构读函数c源代码文件“xml结构定义文件主文件名.XMLREAD.c”和XML-c映射结构写函数c源代码文件“xml结构定义文件主文件名.XMLWRITE.c”。 3.1.2.把自动生成的源代码文件包含到应用程序源代码中,编写应用代码 #include "test.XMLSTRUCT.h" #include "test.XMLREAD.c" #include "test.XMLWRITE.c" ... struct userinfo ui ; FILE *fp = NULL ; ... /* 填充XML-c映射结构 */ memset( &ui , 0x00 , sizeof(struct userinfo) ); strcpy( ui.username , "u" ); strcpy( ui.nickname , "n" ); strcpy( ui.password_device , "d" ); ui.password.cryptmode_age = 3 ; strcpy( ui.password.cryptmode , "cm" ); strcpy( ui.password.cryptograph , "cg" ); strcpy( ui.email_url , "e" ); /* 写XML文件 */ fp = fopen( filename , "w" ) ; iret = XMLWRITE_userinfo( fp , &ui ) ; fclose(fp); ... /* 读XML文件 */ fp = fopen( filename , "r" ) ; memset( &ui , 0x00 , sizeof(struct userinfo) ); iret = XMLREAD_userinfo( fp , &ui ) ; fclose(fp); ... 3.1.3.编译应用程序源代码时添加链接iXML库设置 UNIX/Linux添加库链接“cc ... -L(libiXML.a文件存放路径) -liXML -o (应用程序名)” Windows(Visual C++)环境中链接选项中添加静态库“libiXML.lib” 其它环境配置类似 3.2.一个完整的例子 ·xml结构定义文件 <userinfo> <id>long</id> <username>char*32</username> <nickname>char*64</nickname> <password> <cryptmode>char*8</cryptmode> <cryptograph>char*48</cryptograph> </password> <email>char*64</email> </userinfo> <userinfo2 id=long> <username language="char*16" postid=long>char*32</username> <nickname>char*64</nickname> <password device="char*10"> <cryptmode age=long>char*8</cryptmode> <cryptograph>char*48</cryptograph> </password> <email url="char*64" /> </userinfo2> ·应用程序源代码文件 #include <stdio.h> #include <string.h> #include "XMLToken.h" #include "XMLWrite.h" #include "test.XMLSTRUCT.h" #include "test.XMLWRITE.c" #include "test.XMLREAD.c" void write_userinfo() { struct userinfo userinfo1; FILE *fp ; char filename[256] = "../test.xml" ; int iret ; memset( &userinfo1 , 0x00 , sizeof(struct userinfo) ); userinfo1.id = 1 ; strcpy( userinfo1.username , "u" ); strcpy( userinfo1.nickname , "n" ); strcpy( userinfo1.password.cryptmode , "cm" ); strcpy( userinfo1.password.cryptograph , "cg" ); strcpy( userinfo1.email , "e" ); fp = fopen( filename , "w" ) ; if( fp == NULL ) { printf( "不能打开文件[%s]用于写\n" , filename ); return; } iret = XMLWRITE_userinfo( fp , &userinfo1 ) ; if( iret != 0 ) { printf( "不能输出xml[%d]\n" , iret ); fclose(fp); return; } fclose(fp); return; } void read_userinfo() { struct userinfo userinfo1; FILE *fp ; char filename[256] = "../test.xml" ; int iret ; memset( &userinfo1 , 0x00 , sizeof(struct userinfo) ); fp = fopen( filename , "r" ) ; if( fp == NULL ) { printf( "不能打开文件[%s]用于读\n" , filename ); return; } iret = XMLREAD_userinfo( fp , &userinfo1 ) ; if( iret != 0 ) { printf( "不能输入xml[%d]\n" , iret ); fclose(fp); return; } fclose(fp); printf( "userinfo1.id[%ld]\n" , userinfo1.id ); printf( "userinfo1.username[%s]\n" , userinfo1.username ); printf( "userinfo1.nickname[%s]\n" , userinfo1.nickname ); printf( "userinfo1.password.cryptmode[%s]\n" , userinfo1.password.cryptmode ); printf( "userinfo1.password.cryptograph[%s]\n" , userinfo1.password.cryptograph ); printf( "userinfo1.email[%s]\n" , userinfo1.email ); return; } void write_userinfo2() { struct userinfo2 userinfo2; FILE *fp ; char filename[256] = "../test2.xml" ; int iret ; memset( &userinfo2 , 0x00 , sizeof(struct userinfo2) ); userinfo2.userinfo2_id = 1 ; strcpy( userinfo2.username_language , "l" ); userinfo2.username_postid = 2 ; strcpy( userinfo2.username , "u" ); strcpy( userinfo2.nickname , "&<n>" ); strcpy( userinfo2.password_device , "d" ); userinfo2.password.cryptmode_age = 3 ; strcpy( userinfo2.password.cryptmode , "cm\n" ); strcpy( userinfo2.password.cryptograph , "cg\tcg2\rcg3\ncg4" ); strcpy( userinfo2.email_url , "e" ); fp = fopen( filename , "w" ) ; if( fp == NULL ) { printf( "不能打开文件[%s]用于写\n" , filename ); return; } iret = XMLWRITE_userinfo2( fp , &userinfo2 ) ; if( iret != 0 ) { printf( "不能输出xml[%d]\n" , iret ); fclose(fp); return; } fclose(fp); return; } void read_userinfo2() { struct userinfo2 userinfo2; FILE *fp ; char filename[256] = "../test2.xml" ; int iret ; memset( &userinfo2 , 0x00 , sizeof(struct userinfo) ); fp = fopen( filename , "r" ) ; if( fp == NULL ) { printf( "不能打开文件[%s]用于读\n" , filename ); return; } iret = XMLREAD_userinfo2( fp , &userinfo2 ) ; if( iret != 0 ) { printf( "不能输入xml[%d]\n" , iret ); fclose(fp); return; } fclose(fp); printf( "userinfo2.userinfo2_id[%ld]\n" , userinfo2.userinfo2_id ); printf( "userinfo2.username_language[%s]\n" , userinfo2.username_language ); printf( "userinfo2.username_postid[%ld]\n" , userinfo2.username_postid ); printf( "userinfo2.username[%s]\n" , userinfo2.username ); printf( "userinfo2.nickname[%s]\n" , userinfo2.nickname ); printf( "userinfo2.password_device[%s]\n" , userinfo2.password_device ); printf( "userinfo2.password.cryptmode_age[%ld]\n" , userinfo2.password.cryptmode_age ); printf( "userinfo2.password.cryptmode[%s]\n" , userinfo2.password.cryptmode ); printf( "userinfo2.password.cryptograph[%s]\n" , userinfo2.password.cryptograph ); printf( "userinfo2.email_url[%s]\n" , userinfo2.email_url ); return; } int main() { write_userinfo(); read_userinfo(); write_userinfo2(); read_userinfo2(); return 0; } 4.参考列表 (无)
|