如何从 xml 模式中获取常规 exp?我们知道 xml 模式有明确的正则表达式。但是如何实现呢?(例如,编写一个程序来获得常规的 exp)。
只考虑 complexType。例如:在 xsd 中,我们有:
<xs:element name="letter">
<xs:complexType mixed="true">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="orderid" type="xs:positiveInteger"/>
<xs:element name="shipdate" type="xs:date"/>
</xs:sequence>
</xs:complexType>
</xs:element>
或者:
<xs:complexType name="lettertype" mixed="true">
<xs:sequence>
<xs:element name="name" type="xs:string"/>
<xs:element name="orderid" type="xs:positiveInteger"/>
<xs:element name="shipdate" type="xs:date"/>
</xs:sequence>
</xs:complexType>
查找序列的意思是“,”,所以结果是“letter (name,orderid,shipdate)” 结果是name regex。
另一个例子:(如果 xsd 有这个:)
<xs:complexType name="request">
<xs:all>
<xs:element name="url" type="xs:string"/>
<xs:element name="component" type="xs:string"/>
<xs:element name="action" type="xs:string" minOccurs="0"/>
<xs:element name="params" type="varList" minOccurs="0"/>
<xs:element name="session" type="varList" minOccurs="0"/>
<xs:element name="cgi-data" type="varList" minOccurs="0"/>
</xs:all>
表示 complexType 的名称是“request”。。。。表示。。。的关系是“all”(如果我们用&表示“all”) all是“&”,所以结果是“request url&component&action¶ms&session&cgi-data”
有没有人可以帮我编写一个程序来实现这个功能?或者告诉我一个算法?
我编写了一个程序,但它太错误了,而且逻辑错误。这是我的程序:
#include<stdio.h>
#include<string.h>
#include <stdlib.h>
#include<io.h>
#define MatchMaxLen 69500
void process(char *result,char *str,char *str2,FILE* fp1)
{
if(strstr(str2,"complexType>")) fgets(str2,3000,fp1);
//strcat(str, str2);
char c[5],*pem;
int m=0; if(!strstr(str2,"xs:sequence")&&!strstr(str2,"xs:choice")&&!strstr(str2,"xs:all")) return;
if(strstr(str,"element name=\""))
{
pem=strstr(str,"element name=\"")+strlen("element name=\"");
while(*pem!='\"')*result++=*pem++;//put element name in purec
*result++=' ';
}
if(strstr(str2,"xs:sequence")) {*result++='(';c[m++]=',';}
if(strstr(str2,"xs:choice")) {*result++='(';c[m++]='|';}
if(strstr(str2,"all")) {*result++='(';c[m++]='&';}
fgets(str2,3000,fp1);
while(!(strstr(str2,"sequence>")||strstr(str2,"choice>")||strstr(str2,"all>")))
{
if(str2,"complexType>") process(result,str,str2,fp1);
if(strstr(str2,"element name=\""))
{
pem=strstr(str2,"element name=\"");
pem=pem+strlen("element name=\"");
}
if(strstr(str2,"element ref=\""))
{
pem=strstr(str2,"element ref=\"");
pem=pem+strlen("element ref=\"");
}
while(*pem!='\"') *result++=*pem++;
char *pmax,*pmin;
pmin=strstr(str2,"minOccurs=\"");
pmin=pmin+strlen("minOccurs=\"");
pmax=strstr(str2,"maxOccurs=\"");
pmax=pmax+strlen("maxOccurs=\"");
if(strstr(str2,"minOccurs")&&strstr(str2,"maxOccurs"))
{
if(*pmax=='1'&&*pmin=='0')
{
*result++=')';
*result++='?';
}
if(*pmax=='u'&&*pmin=='0')
{
*result++=')';
*result++='*';
}
if(*pmax=='u' && *pmin=='1')
{
*result++=')';
*result++='+';
}
*result++=c[m-1];
}
fgets(str2,3000,fp1);}
m--;
}
void main()
{
char type[100][20];
char name[100][20];
char res[3000];
char *result=res;
int flag=0;
char *str, *str2,*psp;
char destfname[20];
char *path="E:\\study\\research\\summer\\program\\*.xsd";/*use this when needed in future extension.Well, been used currently*/
char path1[]="E:\\study\\research\\summer\\program\\";
int len;
FILE *fp1,*fp2;
char string[MatchMaxLen];
char string2[3000];
struct _finddata_t ffblk;
long done= _findfirst(path,&ffblk);
do{ /*sprintf(filename,"dtd%d.dtd",i);
In the future if the filename is not regular or we don't know the exact numbersome day,
you may need function like _findnext,_findfirst.Well, currently being used*/
strcat(path1,ffblk.name);
if ((fp1=fopen(path1,"r"))==NULL)
{ /* read source file*/
printf("cannot open file\n");
exit(0);
}
sprintf(destfname,"IncludeNamexsdRe%s.txt",ffblk.name);
if((fp2=fopen(destfname,"w"))==NULL)
{ /* destination file*/
printf("cannot open file\n");
exit(0);
}
char *pem;
int j(0);
int i(0);
while (fgets(string,MatchMaxLen,fp1))
{//first while's purpose is to create the map of name and type
str=string;
if(!strstr(str,"element name")) continue;// the thing u need to process
i++;
pem=strstr(str,"element name");
pem=pem+strlen("element name=")+1;//pem: pointer of the element name
while(*pem!='\"')//while not the end point """
{
name[i][j++]=*pem++;//put the element name to the name[][]
}
name[i][j]='\0';
if(!(psp=strstr(string,"type="))) continue;
memccpy(type[i],psp+6,'\"',22);
}
rewind(fp1);//normal process, here we go
char purecomplex[20];
char *purec=purecomplex;
char ctype[20];
char *cotype=ctype;
while (fgets(string,MatchMaxLen,fp1))
{
if( strlen( string ) == 0 )
continue;
str=string;
if (str == NULL)
continue;
if( strlen( string ) == 1 ) continue;
//printf("%s",string);
str2=string2;
if(strstr(str,"<!--"))
{
while(!strstr(str,"-->"))
{
fgets(str2,3000,fp1);
strcat(str, str2);
//delete useless char
//printf("%s\n",str2);
}
continue;
}
if(!(pem=strstr(str,"element name=\""))&&!strstr(str,"complexType name=")) continue;
/*while(match(str))
{*/
fgets(str2,3000,fp1);
if(strstr(str2,"annotation>"))
{
do{ fgets(str2,3000,fp1);}while(!strstr(str2,"</xs:annotation>"));
fgets(str2,3000,fp1);
}
if(strstr(str,"complexType name=\""))
{
char* pt;
pt=strstr(str,"complexType name=\"")+strlen("complexType name=\"");
//if(strstr(str,"element name=\"")) pt=strstr(str,"element name=\"")+strlen("element name=\"");
while(*pt!='"') *result++=*pt++;//if has complextype name, put it in cotype
*result++=' ';
}
process(result,str,str2,fp1);
}//}
*result='\0';
fputs(res,fp2 );
//fputc('\n',fp2 );
//printf("%s\n",ffblk.name);
printf("2===%s\n",string);
fclose(fp1);
fclose(fp2);
}while(!_findnext(done,&ffblk));
_findclose(done);
}
有没有人可以帮我编写一个程序来实现这个功能?或者告诉我一个算法?