C实现简单的xml格式文件
今天在工作中遇到了一个需要处理xml格式的字符串,需求是修改某个固定的value值,并且还要把这个xml的key和value按照原本的格式在推送回去。
如果使用库,就显得太臃肿了,就想写个简单的demo实现这个功能:
/* AnalysisXml.c */ #include<stdio.h> #include<string.h> /* function: find the corresponding value with the key transmitted * parameter : * [in/out] pTmpXml the afferent string of xml that remaining after finding * [int]pKey the key of incoming * [out]pValue find the corresponding value * returned value: * -1 : pStrXml or pStuXml is null * -2 : the corresponding value is null or the key is not find */ static int AnalysisXml(char *pTmpXml, char *pValue, char *pKey) { int iRet = -1; if (pTmpXml == NULL || pValue == NULL || pKey == NULL) { return iRet; } memset(pValue, 0, sizeof(pValue)); char BegKey[64] = {0}; char EndKey[64] = {0}; sprintf(BegKey, "<%s>", pKey); sprintf(EndKey, "</%s>", pKey); //printf("BegKey = %s\n", BegKey); //printf("EndKey = %s\n", EndKey); char *pBegin = pTmpXml; char *pEnd = NULL; int BegKey_len = strlen(BegKey); if ( (pBegin = strstr(pTmpXml, BegKey)) != NULL) { pEnd = strstr(pBegin + 1,EndKey ); memcpy(pValue, pBegin + BegKey_len, pEnd - pBegin - BegKey_len); //printf("%s = %s\n", BegKey, pValue); pTmpXml = pEnd + strlen(EndKey); //printf("pTmpXml = %s\n",pTmpXml); iRet = 0; } else { iRet = -2; } return iRet; } /* function: analysis string whose foramt is xml * parameter : * [in] pStrXml the afferent string of xml * [out]pStuXml the struct of saving value of various * returned value: * -1 : pStrXml or pStuXml is null */ int HandleXml(char *pStrXml, XML_CONFIG_INPUT *pStuXml) { int iRet = -1; if (pStrXml == NULL || pStuXml == NULL) { return iRet; // } char szInbuf[1024] = {0}; int nInbufSize = 0; nInbufSize += sprintf(szInbuf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); char key[64] = {0}; char value[64] = {0}; char *pTmpXml = pStrXml; char KeyXml[][64] = {"id", "maxFrameRate", "reflectiveEnable", "reflectiveTemperature", "emissivity", "distance", "refreshInterval", "distanceUnit", "temperatureDataLength", "jpegPicEnabled"}; int len_KeyXml = sizeof(KeyXml) / sizeof(KeyXml[0]); printf("len_KeyXml = %d\n", len_KeyXml); for (int i = 0 ; i < len_KeyXml; i++) { //printf("KeyXml[%d] = %s\n", i, KeyXml[i]); sprintf(key, "%s", KeyXml[i]); iRet = AnalysisXml(pTmpXml, value, key); if (value != NULL) { printf("%s = %s\n", key, value); bool flag = (strcmp(key, "jpegPicEnabled")); if(!flag) { nInbufSize += sprintf(szInbuf+nInbufSize, "\n<JpegPictureWithAppendData>"); } nInbufSize += sprintf(szInbuf+nInbufSize, "\n<%s>%s</%s>", key, value, key); if(!flag) { nInbufSize += sprintf(szInbuf+nInbufSize, "\n</JpegPictureWithAppendData>"); } } else { printf("value is null\n"); } } printf("\nszInbuf = %s \n",szInbuf); return 0; } int main() { int iRet = -1; char Outxml[1024] = " <?xml version=\"1.0\" encoding=\"UTF-8\"?> \n\ <PixelToPixelParam version=\"2.0\" xmlns=\"http://www.hikvision.com/ver20/XMLSchema\"> \n\ <id>2</id> \n\ <maxFrameRate>400</maxFrameRate> \n\ <reflectiveEnable>false</reflectiveEnable> \n\ <reflectiveTemperature>20.00</reflectiveTemperature>\n\ <emissivity>0.96</emissivity>\n\ <distance>3000</distance>\n\ <refreshInterval>50</refreshInterval>\n\ <distanceUnit>centimeter</distanceUnit>\n\ <temperatureDataLength>4</temperatureDataLength>\n\ <JpegPictureWithAppendData>\n\ <jpegPicEnabled>true</jpegPicEnabled>\n\ </JpegPictureWithAppendData>\n\ </PixelToPixelParam>"; char Inxml[1024] = {0}; float fEmissvity = 0.01; int wDistance = 10; //iRet = HandleXml(Outxml, &stuXml); char szInbuf[1024] = {0}; int nInbufSize = 0; nInbufSize += sprintf(szInbuf, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); char key[64] = {0}; char value[64] = {0}; char *pTmpXml = Outxml; char KeyXml[][64] = {"id", "maxFrameRate", "reflectiveEnable", "reflectiveTemperature", "emissivity", "distance", "refreshInterval", "distanceUnit", "temperatureDataLength", "jpegPicEnabled"}; int len_KeyXml = sizeof(KeyXml) / sizeof(KeyXml[0]); printf("len_KeyXml = %d\n", len_KeyXml); for (int i = 0 ; i < len_KeyXml; i++) { //printf("KeyXml[%d] = %s\n", i, KeyXml[i]); sprintf(key, "%s", KeyXml[i]); iRet = AnalysisXml(pTmpXml, value, key); if (value != NULL) { printf("%s = %s\n", key, value); bool flag = (strcmp(key, "jpegPicEnabled")); if(!flag) { nInbufSize += sprintf(szInbuf+nInbufSize, "\n<JpegPictureWithAppendData>"); } if ( 0 == (strcmp(key, "emissivity"))) { nInbufSize += sprintf(szInbuf+nInbufSize, "\n<%s>%.2f</%s>", key, fEmissvity, key); } else if ( 0 == (strcmp(key, "distance"))) { nInbufSize += sprintf(szInbuf+nInbufSize, "\n<%s>%d</%s>", key, wDistance, key); } else { nInbufSize += sprintf(szInbuf+nInbufSize, "\n<%s>%s</%s>", key, value, key); } if(!flag) { nInbufSize += sprintf(szInbuf+nInbufSize, "\n</JpegPictureWithAppendData>"); } } else { printf("value is null\n"); } } printf("\nszInbuf = %s \n",szInbuf); return 0; }
如果是都xml文件的话只需要加上读写文件操作就可以使用了。
这个是非常简单的xml文件解析
其实还需要一个错误控制,对于遇到的每一个错误都有相应的返回码,在读取文件错误的时候可以准确的定位到错误在哪里发生的。