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文件解析

其实还需要一个错误控制,对于遇到的每一个错误都有相应的返回码,在读取文件错误的时候可以准确的定位到错误在哪里发生的。

posted @ 2019-12-12 17:49  王清河  阅读(642)  评论(0编辑  收藏  举报