グローバル関数
mssAddXmlTagAttributeDbl 
mssAddXmlTagAttributeInt 
mssAddXmlTagAttributeStr 
mssEncoding 
mssFreeXmlTag 
mssInitXmlTag 
mssInitXmlTagByOpt 
mssNencoding 
mssOpt2XmlTag 
mssWriteXmlContent 
mssWriteXmlDeclaration 
mssWriteXmlEmptyTag 
mssWriteXmlEndTag 
mssWriteXmlIndent 
mssWriteXmlStartTag 
mssWriteXmlTagDbl 
mssWriteXmlTagFlg 
mssWriteXmlTagInt 
mssWriteXmlTagStr 
mssXmlTag2emptyTag 
mssXmlTag2endTag 
mssXmlTag2startTag 
0001: /**  
0002:  * # CHAPTER #  
0003:  * ============================================================================  
0004:  * MUSASHIで用いられるXMLデータの入力関連の関数  
0005:  * ============================================================================  
0006:  */  
0007:   
0008: #include <mssXml.h>  
0009: #include <stdio.h>  
0010: #include <stdlib.h>  
0011: #include <stdarg.h>  
0012: #include <string.h>  
0013: #include <sys/time.h>  
0014: #include <libxml/parser.h>  
0015: #include <libxml/parserInternals.h>  
0016: #include <libxml/encoding.h>  
0017: #include <iconv.h>  
0018: #include <errno.h>   
0019: #include <glob.h>  
0020:   
0021: /*############################################################################*/  
0022: /* グローバル変数                                                             */  
0023: /*############################################################################*/  
0024: xmlParserCtxtPtr ctxt;  
0025:   
0026: /**  
0027:  * # SECTION #  
0028:  * ----------------------------------------------------------------------------  
0029:  * 文字列のエンコーディング変換  
0030:  * ----------------------------------------------------------------------------  
0031:  */  
0032:   
0033: /**  
0034:  * # FUNCTION #  
0035:  * 文字列strをencodingする。encoding方法はグローバル変数icidで決まる。  
0036:  * 返値 : 変換後の文字列ポインタを返す。  
0037:  *        strがNULLならNULLを返す。  
0038:  *        encodingの方法が指定されていなければstrを返す。  
0039:  * icidの設定方法  
0040:  * include <iconv.h>  
0041:  * icid=iconv_open("UTF-8","EUC-JP"); EUC-JPからUTF-8への変換  
0042:  */  
0043: char *mssEncoding(char *str, iconv_t *icid)  
0044: {  
0045:   size_t  encilen; /*iconv用 入力文字列長*/  
0046:   size_t  encolen; /*iconv用 出力文字列長*/  
0047:   char *encip;     /*iconv用 入力文字列を示すポインタ */  
0048:   char *encop;     /*iconv用 出力文字列を示すポインタ */  
0049:   char *outStr;    /*出力文字列の辺値用ポインタ*/  
0050:   int  encMax;  
0051:   
0052:   if(str==NULL)return(NULL);  
0053:   if(icid==NULL)return(str);  
0054:   if(*str=='\0')return(str);  
0055:   
0056:   encMax=strlen(str)*4;  
0057:   
0058:   /*一応、入力文字列の4倍の領域確保*/  
0059:   outStr=mssCalloc(sizeof(char)*encMax,"encoding");  
0060:   encip=str;  
0061:   encop=outStr;  
0062:   encilen=strlen(encip)+1;  
0063:   encolen=encMax;  
0064:   if(-1==iconv(icid,&encip,&encilen,&encop,&encolen)){  
0065:     mssShowErrMsg("encoding error in iconv");  
0066:     exit(mssErrorNoDefault);  
0067:   }  
0068:   return(outStr);  
0069: }  
0070:   
0071: /**  
0072:  * # FUNCTION #  
0073:  * mssEncoding関数の文字数指定バージョン  
0074:  */  
0075: char *mssNencoding(char *str, int len, iconv_t *icid)  
0076: {  
0077:   size_t  encilen; /*iconv用 入力文字列長*/  
0078:   size_t  encolen; /*iconv用 出力文字列長*/  
0079:   char *encip;     /*iconv用 入力文字列を示すポインタ */  
0080:   char *encop;     /*iconv用 出力文字列を示すポインタ */  
0081:   char *outStr;    /*出力文字列の辺値用ポインタ*/  
0082:   int  encMax;  
0083:   
0084:   if(str==NULL)return(NULL);  
0085:   if(icid==NULL)return(str);  
0086:   
0087:   encMax=strlen(str)*4;  
0088:   
0089:   /*一応、入力文字列の4倍の領域確保*/  
0090:   outStr=mssCalloc(sizeof(char)*encMax,"encoding");  
0091:   encip=str;  
0092:   encop=outStr;  
0093:   encilen=len;  
0094:   encolen=encMax;  
0095:   if(-1==iconv(icid,&encip,&encilen,&encop,&encolen)){  
0096:     mssShowErrMsg("encoding error in iconv");  
0097:     exit(mssErrorNoDefault);  
0098:   }  
0099:   return(outStr);  
0100: }  
0101:   
0102: /**  
0103:  * # SECTION #  
0104:  * ----------------------------------------------------------------------------  
0105:  * XMLタグに関する「文字列←→mssXmlTag構造体」相互変換  
0106:  * ----------------------------------------------------------------------------  
0107:  */  
0108:   
0109: /**  
0110:  * # FUNCTION #  
0111:  * mssXmlTag構造体の初期化。  
0112:  * 要素名(element)を登録する(メモリを確保して)。  
0113:  * icidがセットされていれば(NULLでなければ)エンコーディングの変換をおこなう。  
0114:  * 属性をセットする時はmssAddXmlTagAttribute{Str,Int,Dbl}を利用する。  
0115:  * elementがNULLの時はNULLを返す。  
0116:  * elementが'\0'の場合はエラー終了。  
0117:  */  
0118: struct mssXmlTag *mssInitXmlTag(char *element, iconv_t *icid)  
0119: {  
0120:   struct mssXmlTag *xmlTag;  
0121:   
0122:   if(element==NULL){  
0123:     xmlTag=NULL;  
0124:   }else if(*element=='\0'){  
0125:     mssShowErrMsg("name of XML element is NULL");  
0126:     exit(mssErrorNoDefault);  
0127:   }else{  
0128:     xmlTag=mssCalloc(sizeof(struct mssXmlTag),"initXmlTag");  
0129:     if(icid==NULL){  
0130:       xmlTag->element=mssStrdup(element);  
0131:     }else{  
0132:       xmlTag->element=mssEncoding(element,icid);  
0133:     }  
0134:   }  
0135:   return(xmlTag);  
0136: }  
0137:   
0138: /**  
0139:  * # FUNCTION #  
0140:  * パラメータで与えられた要素&属性リストをセット、mssXmlTag構造体を返す。  
0141:  * str="element:attNam1=attVal1,attNam2=attVal2"  
0142:  * icidがセットされていれば(NULLでなければ)エンコーディングの変換をおこなう。  
0143:  * 要素名が'\0'の場合はエラー終了。  
0144:  */  
0145: struct mssXmlTag *mssInitXmlTagByOpt(char *str, iconv_t *icid)  
0146: {  
0147:   struct mssXmlTag *xmlTag;  
0148:   char *tmp;  
0149:   char *pos;  
0150:   int   attCnt;  
0151:   char **attNam;  
0152:   int   i;  
0153:   
0154:   if(!mssIsValidStr(str)) return(NULL);  
0155:     
0156:   /*元の文字列を保存*/  
0157:   tmp=mssStrdup(str);  
0158:   
0159:   /* 要素-属性セパレータの発見*/  
0160:   if( NULL!=(pos=strchr(tmp,':')) ){  
0161:     *pos='\0';  
0162:   }  
0163:   
0164:   /*要素の登録*/  
0165:   xmlTag=mssInitXmlTag(tmp,icid);  
0166:   
0167:   /*属性の登録*/  
0168:   if( pos!=NULL ){  
0169:     pos++;  
0170:   
0171:     attCnt=0;  
0172:     attNam=mssTokByChr(pos,',',&attCnt,0);  
0173:     for(i=0; i<attCnt; i++){  
0174:       if( NULL!=(pos=strchr(*(attNam+i),'=')) ){  
0175:         *pos='\0'; pos++;  
0176:         mssAddXmlTagAttributeStr(xmlTag,*(attNam+i), pos, icid);  
0177:       }else{  
0178:         mssAddXmlTagAttributeStr(xmlTag,*(attNam+i), "", icid);  
0179:       }  
0180:     }  
0181:     mssFree(attNam);  
0182:   }  
0183:   mssFree(tmp);  
0184:   return(xmlTag);  
0185: }  
0186:   
0187: /**  
0188:  * # FUNCTION #  
0189:  * mssXmlTag構造体領域の開放。  
0190:  */  
0191: void mssFreeXmlTag(struct mssXmlTag *xmlTag)  
0192: {  
0193:   int i;  
0194:   
0195:   if(xmlTag!=NULL){  
0196:     mssFree(xmlTag->element);  
0197:     for(i=0; i<xmlTag->attCnt; i++){  
0198:       mssFree(*(xmlTag->attributes+i));  
0199:     }  
0200:     mssFree(xmlTag->attributes);  
0201:     mssFree(xmlTag);  
0202:   }  
0203: }  
0204:   
0205: /**  
0206:  * # FUNCTION #  
0207:  * mssXmlTag構造体に指定の属性名(name)があるかどうかを調べ、あれば、  
0208:  * その属性名に対する値(文字列:value)を更新する。なければ、属性名と値を追加する  
0209:  * icidがセットされていれば(NULLでなければ)エンコーディングの変換をおこなう。  
0210:  * xmlTag->attributesの偶数番要素に属性名を、奇数番要素に値が保持される。  
0211:  * xmlTagがNULLの場合は何もせずにリターンする。  
0212:  */  
0213: void mssAddXmlTagAttributeStr(struct mssXmlTag *xmlTag, char *name, char *value, iconv_t *icid)  
0214: {  
0215:   char *buf;  
0216:   char *val;  
0217:   char *nam;  
0218:   int i;  
0219:   
0220:   if(xmlTag==NULL){  
0221:     return;  
0222:   }  
0223:   
0224:   if(name==NULL || value==NULL){  
0225:     mssShowErrMsg("internal error in addXmlAttribute");  
0226:     exit(mssErrorNoDefault);  
0227:   }  
0228:   
0229:   /*属性名*/  
0230:   if(icid==NULL){  
0231:     nam=mssStrdup(name);  
0232:   }else{  
0233:     nam=mssEncoding(name,icid);  
0234:   }  
0235:   /*属性値*/  
0236:   buf=mssMalloc(sizeof(char)*(strlen(value)+3),"updXmlTag");  
0237:   strcpy(buf,"\"");  
0238:   strcat(buf,value);  
0239:   strcat(buf,"\"");  
0240:   if(icid==NULL){  
0241:     val=mssStrdup(buf);  
0242:   }else{  
0243:     val=mssEncoding(buf,icid);  
0244:   }  
0245:   mssFree(buf);  
0246:    
0247:   /*既に登録されているか調べる*/  
0248:   for(i=0; i<xmlTag->attCnt; i=i+2){  
0249:     /*一致する属性があった!!*/  
0250:     if(strcmp(*(xmlTag->attributes+i),nam)==0){  
0251:       mssFree(*(xmlTag->attributes+i+1));  
0252:       *(xmlTag->attributes+i+1)=val;  
0253:       return;  
0254:     }  
0255:   }  
0256:     
0257:   /*valueに一致する属性名がなかったので追加*/  
0258:   xmlTag->attCnt+=2;  
0259:   xmlTag->attributes=mssRealloc(xmlTag->attributes,  
0260:                                 sizeof(char *)*xmlTag->attCnt,"addXmlAtt");  
0261:   *(xmlTag->attributes+xmlTag->attCnt-2)=nam;  
0262:   *(xmlTag->attributes+xmlTag->attCnt-1)=val;  
0263: }  
0264:   
0265: /**  
0266:  * # FUNCTION #  
0267:  * mssXmlTag構造体に指定の属性名(name)があるかどうかを調べ、あれば、  
0268:  * その属性名に体する値(整数:value)を更新する。なければ、属性名と値を追加する  
0269:  * icidがセットされていれば(NULLでなければ)エンコーディングの変換をおこなう。  
0270:  * xmlTag->attributesの偶数番要素に属性名を、奇数番要素に値が保持される。  
0271:  * xmlTagがNULLの場合は何もせずにリターンする。  
0272:  */  
0273: void mssAddXmlTagAttributeInt(struct mssXmlTag *xmlTag, char *name, int value, iconv_t *icid)  
0274: {  
0275:   char buf[100];  
0276:   char *tmp;  
0277:   char *val;  
0278:   char *nam;  
0279:   int i;  
0280:   
0281:   if(xmlTag==NULL){  
0282:     return;  
0283:   }  
0284:   
0285:   if(name==NULL){  
0286:     mssShowErrMsg("internal error in addXmlAttribute");  
0287:     exit(mssErrorNoDefault);  
0288:   }  
0289:   
0290:   /*属性名*/  
0291:   if(icid==NULL){  
0292:     nam=mssStrdup(name);  
0293:   }else{  
0294:     nam=mssEncoding(name,icid);  
0295:   }  
0296:   
0297:   /*属性値*/  
0298:   strcpy(buf,"\"");  
0299:   tmp=mssItoA(value);  
0300:   strcat(buf,tmp); mssFree(tmp);  
0301:   strcat(buf,"\"");  
0302:   if(icid==NULL){  
0303:     val=mssStrdup(buf);  
0304:   }else{  
0305:     val=mssEncoding(buf,icid);  
0306:   }  
0307:    
0308:   /*既に登録されているか調べる*/  
0309:   for(i=0; i<xmlTag->attCnt; i=i+2){  
0310:     /*一致する属性があった!!*/  
0311:     if(strcmp(*(xmlTag->attributes+i),nam)==0){  
0312:       mssFree(*(xmlTag->attributes+i+1));  
0313:       *(xmlTag->attributes+i+1)=val;  
0314:       return;  
0315:     }  
0316:   }  
0317:   
0318:   /*valueに一致する属性名がなかったので追加*/  
0319:   xmlTag->attCnt+=2;  
0320:   xmlTag->attributes=mssRealloc(xmlTag->attributes,  
0321:                                 sizeof(char *)*xmlTag->attCnt,"addXmlAtt");  
0322:   *(xmlTag->attributes+xmlTag->attCnt-2)=nam;  
0323:   *(xmlTag->attributes+xmlTag->attCnt-1)=val;  
0324: }  
0325:   
0326: /**  
0327:  * # FUNCTION #  
0328:  * mssXmlTag構造体に指定の属性名(name)があるかどうかを調べ、あれば、  
0329:  * その属性名に体する値(実数:value)を更新する。なければ、属性名と値を追加する  
0330:  * icidがセットされていれば(NULLでなければ)エンコーディングの変換をおこなう。  
0331:  * xmlTag->attributesの偶数番要素に属性名を、奇数番要素に値が保持される。  
0332:  * xmlTagがNULLの場合は何もせずにリターンする。  
0333:  */  
0334: void mssAddXmlTagAttributeDbl(struct mssXmlTag *xmlTag, char *name, double value, iconv_t *icid)  
0335: {  
0336:   char buf[256];  
0337:   char *tmp;  
0338:   char *val;  
0339:   char *nam;  
0340:   int i;  
0341:   
0342:   if(xmlTag==NULL){  
0343:     return;  
0344:   }  
0345:   
0346:   if(name==NULL){  
0347:     mssShowErrMsg("internal error in addXmlAttribute");  
0348:     exit(mssErrorNoDefault);  
0349:   }  
0350:   
0351:   /*属性名*/  
0352:   if(icid==NULL){  
0353:     nam=mssStrdup(name);  
0354:   }else{  
0355:     nam=mssEncoding(name,icid);  
0356:   }  
0357:   
0358:   /*属性値*/  
0359:   strcpy(buf,"\"");  
0360:   tmp=mssFtoA(value);  
0361:   strcat(buf,tmp); mssFree(tmp);  
0362:   strcat(buf,"\"");  
0363:   if(icid==NULL){  
0364:     val=mssStrdup(buf);  
0365:   }else{  
0366:     val=mssEncoding(buf,icid);  
0367:   }  
0368:    
0369:   /*既に登録されているか調べる*/  
0370:   for(i=0; i<xmlTag->attCnt; i=i+2){  
0371:     /*一致する属性があった!!*/  
0372:     if(strcmp(*(xmlTag->attributes+i),nam)==0){  
0373:       mssFree(*(xmlTag->attributes+i+1));  
0374:       *(xmlTag->attributes+i+1)=val;  
0375:       return;  
0376:     }  
0377:   }  
0378:   
0379:   /*valueに一致する属性名がなかったので追加*/  
0380:   xmlTag->attCnt+=2;  
0381:   xmlTag->attributes=mssRealloc(xmlTag->attributes,  
0382:                                 sizeof(char *)*xmlTag->attCnt,"addXmlAtt");  
0383:   *(xmlTag->attributes+xmlTag->attCnt-2)=nam;  
0384:   *(xmlTag->attributes+xmlTag->attCnt-1)=val;  
0385: }  
0386:   
0387: /**  
0388:  * # FUNCTION #  
0389:  * オプションで指定される要素-属性の指定書式をmssXmlTag構造体にセットし、  
0390:  * そのポインタを返す。  
0391:  * 与えられた文字列(str)がNULLの場合はNULLを返す。  
0392:  * 与えられた文字列(str)には一切変更を加えず、要素名、属性名、属性値  
0393:  * は新しい領域にセットされる。  
0394:  *  
0395:  * ex)  
0396:  * str="title:date=2002/01/01,time=10:34:58"  
0397:  * ->  
0398:  * xmlTag->element="title"  
0399:  * xmlTag->attributes={"date","2002/01/01","time","10:34:58"}  
0400:  * xmlTag->attCnt=4  
0401:  */  
0402: struct mssXmlTag *mssOpt2XmlTag(char *str, iconv_t *icid)  
0403: {  
0404:   char *pos;  
0405:   int   attCnt;  
0406:   char **atts;  
0407:   char *tmpStr;  
0408:   int   i;  
0409:   struct mssXmlTag *xmlTag;   
0410:     
0411:   if(!mssIsValidStr(str)) return(NULL);  
0412:   
0413:   tmpStr=mssStrdup(str);  
0414:   pos=strchr(tmpStr,':');  
0415:   
0416:   /*要素名だけの場合*/  
0417:   if(pos==NULL){  
0418:     xmlTag=mssInitXmlTag(tmpStr,icid);  
0419:     return(xmlTag);  
0420:   }  
0421:   
0422:   /*属性名、属性値のセット*/  
0423:   *pos++='\0';  
0424:   xmlTag=mssInitXmlTag(tmpStr,icid);  
0425:   atts=mssTokByChr(pos,',',&attCnt,0);  
0426:   for(i=0; i<attCnt; i++){  
0427:     pos=strchr(*(atts+i),'=');  
0428:     if(pos==NULL){  
0429:       mssShowErrMsg("invalid attribute specified");  
0430:       exit(mssErrorNoDefault);  
0431:     }  
0432:     *pos++='\0';  
0433:     mssAddXmlTagAttributeStr(xmlTag,*(atts+i), pos,icid);  
0434:   }  
0435:   
0436:   mssFree(atts);  
0437:   mssFree(tmpStr);  
0438:   return(xmlTag);  
0439: }     
0440:   
0441: /**  
0442:  * # FUNCTION #  
0443:  * mssXmlTag構造体から文字列としての空タグを作成し、そのポインタを返す。  
0444:  * icidがセットされていれば(NULLでなければ)エンコーディングの変換をおこなう。  
0445:  * 属性の数(xmlTag->attCnt)が奇数個の場合は、属性の最後の配列要素は無視される。  
0446:  *  
0447:  * ex.)  
0448:  * xmlTag->element="title"  
0449:  * xmlTag->attributes="date","2002/01/01","time","10:10:45"  
0450:  * xmlTag->attCnt=4  
0451:  *   ->  
0452:  * <title date="2002/01/01" time="10:10:45"/>  
0453:  */  
0454: char *mssXmlTag2emptyTag(struct mssXmlTag *xmlTag, iconv_t *icid)  
0455: {  
0456:   char buf[4096];  
0457:   char *str;  
0458:   int bc;  
0459:   int i;  
0460:   
0461:   buf[0]='<';  
0462:   
0463:   str=xmlTag->element;  
0464:   bc=1;  
0465:   while(*str!='\0'){  
0466:     if(bc>=4093){  
0467:       mssShowErrMsg("XML tag is too long");  
0468:       exit(mssErrorNoDefault);  
0469:     }  
0470:     buf[bc++]=*str++;  
0471:   }  
0472:   
0473:   for(i=0; i<xmlTag->attCnt/2; i++){  
0474:     buf[bc++]=' ';  
0475:     str=*(xmlTag->attributes+i);  
0476:     while(*str!='\0'){  
0477:       if(bc>=4093){  
0478:         mssShowErrMsg("XML tag is too long");  
0479:         exit(mssErrorNoDefault);  
0480:       }  
0481:       buf[bc++]=*str++;  
0482:     }  
0483:     buf[bc++]='=';  
0484:     str=*(xmlTag->attributes+i+1);  
0485:     while(*str!='\0'){  
0486:       if(bc>=4093){  
0487:         mssShowErrMsg("XML tag is too long");  
0488:         exit(mssErrorNoDefault);  
0489:       }  
0490:       buf[bc++]=*str++;  
0491:     }  
0492:   }  
0493:   
0494:   buf[bc++]='/';  
0495:   buf[bc++]='>';  
0496:   buf[bc++]='\0';  
0497:   
0498:   if(icid!=NULL){  
0499:     return(mssEncoding(buf,icid));  
0500:   }else{  
0501:     return(mssStrdup(buf));  
0502:   }  
0503: }  
0504:   
0505: /**  
0506:  * # FUNCTION #  
0507:  * mssXmlTag構造体から文字列としての開始タグを作成し、そのポインタを返す。  
0508:  * icidがセットされていれば(NULLでなければ)エンコーディングの変換をおこなう。  
0509:  * 属性の数(xmlTag->attCnt)が奇数個の場合は、属性の最後の配列要素は無視される。  
0510:  *  
0511:  * ex.)  
0512:  * xmlTag->element="title"  
0513:  * xmlTag->attributes="date","2002/01/01","time","10:10:45"  
0514:  * xmlTag->attCnt=4  
0515:  *   ->  
0516:  * <title date="2002/01/01" time="10:10:45">  
0517:  */  
0518: char *mssXmlTag2startTag(struct mssXmlTag *xmlTag, iconv_t *icid)  
0519: {  
0520:   char buf[4096];  
0521:   char *str;  
0522:   int bc;  
0523:   int i;  
0524:   
0525:   buf[0]='<';  
0526:   
0527:   str=xmlTag->element;  
0528:   bc=1;  
0529:   while(*str!='\0'){  
0530:     if(bc>=4093){  
0531:       mssShowErrMsg("XML tag is too long");  
0532:       exit(mssErrorNoDefault);  
0533:     }  
0534:     buf[bc++]=*str++;  
0535:   }  
0536:   
0537:   for(i=0; i<xmlTag->attCnt/2; i++){  
0538:     buf[bc++]=' ';  
0539:     str=*(xmlTag->attributes+i*2);  
0540:     while(*str!='\0'){  
0541:       if(bc>=4093){  
0542:         mssShowErrMsg("XML tag is too long");  
0543:         exit(mssErrorNoDefault);  
0544:       }  
0545:       buf[bc++]=*str++;  
0546:     }  
0547:     buf[bc++]='=';  
0548:     str=*(xmlTag->attributes+i*2+1);  
0549:     while(*str!='\0'){  
0550:       if(bc>=4093){  
0551:         mssShowErrMsg("XML tag is too long");  
0552:         exit(mssErrorNoDefault);  
0553:       }  
0554:       buf[bc++]=*str++;  
0555:     }  
0556:   }  
0557:   
0558:   buf[bc++]='>';  
0559:   buf[bc++]='\0';  
0560:   
0561:   if(icid!=NULL){  
0562:     return(mssEncoding(buf,icid));  
0563:   }else{  
0564:     return(mssStrdup(buf));  
0565:   }  
0566: }  
0567:   
0568: /**  
0569:  * # FUNCTION #  
0570:  * mssXmlTag構造体から文字列としての終了タグを作成し、そのポインタを返す。  
0571:  * icidがセットされていれば(NULLでなければ)エンコーディングの変換をおこなう。  
0572:  *  
0573:  * ex.)  
0574:  * xmlTag->element="title"  
0575:  * xmlTag->attributes="date","2002/01/01","time","10:10:45"  
0576:  * xmlTag->attCnt=4  
0577:  *   ->  
0578:  * </title>  
0579:  */  
0580: char *mssXmlTag2endTag(struct mssXmlTag *xmlTag, iconv_t *icid)  
0581: {  
0582:   char buf[4096];  
0583:   char *str;  
0584:   int bc;  
0585:   
0586:   buf[0]='<';  
0587:   buf[1]='/';  
0588:   
0589:   str=xmlTag->element;  
0590:   bc=2;  
0591:   while(*str!='\0'){  
0592:     if(bc>=4093){  
0593:       mssShowErrMsg("XML tag is too long");  
0594:       exit(mssErrorNoDefault);  
0595:     }  
0596:     buf[bc++]=*str++;  
0597:   }  
0598:   
0599:   buf[bc++]='>';  
0600:   buf[bc++]='\0';  
0601:   
0602:   if(icid!=NULL){  
0603:     return(mssEncoding(buf,icid));  
0604:   }else{  
0605:     return(mssStrdup(buf));  
0606:   }  
0607: }  
0608:   
0609: /**  
0610:  * # SECTION #  
0611:  * ----------------------------------------------------------------------------  
0612:  * XMLの出力関連  
0613:  * ----------------------------------------------------------------------------  
0614:  */  
0615:   
0616: /**  
0617:  * # FUNCTION #  
0618:  * XML宣言の出力。  
0619:  * バージョンとエンコーディングは、それぞれver,encで指定する。  
0620:  *  
0621:  * 例)  
0622:  * <?XML version="1.0" encoding="EUC-JP"?>  
0623:  */  
0624: void mssWriteXmlDeclaration( char *ver, char *enc, struct mssFPW *fp )  
0625: {  
0626:     
0627:   mssWriteStr("<?xml",fp);  
0628:   if(ver!=NULL){  
0629:     mssWriteStr(" version=\"", fp);  
0630:     mssWriteStr(ver, fp);  
0631:     mssWriteStr("\"", fp);  
0632:   }  
0633:   if(enc!=NULL){  
0634:     mssWriteStr(" encoding=\"", fp);  
0635:     mssWriteStr(enc, fp);  
0636:     mssWriteStr("\"",fp);  
0637:   }  
0638:   mssWriteStr("?>\n",fp);  
0639: }  
0640:   
0641: /**  
0642:  * # FUNCTION #  
0643:  * mssXmlTag構造体の情報を元に、開始タグを出力する。  
0644:  * icidがNULLでなければエンコーディング変換を行って出力する。  
0645:  */  
0646: void mssWriteXmlStartTag(struct mssXmlTag *xmlTag, iconv_t *icid, struct mssFPW *fpw)  
0647: {  
0648:   char *str;  
0649:   str=mssXmlTag2startTag(xmlTag, icid);  
0650:   mssWriteStr(str,fpw);  
0651:   mssFree(str);  
0652: }  
0653:   
0654: /**  
0655:  * # FUNCTION #  
0656:  * mssXmlTag構造体の情報を元に、終了タグを出力する。  
0657:  * icidがNULLでなければエンコーディング変換を行って出力する。  
0658:  */  
0659: void mssWriteXmlEndTag(struct mssXmlTag *xmlTag, iconv_t *icid, struct mssFPW *fpw)  
0660: {  
0661:   char *str;  
0662:   str=mssXmlTag2endTag(xmlTag, icid);  
0663:   mssWriteStr(str,fpw);  
0664:   mssFree(str);  
0665: }  
0666:   
0667: /**  
0668:  * # FUNCTION #  
0669:  * mssXmlTag構造体の情報を元に、空タグを出力する。  
0670:  * icidがNULLでなければエンコーディング変換を行って出力する。  
0671:  */  
0672: void mssWriteXmlEmptyTag(struct mssXmlTag *xmlTag, iconv_t *icid, struct mssFPW *fpw)  
0673: {  
0674:   char *str;  
0675:   str=mssXmlTag2emptyTag(xmlTag, icid);  
0676:   mssWriteStr(str,fpw);  
0677:   mssFree(str);  
0678: }  
0679:   
0680: /**  
0681:  * # FUNCTION #  
0682:  * 文字列(str)を出力する。  
0683:  * icidがNULLでなければエンコーディング変換を行って出力する。  
0684:  */  
0685: void mssWriteXmlContent( char *str, iconv_t *icid, struct mssFPW *fp )  
0686: {  
0687:   char *encStr;  
0688:   
0689:   if(str==NULL) return;  
0690:   
0691:   if(icid!=NULL){  
0692:     encStr=mssEncoding(str,icid);  
0693:     mssWriteStr(encStr,fp);  
0694:     mssFree(encStr);  
0695:   }else{  
0696:     mssWriteStr(str,fp);  
0697:   }  
0698: }  
0699:   
0700: /**  
0701:  * # FUNCTION #  
0702:  * XMLのインデントを出力する。  
0703:  * インデントの単位は半角空白2文字で、cnt個の空白を出力する。  
0704:  */  
0705: void mssWriteXmlIndent(int cnt, struct mssFPW *fpw)  
0706: {  
0707:   char spc[1025];  
0708:   int i;  
0709:   if(cnt>512) cnt=512;  
0710:   for(i=0; i<cnt; i++){  
0711:     spc[i*2]=' ';  
0712:     spc[i*2+1]=' ';  
0713:   }  
0714:   spc[i*2]='\0';  
0715:   mssWriteStr(spc, fpw);  
0716: }  
0717:   
0718: /**  
0719:  * # FUNCTION #  
0720:  * 開始タグ、文字列、終了タグをセットで出力する。  
0721:  * 属性を含む開始タグは扱えない。  
0722:  * またインデント、改行の有無も指定できる。  
0723:  * icidがNULLでなければエンコーディング変換を行って出力する。  
0724:  * ex)  
0725:  * indCnt=2, element="title", content="this is title" ,retFlg=1  
0726:  * ->  
0727:  *     <title>this is title</title>  
0728:  */  
0729: void mssWriteXmlTagStr(int indCnt, char *element, char *content, int retFlg, iconv_t *icid, struct mssFPW *fp )  
0730: {  
0731:   struct mssXmlTag *xmlTag;  
0732:   
0733:   if(content==NULL) return;  
0734:   
0735:   mssWriteXmlIndent(indCnt,fp);  
0736:   
0737:   xmlTag=mssInitXmlTag(element,icid);  
0738:   mssWriteXmlStartTag(xmlTag,icid,fp);  
0739:   mssWriteXmlContent(content, icid, fp);  
0740:   mssWriteXmlEndTag(xmlTag, icid,fp);  
0741:   mssFreeXmlTag(xmlTag);  
0742:   
0743:   if(retFlg){  
0744:     mssWriteRet(fp);  
0745:   }  
0746: }  
0747:   
0748: /**  
0749:  * # FUNCTION #  
0750:  * 開始タグ、整数、終了タグをセットで出力する。  
0751:  * 属性を含む開始タグは扱えない。  
0752:  * またインデント、改行の有無も指定できる。  
0753:  * icidがNULLでなければエンコーディング変換を行って出力する。  
0754:  * ex)  
0755:  * indCnt=2, element="title", content=10 ,retFlg=1  
0756:  * ->  
0757:  *     <title>10</title>  
0758:  */  
0759: void mssWriteXmlTagInt(int indCnt, char *element, int content, int retFlg, iconv_t *icid, struct mssFPW *fp )  
0760: {  
0761:   char *buf;  
0762:   struct mssXmlTag *xmlTag;  
0763:   
0764:   buf=mssItoA(content);  
0765:   mssWriteXmlIndent(indCnt,fp);  
0766:   
0767:   xmlTag=mssInitXmlTag(element,icid);  
0768:   mssWriteXmlStartTag(xmlTag,icid,fp);  
0769:   mssWriteXmlContent(buf, icid, fp);  
0770:   mssWriteXmlEndTag(xmlTag, icid,fp);  
0771:   mssFreeXmlTag(xmlTag);  
0772:   
0773:   if(retFlg){  
0774:     mssWriteRet(fp);  
0775:   }  
0776: }  
0777:   
0778: /**  
0779:  * # FUNCTION #  
0780:  * 開始タグ、実数、終了タグをセットで出力する。  
0781:  * 属性を含む開始タグは扱えない。  
0782:  * またインデント、改行の有無も指定できる。  
0783:  * icidがNULLでなければエンコーディング変換を行って出力する。  
0784:  * ex)  
0785:  * indCnt=2, element="title", content=5.24 ,retFlg=1  
0786:  * ->  
0787:  *     <title>5.24</title>  
0788:  */  
0789: void mssWriteXmlTagDbl(int indCnt, char *element, double content, int retFlg, iconv_t *icid, struct mssFPW *fp )  
0790: {  
0791:   char *buf;  
0792:   struct mssXmlTag *xmlTag;  
0793:   
0794:   buf=mssFtoA(content);  
0795:   mssWriteXmlIndent(indCnt,fp);  
0796:   
0797:   xmlTag=mssInitXmlTag(element,icid);  
0798:   mssWriteXmlStartTag(xmlTag,icid,fp);  
0799:   mssWriteXmlContent(buf, icid, fp);  
0800:   mssWriteXmlEndTag(xmlTag, icid,fp);  
0801:   mssFreeXmlTag(xmlTag);  
0802:   
0803:   if(retFlg){  
0804:     mssWriteRet(fp);  
0805:   }  
0806: }  
0807:   
0808: /**  
0809:  * # FUNCTION #  
0810:  * flgが1ならば空タグを出力する。  
0811:  * 属性を含む空タグは扱えない。  
0812:  * またインデント、改行の有無も指定できる。  
0813:  * icidがNULLでなければエンコーディング変換を行って出力する。  
0814:  * ex)  
0815:  * indCnt=2, element="title", flg=1 ,retFlg=1  
0816:  * ->  
0817:  *     <title/>  
0818:  */  
0819: void mssWriteXmlTagFlg(int indCnt, char *element, int flg, int retFlg, iconv_t *icid, struct mssFPW *fp )  
0820: {  
0821:   struct mssXmlTag *xmlTag;  
0822:   
0823:   if(flg){  
0824:   
0825:     mssWriteXmlIndent(indCnt,fp);  
0826:   
0827:     xmlTag=mssInitXmlTag(element,icid);  
0828:     mssWriteXmlEmptyTag(xmlTag,icid,fp);  
0829:     mssFreeXmlTag(xmlTag);  
0830:   
0831:     if(retFlg){  
0832:       mssWriteRet(fp);  
0833:     }  
0834:   }  
0835: }