MUSASHI C source: mssXml.c


グローバル関数
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: }