JSON<->XML conversion sample program.

In this sample, you can do the following:

  • Parse JSON string and convert it to XML. Then save it to a file.
  • Parse the XML document and converts it to a JSON string. Then save it to a file.

To use this sample, link the following library to your application program and add the directory to the include files directory.

Header file:
lib.h : System E6.0 or later.
jansson.h
jansson_config.h
jansson_log.h
XML.h
CodeConversion.h : ver.1.1.1 or later.
Library file:
libJansson.a
libXML.a
libCodeConversion.a : ver.1.1.1 or later.
libSTARTUPOPH5000.a : System E6.0 or later.

Note:

When adding library files, link them in the above order.

    When adding a include file directory, follow the steps below to modify the project.
    1. Select the project in the [Project Explorer] view of e² studio and click [Properties] on the [Project] menu to display the [Properties] screen.

    2. Click [C/C++ Build] → [Settings] → [Tool Settings] → [Compiler: Source] → [ button].

    3. When the [Include file directories] dialogue appears, specify the directory in the following format in the [Directory] field and click [OK].

      "${TCINSTALL}/lib/gcc/rx-elf/${GCC_VERSION}/include-fixed"
      


    4. Click [OK] to close the [Properties] screen.

sampleConvertJsonToXml()

Parse the following JSON string and converts it to XML. Then save it to a file.

jsonText1
[
  {
    "name": "Sample001",
    "itemID": [
      "ID001"
    ],
    "score": 0,
    "result": null
  },
  {
    "name": "Sample002",
    "itemID": [
      "ID001",
      "ID002"
    ],
    "score": 35.5,
    "result": false
  },
  {
    "name": "Sample003",
    "itemID": [
      "ID001",
      "ID003"
    ],
    "score": 95,
    "result": true
  }
]

jsonText2
{
  "object1": {
    "name": "Sample001",
    "itemID": [
      "ID001"
    ],
    "score": 15.5,
    "result": null
  },
  "object2": {
    "name": "Sample002",
    "itemID": [
      "ID002"
    ],
    "score": 35.5,
    "result": false
  },
  "object3": {
    "name": "Sample003",
    "itemID": [
      "ID001",
      "ID002"
    ],
    "score": 90,
    "result": true
  },
  "object4": {
    "name": "Sample004",
    "itemID": [
      "ID001",
      "ID003"
    ],
    "score": 95,
    "result": true
  }
}

sampleConvertXmlToJson()

Parse the following XML document and converts it to a JSON string. Then save it to a file.

XmlDocument1
<?xml version="1.0" encoding="UTF-8"?>
<root type="ARRAY">
  <array_value type="OBJECT">
    <name type="STRING">Sample001</name>
    <itemID type="ARRAY">
      <array_value type="STRING">ID001</array_value>
    </itemID>
    <score type="INTEGER">0</score>
    <result type="NULL">null</result>
  </array_value>
  <array_value type="OBJECT">
    <name type="STRING">Sample002</name>
    <itemID type="ARRAY">
      <array_value type="STRING">ID001</array_value>
      <array_value type="STRING">ID002</array_value>
    </itemID>
    <score type="REAL">35.5</score>
    <result type="BOOLEAN">false</result>
  </array_value>
  <array_value type="OBJECT">
    <name type="STRING">Sample003</name>
    <itemID type="ARRAY">
      <array_value type="STRING">ID001</array_value>
      <array_value type="STRING">ID003</array_value>
    </itemID>
    <score type="INTEGER">95</score>
    <result type="BOOLEAN">true</result>
  </array_value>
</root>

XmlDocument2
<?xml version="1.0" encoding="UTF-8"?>
<root>
  <object1>
    <name>Sample001</name>
    <itemID type="ARRAY">
      <array_value>ID001</array_value>
    </itemID>
    <score type="REAL">15.5</score>
    <result>null</result>
  </object1>
  <object2>
    <name>Sample002</name>
    <itemID>
      <array_value>ID002</array_value>
    </itemID>
    <score>35.5</score>
    <result>false</result>
  </object2>
  <object3>
    <name>Sample003</name>
    <itemID type="ARRAY">
      <array_value>ID001</array_value>
      <array_value>ID002</array_value>
    </itemID>
    <score type="INTEGER">90</score>
    <result>true</result>
  </object3>
  <object4>
    <name>Sample004</name>
    <itemID>
      <array_value>ID001</array_value>
      <array_value>ID003</array_value>
    </itemID>
    <score>95</score>
    <result>true</result>
  </object4>
</root>


Sample: main.c

#include <stdio.h>
#include "lib.h"
#include "logapi.h"
#include "convertFormat.h"

int DBG_SAMPLE_CONVERT_FORMAT_ERROR = 1;
int DBG_SAMPLE_CONVERT_FORMAT_INFO = 1;
int DBG_SAMPLE_CONVERT_FORMAT_DEBUG = 1;

void sampleConvertJsonToXml();
void sampleConvertXmlToJson();

void main(void)
{
    Cursor(AUTOWRAP);

    while (1) {
        printf("1:JSON -> XML\n");
        printf("2:XML -> JSON\n");

        while (1) {
            if (kbhit()) {
                int key = getchar();
                if (key == '1') {
                    sampleConvertJsonToXml();
                    break;
                }
                if (key == '2') {
                    sampleConvertXmlToJson();
                    break;
                }
            }
            Idle();
        }
    }
}

const char* jsonText1 = "["
                            "{\"name\": \"Sample001\", "
                            "\"itemID\": [\"ID001\"], "
                            "\"score\": 0, \"result\": null}, "
                            "{\"name\": \"Sample002\", "
                            "\"itemID\": [\"ID001\", \"ID002\"], "
                            "\"score\": 35.5, \"result\": false},"
                            "{\"name\": \"Sample003\", "
                            "\"itemID\": [\"ID001\", \"ID003\"], "
                            "\"score\": 95, \"result\": true}"
                        "]";

const char* jsonText2 = "{"
                            "\"object1\":{\"name\": \"Sample001\", "
                            "\"itemID\": [\"ID001\"], "
                            "\"score\": 15.5, ""\"result\": null}, "
                            "\"object2\":{\"name\": \"Sample002\", "
                            "\"itemID\": [\"ID002\"], "
                            "\"score\": 35.5, \"result\": false},"
                            "\"object3\":{\"name\": \"Sample003\", "
                            "\"itemID\": [\"ID001\", \"ID002\"], "
                            "\"score\": 90, \"result\": true},"
                            "\"object4\":{\"name\": \"Sample004\", "
                            "\"itemID\": [\"ID001\", \"ID003\"], "
                            "\"score\": 95, \"result\": true}"
                        "}";



void sampleConvertJsonToXml()
{
    convertJsonToXml(jsonText1, "XML1.XML");
    /* Output
        <?xml version="1.0" encoding="UTF-8"?>
        <root type="ARRAY">
            <array_value type="OBJECT">
                <name type="STRING">Sample001</name>
                <itemID type="ARRAY">
                    <array_value type="STRING">ID001</array_value>
                </itemID>
                <score type="INTEGER">0</score>
                <result type="NULL">null</result>
            </array_value>
            <array_value type="OBJECT">
                <name type="STRING">Sample002</name>
                <itemID type="ARRAY">
                    <array_value type="STRING">ID001</array_value>
                    <array_value type="STRING">ID002</array_value>
                </itemID>
                <score type="REAL">35.5</score>
                <result type="BOOLEAN">false</result>
            </array_value>
            <array_value type="OBJECT">
                <name type="STRING">Sample003</name>
                <itemID type="ARRAY">
                    <array_value type="STRING">ID001</array_value>
                    <array_value type="STRING">ID003</array_value>
                </itemID>
                <score type="INTEGER">95</score>
                <result type="BOOLEAN">true</result>
            </array_value>
        </root>
     */
    convertJsonToXml(jsonText2, "XML2.XML");
    /* Output
        <?xml version="1.0" encoding="UTF-8"?>
        <root type="OBJECT">
            <object1 type="OBJECT">
                <name type="STRING">Sample001</name>
                <itemID type="ARRAY">
                    <array_value type="STRING">ID001</array_value>
                </itemID>
                <score type="REAL">15.5</score>
                <result type="NULL">null</result>
            </object1>
            <object2 type="OBJECT">
                <name type="STRING">Sample002</name>
                <itemID type="ARRAY">
                    <array_value type="STRING">ID002</array_value>
                </itemID>
                <score type="REAL">35.5</score>
                <result type="BOOLEAN">false</result>
            </object2>
            <object3 type="OBJECT">
                <name type="STRING">Sample003</name>
                <itemID type="ARRAY">
                    <array_value type="STRING">ID001</array_value>
                    <array_value type="STRING">ID002</array_value>
                </itemID>
                <score type="INTEGER">90</score>
                <result type="BOOLEAN">true</result>
            </object3>
            <object4 type="OBJECT">
                <name type="STRING">Sample004</name>
                <itemID type="ARRAY">
                    <array_value type="STRING">ID001</array_value>
                    <array_value type="STRING">ID003</array_value>
                </itemID>
                <score type="INTEGER">95</score>
                <result type="BOOLEAN">true</result>
            </object4>
        </root>
     */
}


const char* XmlDocument1 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<root type=\"ARRAY\">"
"  <array_value type=\"OBJECT\">"
"    <name type=\"STRING\">Sample001</name>"
"    <itemID type=\"ARRAY\">"
"      <array_value type=\"STRING\">ID001</array_value>"
"    </itemID>"
"    <score type=\"INTEGER\">0</score>"
"    <result type=\"NULL\">null</result>"
"  </array_value>"
"  <array_value type=\"OBJECT\">"
"    <name type=\"STRING\">Sample002</name>"
"    <itemID type=\"ARRAY\">"
"      <array_value type=\"STRING\">ID001</array_value>"
"      <array_value type=\"STRING\">ID002</array_value>"
"    </itemID>"
"    <score type=\"REAL\">35.5</score>"
"    <result type=\"BOOLEAN\">false</result>"
"  </array_value>"
"  <array_value type=\"OBJECT\">"
"    <name type=\"STRING\">Sample003</name>"
"    <itemID type=\"ARRAY\">"
"      <array_value type=\"STRING\">ID001</array_value>"
"      <array_value type=\"STRING\">ID003</array_value>"
"    </itemID>"
"    <score type=\"INTEGER\">95</score>"
"    <result type=\"BOOLEAN\">true</result>"
"  </array_value>"
"</root>";

const char* XmlDocument2 =
"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"
"<root>"
"  <object1>"
"    <name>Sample001</name>"
"    <itemID type=\"ARRAY\">"
"      <array_value>ID001</array_value>"
"    </itemID>"
"    <score type=\"REAL\">15.5</score>"
"    <result>null</result>"
"  </object1>"
"  <object2>"
"    <name>Sample002</name>"
"    <itemID>"
"      <array_value>ID002</array_value>"
"    </itemID>"
"    <score>35.5</score>"
"    <result>false</result>"
"  </object2>"
"  <object3>"
"    <name>Sample003</name>"
"    <itemID type=\"ARRAY\">"
"      <array_value>ID001</array_value>"
"      <array_value>ID002</array_value>"
"    </itemID>"
"    <score type=\"INTEGER\">90</score>"
"    <result>true</result>"
"  </object3>"
"  <object4>"
"    <name>Sample004</name>"
"    <itemID>"
"      <array_value>ID001</array_value>"
"      <array_value>ID003</array_value>"
"    </itemID>"
"    <score>95</score>"
"    <result>true</result>"
"  </object4>"
"</root>";

void sampleConvertXmlToJson()
{
    convertXmlToJson(XmlDocument1, "JSON1.TXT");
    /* Output
        [
          {
            "name": "Sample001",
            "itemID": [
              "ID001"
            ],
            "score": 0,
            "result": null
          },
          {
            "name": "Sample002",
            "itemID": [
              "ID001",
              "ID002"
            ],
            "score": 35.5,
            "result": false
          },
          {
            "name": "Sample003",
            "itemID": [
              "ID001",
              "ID003"
            ],
            "score": 95,
            "result": true
          }
        ]
     */
    convertXmlToJson(XmlDocument2, "JSON2.TXT");
    /* Output
        {
          "object1": {
            "name": "Sample001",
            "itemID": [
              "ID001"
            ],
            "score": 15.5,
            "result": null
          },
          "object2": {
            "name": "Sample002",
            "itemID": [
              "ID002"
            ],
            "score": "35.5",
            "result": false
          },
          "object3": {
            "name": "Sample003",
            "itemID": [
              "ID001",
              "ID002"
            ],
            "score": 90,
            "result": true
          },
          "object4": {
            "name": "Sample004",
            "itemID": [
              "ID001",
              "ID003"
            ],
            "score": "95",
            "result": true
          }
        }
     */
}

Sample: convertFormat.h
/*
 * Includes jansson library
 * This software is released under the MIT License.
 *
 * Refer https://opensource.org/licenses/mit-license.php
 * Refer https://jansson.readthedocs.io/en/latest/
 * Refer https://github.com/akheron/jansson/releases
 */

#ifndef CONVERT_FORMAT_H_
#define CONVERT_FORMAT_H_

#include "XML.h"
#include "jansson.h"

#define CONVERT_FORMAT_TAG    "[CONVERT_FORMAT]"
#define CONVERT_FORMAT_SUCCESS    0
#define CONVERT_FORMAT_ERROR      (-1)

#define ATTRUBUTE_TYPE          "type"

#define JSON_TYPE_NAME_OBJECT   "OBJECT"
#define JSON_TYPE_NAME_ARRAY    "ARRAY"
#define JSON_TYPE_NAME_STRING   "STRING"
#define JSON_TYPE_NAME_INTEGER  "INTEGER"
#define JSON_TYPE_NAME_REAL     "REAL"
#define JSON_TYPE_NAME_BOOLEAN  "BOOLEAN"
#define JSON_TYPE_NAME_NULL     "NULL"

typedef enum {
    ORIGIN_JSON_OBJECT,
    ORIGIN_JSON_ARRAY,
    ORIGIN_JSON_STRING,
    ORIGIN_JSON_INTEGER,
    ORIGIN_JSON_REAL,
    ORIGIN_JSON_BOOLEAN,
    ORIGIN_JSON_NULL,
    ORIGIN_JSON_OTHER,
    ORIGIN_JSON_INIT,
    ORIGIN_JSON_MAX
} origin_json_type;

extern void Idle(void);
int jsonAnalysisFromJson(json_t* pRoot);
int jsonAnalysis(const char* pText);
int integerToStr(json_int_t jsonInt, int valueStrLength, char* pValueStr);
int realToStr(double real, int valueStrLength, char* pValueStr);
int strToInteger(char* pStr, long* pValue);
int strToReal(char* pStr, double* pValue);
int setConvertedFormatKeyNode(XML_HANDLE hXml, char* pJsonTypeName,
    char* pNodeKey, char* pNodeValue,
    origin_json_type parentType, XML_Node** ppParentNode);
int setJsonTypeNameAndValueStr(json_t* pValue, char** ppJsonTypeName, char** ppValueStr);
int setRootNodeAttribute(XML_HANDLE hXml, origin_json_type parentType, char* pJsonTypeName);
int setObjectOrArrayAddNode(XML_HANDLE hXml, char* pJsonTypeName,
    char* pNodeKey, char* pNodeValue, XML_Node** ppParentNode,
    origin_json_type currentType, XML_Node** ppCurrentNode);
int jsonToXml(json_t* pRoot, XML_HANDLE hXml,
    origin_json_type parentType, XML_Node** ppParentNode);
void convertJsonToXml(const char* pJsonText, char* pFileName);
int getAttributeJsonType(XML_HANDLE hXml, XML_Node** ppParentNode,
    origin_json_type* pJsonType);
int analysisJsonType(XML_Node** ppCurrentNode, origin_json_type* pJsonType);
int xmlToJson(json_t** ppRoot, XML_HANDLE hXml, XML_Node** ppCurrentNode,
    origin_json_type parentType, json_t** ppAppendJson, char** ppAppendJsonkey);
void convertXmlToJson(const char* XmlDocument, char* pFileName);

#endif /* CONVERT_FORMAT_H_ */

Sample: convertFormat.c
/*
 * Includes jansson library
 * This software is released under the MIT License.
 *
 * Refer https://opensource.org/licenses/mit-license.php
 * Refer https://jansson.readthedocs.io/en/latest/
 * Refer https://github.com/akheron/jansson/releases
 */

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <float.h>
#include <math.h>
#include <errno.h>
#include <limits.h>
#include "CodeConversion.h"
#include "lib.h"
#include "logapi.h"
#include "convertFormat.h"

 //Log setting
int DBG_JANSSON_API_ERROR = 1;
int DBG_JANSSON_API_INFO = 1;
int DBG_JANSSON_API_DEBUG = 0;

int DBG_CONVERT_FORMAT_ERROR = 1;
int DBG_CONVERT_FORMAT_INFO = 1;
int DBG_CONVERT_FORMAT_DEBUG = 0;

char convertFormatApiVersion[] = "1.00";

const char ROOT_PATH[] = "/";
const char OBJECT_VALUE[] = "object_value";
const char ARRAY_VALUE[] = "array_value";

const int VALUE_STR_LEN_MAX = 32;

//[In]pRoot: json.
int jsonAnalysisFromJson(json_t* pRoot)
{
    char* pJsonText = NULL;
    char* pEncodeText = NULL;
    char* pSeparateText = NULL;
    int errorCode = 0;
    size_t outputLength = 0;

    if (!pRoot) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s jsonAnalysisFromJson. parameter error.\n",
            CONVERT_FORMAT_TAG);
        return CONVERT_FORMAT_ERROR;
    }

    pJsonText = json_dumps(pRoot, JSON_ENCODE_ANY | JSON_INDENT(2));
    if (!pJsonText) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s json_dumps error.\n", CONVERT_FORMAT_TAG);
        return CONVERT_FORMAT_ERROR;
    }

    pEncodeText = CONV_Utf8ToCP437oseString(pJsonText, strlen(pJsonText),
        &errorCode, &outputLength);
    if (!pEncodeText) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
            "%s  jsonAnalysisFromJson. convert string error. errorCode: %d.\n",
            CONVERT_FORMAT_TAG, errorCode);
        free(pJsonText);
        return CONVERT_FORMAT_ERROR;
    }

    LOG_PRINTF(DBG_CONVERT_FORMAT_INFO, "%s JSON Data: \n", CONVERT_FORMAT_TAG);

    pSeparateText = strtok(pEncodeText, "\n");
    LOG_PRINTF(DBG_CONVERT_FORMAT_INFO, "%s %s\n", CONVERT_FORMAT_TAG, pSeparateText);

    while (pSeparateText != NULL) {
        pSeparateText = strtok(NULL, "\n");
        LOG_PRINTF(DBG_CONVERT_FORMAT_INFO, "%s %s\n", CONVERT_FORMAT_TAG, pSeparateText);
    }
    free(pEncodeText);
    free(pJsonText);

    return CONVERT_FORMAT_SUCCESS;
}

//[In]pText: text.
int jsonAnalysis(const char* pText)
{
    json_t* pRoot = NULL;
    json_error_t error;
    int result = CONVERT_FORMAT_SUCCESS;

    if (!pText) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s jsonAnalysis. parameter error.\n",
            CONVERT_FORMAT_TAG);
        return CONVERT_FORMAT_ERROR;
    }

    pRoot = json_loads(pText, 0, &error);
    if (!pRoot) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s json_loads. error: on line %d: %s\n",
            CONVERT_FORMAT_TAG, error.line, error.text);
        return CONVERT_FORMAT_ERROR;
    }

    result = jsonAnalysisFromJson(pRoot);
    json_decref(pRoot);

    if (result != CONVERT_FORMAT_SUCCESS) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, error.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        return CONVERT_FORMAT_ERROR;
    }

    return CONVERT_FORMAT_SUCCESS;
}

//[In]jsonInt: a jansson integer value.
//[In]valueStrLength: a buffer memory length.
//[Out]pValueStr: Convert a integer value to a string value.
int integerToStr(json_int_t jsonInt, int valueStrLength, char* pValueStr)
{
    memset(pValueStr, 0, valueStrLength);
    int valueStrResult = sprintf(pValueStr, "%ld", jsonInt);
    if (valueStrResult < 0) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, integerToStr.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        return CONVERT_FORMAT_ERROR;
    }
    return CONVERT_FORMAT_SUCCESS;
}

//[In]real: a double value.
//[In]valueStrLength: a buffer memory length.
//[Out]pValueStr: Convert a double value to a string value.
int realToStr(double real, int valueStrLength, char* pValueStr)
{
    memset(pValueStr, 0, valueStrLength);
    int valueStrResult = sprintf(pValueStr, "%lg", real);
    if (valueStrResult < 0) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, realToStr.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        return CONVERT_FORMAT_ERROR;
    }
    return CONVERT_FORMAT_SUCCESS;
}

//[In]pStr
//[Out]pValue
int strToInteger(char* pStr, long* pValue)
{
    errno = 0;
    char* pIntegerEndStr = NULL;
    long longValue = 0;

    if ((pStr == NULL) || (pValue == NULL)) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, parameter error.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        return CONVERT_FORMAT_ERROR;
    }

    longValue = strtol(pStr, &pIntegerEndStr, 10);
    if ((longValue == LONG_MIN || longValue == LONG_MAX) && errno == ERANGE) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, strtol error.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        return CONVERT_FORMAT_ERROR;
    }
    else if (!pIntegerEndStr) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, strtol error.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        return CONVERT_FORMAT_ERROR;
    }

    *pValue = longValue;
    return CONVERT_FORMAT_SUCCESS;
}

//[In]pStr
//[Out]pValue
int strToReal(char* pStr, double* pValue)
{
    errno = 0;
    char* pEndRealStr = NULL;
    double realValue = 0;

    if ((pStr == NULL) || (pValue == NULL)) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, parameter error.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        return CONVERT_FORMAT_ERROR;
    }

    realValue = strtod(pStr, &pEndRealStr);
    if (errno) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, strtod error.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        return CONVERT_FORMAT_ERROR;
    }

    *pValue = realValue;
    return CONVERT_FORMAT_SUCCESS;
}

//[In]hXml: XML_HANDLE
//[In]pJsonTypeName: json type name. Ex)OBJECT, ARRAY, STRING, etc.
//[In]pNodeKey: node key.
//[In]pNodeValue: node value.
//[In]parentType: parent type.
//[In]ppParentNode: address of parrent node address.
int setConvertedFormatKeyNode(XML_HANDLE hXml, char* pJsonTypeName,
    char* pNodeKey, char* pNodeValue,
    origin_json_type parentType, XML_Node** ppParentNode)
{
    int errorCode = 0;
    XML_Node* pXmlNode = NULL;

    if (parentType == ORIGIN_JSON_INIT) {
        pXmlNode = XML_GetRootNode(hXml, &errorCode);
        if (!pXmlNode) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, XML_GetRootNode(). error:%d\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
            return CONVERT_FORMAT_ERROR;
        }
    }
    else {
        pXmlNode = XML_SetChildNodeValueByPath(hXml, *ppParentNode, pNodeKey,
            pNodeValue, &errorCode);

        if (!pXmlNode) {
            if (errorCode == XML_NO_VALUE_IN_INTERMEDIATE_NODE) {
                return CONVERT_FORMAT_SUCCESS;
            }
            else {
                LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                    "%s file: %s, line:%d, XML_SetChildNodeValueByPath(). error:%d.\n",
                    CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
                return CONVERT_FORMAT_ERROR;
            }
        }
        else {
            if (!XML_SetAttribute(hXml, pXmlNode, ATTRUBUTE_TYPE, pJsonTypeName, &errorCode)) {
                LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                    "%s file: %s, line:%d, XML_SetAttribute(). error:%d\n",
                    CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
                return CONVERT_FORMAT_ERROR;
            }
        }
    }
    return CONVERT_FORMAT_SUCCESS;
}

//[In]pValue: a Jansson value.
//[Out]pJsonTypeName: JSON type name. Ex) INTEGER, REAL, etc. Need to free memory.
//[Out]pValueStr: Convert a JSON value to a string value. Local language. Need to free memory.
int setJsonTypeNameAndValueStr(json_t* pValue, char** ppJsonTypeName, char** ppValueStr)
{
    int valueStrResult = -1;
    char* pEncodeText = NULL;
    char* pTempStr = NULL;
    int errorCode = 0;
    size_t outputLength = 0;
    size_t len = 0;
    const char TRUE_VALUE[] = "true";
    const char FALSE_VALUE[] = "false";
    const char NULL_VALUE[] = "null";

    if (json_is_string(pValue)) {
        len = strlen(json_string_value(pValue)) + 1;

        pTempStr = malloc(len);
        if (pTempStr == NULL) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, Cannot allocate memory.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }
        memset(pTempStr, 0, len);
        strcpy(pTempStr, json_string_value(pValue));

        len = strlen(JSON_TYPE_NAME_STRING) + 1;
        *ppJsonTypeName = malloc(len);
        if ((*ppJsonTypeName) == NULL) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, Cannot allocate memory.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }
        memset(*ppJsonTypeName, 0, len);
        strcpy(*ppJsonTypeName, JSON_TYPE_NAME_STRING);
    }
    else if (json_is_integer(pValue)) {
        pTempStr = malloc(VALUE_STR_LEN_MAX);
        if (pTempStr == NULL) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, Cannot allocate memory.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }
        memset(pTempStr, 0, len);
        valueStrResult = integerToStr(json_integer_value(pValue), VALUE_STR_LEN_MAX, pTempStr);
        if (valueStrResult != CONVERT_FORMAT_SUCCESS) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, integerToStr().\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }

        len = strlen(JSON_TYPE_NAME_INTEGER) + 1;
        *ppJsonTypeName = malloc(len);
        if ((*ppJsonTypeName) == NULL) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, Cannot allocate memory.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }
        memset(*ppJsonTypeName, 0, len);
        strcpy(*ppJsonTypeName, JSON_TYPE_NAME_INTEGER);
    }
    else if (json_is_real(pValue)) {
        pTempStr = malloc(VALUE_STR_LEN_MAX);
        if (pTempStr == NULL) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, Cannot allocate memory.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }
        memset(pTempStr, 0, len);
        valueStrResult = realToStr(json_real_value(pValue), VALUE_STR_LEN_MAX, pTempStr);
        if (valueStrResult != CONVERT_FORMAT_SUCCESS) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, realToStr().\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }

        len = strlen(JSON_TYPE_NAME_REAL) + 1;
        *ppJsonTypeName = malloc(len);
        if ((*ppJsonTypeName) == NULL) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, Cannot allocate memory.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }
        memset(*ppJsonTypeName, 0, len);
        strcpy(*ppJsonTypeName, JSON_TYPE_NAME_REAL);
    }
    else if (json_is_true(pValue)) {
        len = strlen(TRUE_VALUE) + 1;
        pTempStr = malloc(len);
        if (pTempStr == NULL) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, Cannot allocate memory.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }
        memset(pTempStr, 0, len);
        strcpy(pTempStr, TRUE_VALUE);

        len = strlen(JSON_TYPE_NAME_BOOLEAN) + 1;
        *ppJsonTypeName = malloc(len);
        if ((*ppJsonTypeName) == NULL) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, Cannot allocate memory.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }
        memset(*ppJsonTypeName, 0, len);
        strcpy(*ppJsonTypeName, JSON_TYPE_NAME_BOOLEAN);
    }
    else if (json_is_false(pValue)) {
        len = strlen(FALSE_VALUE) + 1;
        pTempStr = malloc(len);
        if (pTempStr == NULL) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, Cannot allocate memory.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }
        memset(pTempStr, 0, len);
        strcpy(pTempStr, FALSE_VALUE);

        len = strlen(JSON_TYPE_NAME_BOOLEAN) + 1;
        *ppJsonTypeName = malloc(len);
        if ((*ppJsonTypeName) == NULL) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, Cannot allocate memory.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }
        memset(*ppJsonTypeName, 0, len);
        strcpy(*ppJsonTypeName, JSON_TYPE_NAME_BOOLEAN);
    }
    else if (json_is_null(pValue)) {
        len = strlen(NULL_VALUE) + 1;
        pTempStr = malloc(len);
        if (pTempStr == NULL) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, Cannot allocate memory.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }
        memset(pTempStr, 0, len);
        strcpy(pTempStr, NULL_VALUE);

        len = strlen(JSON_TYPE_NAME_NULL) + 1;
        *ppJsonTypeName = malloc(len);
        if ((*ppJsonTypeName) == NULL) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, Cannot allocate memory.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }
        memset(*ppJsonTypeName, 0, len);
        strcpy(*ppJsonTypeName, JSON_TYPE_NAME_NULL);
    }
    else {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
            "%s file: %s, line:%d, setJsonTypeNameAndValueStr. Other case.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        goto Exit;
    }

    pEncodeText = CONV_Utf8ToCP437oseString(pTempStr, strlen(pTempStr),
        &errorCode, &outputLength);
    if (!pEncodeText) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, errorCode: %d\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
        goto Exit;
    }

    len = outputLength + 1;
    *ppValueStr = malloc(len);
    if ((*ppValueStr) == NULL) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
            "%s file: %s, line:%d, Cannot allocate memory.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        goto Exit;
    }
    memset(*ppValueStr, 0, len);
    strcpy(*ppValueStr, pEncodeText);
    free(pEncodeText);
    free(pTempStr);
    return CONVERT_FORMAT_SUCCESS;

Exit:
    LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, [error]Exit.\n",
        CONVERT_FORMAT_TAG, __FILE__, __LINE__);
    if (pEncodeText)
        free(pEncodeText);
    if (pTempStr)
        free(pTempStr);
    return CONVERT_FORMAT_ERROR;
}

int setRootNodeAttribute(XML_HANDLE hXml, origin_json_type parentType, char* pJsonTypeName)
{
    int errorCode = 0;
    XML_Node* pXmlNode = NULL;
    if (parentType == ORIGIN_JSON_INIT) {
        pXmlNode = XML_GetRootNode(hXml, &errorCode);
        if (!pXmlNode) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, XML_GetRootNode(). error:%d\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
            return CONVERT_FORMAT_ERROR;
        }

        if (!XML_SetAttribute(hXml, pXmlNode, ATTRUBUTE_TYPE, pJsonTypeName, &errorCode)) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, XML_SetAttribute(). error:%d\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
            return CONVERT_FORMAT_ERROR;
        }
        return CONVERT_FORMAT_SUCCESS;
    }
    return CONVERT_FORMAT_ERROR;
}

//[In]hXml
//[In]pJsonTypeName
//[In]pNodeKey
//[In]pNodeValue
//[In]ppParentNode
//[In]currentType
//[Out]ppCurrentNode
int setObjectOrArrayAddNode(XML_HANDLE hXml, char* pJsonTypeName,
    char* pNodeKey, char* pNodeValue, XML_Node** ppParentNode,
    origin_json_type currentType, XML_Node** ppCurrentNode)
{
    int errorCode = 0;

    if (pNodeKey != NULL && strlen(pNodeKey) > 0) {
        *ppCurrentNode = XML_AddChildNode(hXml, *ppParentNode, pNodeKey,
            pNodeValue, &errorCode);
    }
    else {
        switch (currentType) {
        case ORIGIN_JSON_OBJECT:
            *ppCurrentNode = XML_AddChildNode(hXml, *ppParentNode,
                OBJECT_VALUE, pNodeValue, &errorCode);
            break;
        case ORIGIN_JSON_ARRAY:
            *ppCurrentNode = XML_AddChildNode(hXml, *ppParentNode,
                ARRAY_VALUE, pNodeValue, &errorCode);
            break;
        default:
            LOG_PRINTF(DBG_CONVERT_FORMAT_INFO,
                "%s [CREATE_XML]setObjectOrArrayAddNode(). currentType:%d.\n",
                CONVERT_FORMAT_TAG, currentType);
            break;
        }
    }
    if (!(*ppCurrentNode)) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
            "%s file: %s, line:%d, XML_AddChildNode(). error:%d.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
        return CONVERT_FORMAT_ERROR;
    }
    else {
        if (!XML_SetAttribute(hXml, *ppCurrentNode, ATTRUBUTE_TYPE,
            pJsonTypeName, &errorCode)) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, XML_SetAttribute(). error:%d\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
            return CONVERT_FORMAT_ERROR;
        }
    }
    return CONVERT_FORMAT_SUCCESS;
}

//[In]pRoot
//[In]hXml
//[In]parentType
//[Out]ppParentNode
int jsonToXml(json_t* pRoot, XML_HANDLE hXml,
    origin_json_type parentType, XML_Node** ppParentNode)
{
    const char* pKey = NULL;
    json_t* pValue = NULL;
    void* pTmp = NULL;
    int i = 0;
    size_t index = 0;
    XML_Node* pCurrentNode = NULL;
    char* pValueStr = NULL;
    char* pJsonTypeName = NULL;
    int result = -1;
    char* pEncodedKey = NULL;
    int errorCode = 0;
    size_t outputLength = 0;

    switch (json_typeof(pRoot)) {
    case JSON_OBJECT:
        LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG, "%s {\n", CONVERT_FORMAT_TAG);
        if (parentType == ORIGIN_JSON_INIT) {
            if (setRootNodeAttribute(hXml, parentType,
                JSON_TYPE_NAME_OBJECT) != CONVERT_FORMAT_SUCCESS) {
                LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                    "%s file: %s, line:%d, setRootNodeAttribute(). error:%d\n",
                    CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
                goto Exit;
            }
        }

        json_object_foreach_safe(pRoot, pTmp, pKey, pValue) {
            pEncodedKey = CONV_Utf8ToCP437oseString((char*)pKey, strlen(pKey),
                &errorCode, &outputLength);
            if (!pEncodedKey) {
                LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                    "%s file: %s, line:%d, errorCode: %d\n",
                    CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
                goto Exit;
            }

            if (json_is_object(pValue)) {
                if (setObjectOrArrayAddNode(hXml, JSON_TYPE_NAME_OBJECT,
                    pEncodedKey, NULL, ppParentNode, ORIGIN_JSON_OBJECT,
                    &pCurrentNode) != CONVERT_FORMAT_SUCCESS) {
                    LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                        "%s file: %s, line:%d, "
                        "object setObjectOrArrayAddChildNode().\n",
                        CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                    goto Exit;
                }

                if (json_object_size(pValue) != 0) {
                    LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                        "%s [PARSE_JSON]object_object. i:%d, pKey:%s, object.\n",
                        CONVERT_FORMAT_TAG, i, pEncodedKey);
                    result = jsonToXml(pValue, hXml, ORIGIN_JSON_OBJECT, &pCurrentNode);
                    if (result != CONVERT_FORMAT_SUCCESS) {
                        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                            "%s file: %s, line:%d, jsonToXml error.\n",
                            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                        goto Exit;
                    }
                }
            }
            else if (json_is_array(pValue)) {
                if (setObjectOrArrayAddNode(hXml, JSON_TYPE_NAME_ARRAY,
                    pEncodedKey, NULL, ppParentNode, ORIGIN_JSON_OBJECT,
                    &pCurrentNode) != CONVERT_FORMAT_SUCCESS) {
                    LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                        "%s file: %s, line:%d, setObjectOrArrayAddChildNode().\n",
                        CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                    goto Exit;
                }

                LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                    "%s [PARSE_JSON]object_array. i:%d, pKey:%s, array.\n",
                    CONVERT_FORMAT_TAG, i, pEncodedKey);
                result = jsonToXml(pValue, hXml, ORIGIN_JSON_ARRAY, &pCurrentNode);
                if (result != CONVERT_FORMAT_SUCCESS) {
                    LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                        "%s file: %s, line:%d, jsonToXml error.\n",
                        CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                    goto Exit;
                }
            }
            else {
                //Need to free pJsonTypeName and pValueStr if you do not need it.
                result = setJsonTypeNameAndValueStr(pValue, &pJsonTypeName, &pValueStr);
                if (result != CONVERT_FORMAT_SUCCESS) {
                    LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                        "%s file: %s, line:%d, setJsonTypeNameAndValueStr.\n",
                        CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                    goto Exit;
                }
                LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                    "%s [PARSE_JSON]object_other. i:%d, pKey:%s, pValueStr:%s\n",
                    CONVERT_FORMAT_TAG, i, pEncodedKey, pValueStr);
                if (setConvertedFormatKeyNode(hXml, pJsonTypeName, pEncodedKey, pValueStr,
                    parentType, ppParentNode) != CONVERT_FORMAT_SUCCESS) {
                    LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                        "%s file: %s, line:%d, setConvertedFormatKeyNode.\n",
                        CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                    goto Exit;
                }
                free(pJsonTypeName);
                free(pValueStr);
            }
            i += 1;
            free(pEncodedKey);
        }
        LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG, "%s }\n", CONVERT_FORMAT_TAG);
        break;
    case JSON_ARRAY:
        LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG, "%s [\n", CONVERT_FORMAT_TAG);

        if (parentType == ORIGIN_JSON_INIT) {
            if (setRootNodeAttribute(hXml, parentType,
                JSON_TYPE_NAME_ARRAY) != CONVERT_FORMAT_SUCCESS) {
                LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                    "%s file: %s, line:%d, setRootNodeAttribute(). error:%d\n",
                    CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
                goto Exit;
            }
        }

        json_array_foreach(pRoot, index, pValue) {
            if (json_is_array(pValue)) {
                if (setObjectOrArrayAddNode(hXml, JSON_TYPE_NAME_ARRAY,
                    pEncodedKey, NULL, ppParentNode, ORIGIN_JSON_ARRAY,
                    &pCurrentNode) != CONVERT_FORMAT_SUCCESS) {
                    LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                        "%s file: %s, line:%d, "
                        "object setObjectOrArrayAddChildNode().\n",
                        CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                    goto Exit;
                }

                if (json_array_size(pValue) != 0) {
                    LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                        "%s [PARSE_JSON]array_array. index:%d, array.\n",
                        CONVERT_FORMAT_TAG, index);
                    result = jsonToXml(pValue, hXml, ORIGIN_JSON_ARRAY, &pCurrentNode);
                    if (result != CONVERT_FORMAT_SUCCESS) {
                        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                            "%s file: %s, line:%d, jsonToXml error.\n",
                            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                        goto Exit;
                    }
                }
            }
            else if (json_is_object(pValue)) {
                LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                    "%s [PARSE_JSON]array_object. index:%d, object.\n",
                    CONVERT_FORMAT_TAG, index);
                if (setObjectOrArrayAddNode(hXml, JSON_TYPE_NAME_OBJECT,
                    pEncodedKey, NULL, ppParentNode, ORIGIN_JSON_ARRAY,
                    &pCurrentNode) != CONVERT_FORMAT_SUCCESS) {
                    LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                        "%s file: %s, line:%d, "
                        "object setObjectOrArrayAddChildNode().\n",
                        CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                    goto Exit;
                }

                result = jsonToXml(pValue, hXml, ORIGIN_JSON_OBJECT, &pCurrentNode);
                if (result != CONVERT_FORMAT_SUCCESS) {
                    LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                        "%s file: %s, line:%d, jsonToXml error.\n",
                        CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                    goto Exit;
                }
            }
            else {
                //Need to free pJsonTypeName and pValueStr if you do not need it.
                result = setJsonTypeNameAndValueStr(pValue, &pJsonTypeName, &pValueStr);
                if (result != CONVERT_FORMAT_SUCCESS) {
                    LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                        "%s file: %s, line:%d, setJsonTypeNameAndValueStr.\n",
                        CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                    goto Exit;
                }

                LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                    "%s [PARSE_JSON]array_other. pKey:%s, pValueStr:%s\n",
                    CONVERT_FORMAT_TAG, pEncodedKey, pValueStr);

                if (setObjectOrArrayAddNode(hXml, pJsonTypeName, pEncodedKey,
                    pValueStr, ppParentNode, ORIGIN_JSON_ARRAY,
                    &pCurrentNode) != CONVERT_FORMAT_SUCCESS) {
                    LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                        "%s file: %s, line:%d, "
                        "object setObjectOrArrayAddChildNode().\n",
                        CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                    goto Exit;
                }
                free(pJsonTypeName);
                free(pValueStr);
            }
            i += 1;
        }
        LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG, "%s ]\n", CONVERT_FORMAT_TAG);
        break;
    default:
        LOG_PRINTF(DBG_CONVERT_FORMAT_INFO, "%s JSON TYPE: %d \n",
            CONVERT_FORMAT_TAG, json_typeof(pRoot));
        goto Exit;
    }

    return CONVERT_FORMAT_SUCCESS;

Exit:
    LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s [error]Exit.\n", CONVERT_FORMAT_TAG);
    if (pJsonTypeName)
        free(pJsonTypeName);
    if (pValueStr)
        free(pValueStr);
    if (pEncodedKey)
        free(pEncodedKey);

    return CONVERT_FORMAT_ERROR;
}


const char* XmlTemplate =
"<root>"
"</root>";

void convertJsonToXml(const char* pJsonText, char* pFileName)
{
    json_t* pRoot = NULL;
    json_error_t error;
    XML_HANDLE hXml = NULL;
    int result = 0;
    int errorCode = 0;
    size_t outputLength = 0;
    char* utf8Str;

    LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG, "%s convertJsonToXml\n", CONVERT_FORMAT_TAG);

    utf8Str = CONV_CP437oseToUtf8String((char*)pJsonText, strlen(pJsonText),
        &errorCode, &outputLength);

    if (!utf8Str) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s convert error. error:%d\n",
            CONVERT_FORMAT_TAG, errorCode);
        goto Exit;
    }

    result = jsonAnalysis(utf8Str);
    if (result != CONVERT_FORMAT_SUCCESS) {
        goto Exit;
    }
    pRoot = json_loads(utf8Str, 0, &error);
    free(utf8Str);
    if (!pRoot) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
            "%s file: %s, line:%d, json_loads. error: on line %d: %s\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__, error.line, error.text);
        goto Exit;
    }

    hXml = XML_CreateXmlObject(XML_LOCAL_STRING, XmlTemplate, 0, -1,
        CONV_CP437oseToUtf8String, CONV_Utf8ToCP437oseString, &errorCode);
    if (!hXml) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
            "%s file: %s, line:%d, XML_CreateXmlObject error. error:%d\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
        goto Exit;
    }

    XML_Node* xmlNode = XML_GetRootNode(hXml, &errorCode);
    if (!xmlNode) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
            "%s file: %s, line:%d, XML_GetRootNode error. error:%d\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
        goto Exit;
    }

    result = jsonToXml(pRoot, hXml, ORIGIN_JSON_INIT, &xmlNode);
    if (result != CONVERT_FORMAT_SUCCESS) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, jsonToXml error.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        goto Exit;
    }
    else {
        char fileStr[16];
        memset(fileStr, 0, sizeof(fileStr));
        if (pFileName && strlen(pFileName) >= 1 && strlen(pFileName) <= 12) {
            sprintf(fileStr, "%s", pFileName);
        }
        else {
            strcpy(fileStr, "JSON2XML.XML");
        }
        LOG_PRINTF(DBG_CONVERT_FORMAT_INFO, "%s File name:%s\n", CONVERT_FORMAT_TAG, fileStr);

        if (XML_SaveAsXmlFile(hXml, "<?xml version=\"1.0\" encoding=\"UTF-8\"?>",
            fileStr, true, &errorCode)) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG, "%s XML_SaveAsXmlFile. Saved successfully\n",
                CONVERT_FORMAT_TAG, errorCode);
        }
        else {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s XML_SaveAsXmlFile. error:%d\n",
                CONVERT_FORMAT_TAG, errorCode);
        }
        XML_DumpXmlObject(hXml);
        XML_ReleaseXmlObject(hXml, NULL);
    }
    json_decref(pRoot);

    return;
Exit:
    if (utf8Str)
        free(utf8Str);
    if (hXml)
        XML_ReleaseXmlObject(hXml, NULL);
    if (pRoot)
        json_decref(pRoot);
    return;
}

//[In]hXml
//[In]ppParentNode
//[Out]pJsonType
int getAttributeJsonType(XML_HANDLE hXml, XML_Node** ppParentNode, origin_json_type* pJsonType)
{
    int errorCode = 0;

    XML_Attribute* xmlAttr = XML_GetAttribute(hXml, *ppParentNode, &errorCode);
    if (!xmlAttr) {
        if (errorCode == XML_NOT_FOUND) { //No Attribute
            return CONVERT_FORMAT_SUCCESS;
        }
        else {
            *pJsonType = ORIGIN_JSON_OTHER;
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s getAttributeJsonType. XML_GetAttribute. error:%d.\n",
                CONVERT_FORMAT_TAG, errorCode);
        }
    }

    if (strcmp(JSON_TYPE_NAME_OBJECT, xmlAttr->value_raw) == 0) {
        *pJsonType = ORIGIN_JSON_OBJECT;
    }
    else if (strcmp(JSON_TYPE_NAME_ARRAY, xmlAttr->value_raw) == 0) {
        *pJsonType = ORIGIN_JSON_ARRAY;
    }
    else if (strcmp(JSON_TYPE_NAME_STRING, xmlAttr->value_raw) == 0) {
        *pJsonType = ORIGIN_JSON_STRING;
    }
    else if (strcmp(JSON_TYPE_NAME_INTEGER, xmlAttr->value_raw) == 0) {
        *pJsonType = ORIGIN_JSON_INTEGER;
    }
    else if (strcmp(JSON_TYPE_NAME_REAL, xmlAttr->value_raw) == 0) {
        *pJsonType = ORIGIN_JSON_REAL;
    }
    else if (strcmp(JSON_TYPE_NAME_BOOLEAN, xmlAttr->value_raw) == 0) {
        *pJsonType = ORIGIN_JSON_BOOLEAN;
    }
    else if (strcmp(JSON_TYPE_NAME_NULL, xmlAttr->value_raw) == 0) {
        *pJsonType = ORIGIN_JSON_NULL;
    }
    else {
        *pJsonType = ORIGIN_JSON_OTHER;
    }

    return CONVERT_FORMAT_SUCCESS;
}


//[In]ppCurrentNode
//[Out]jsonType
int analysisJsonType(XML_Node** ppCurrentNode, origin_json_type* pJsonType)
{
    XML_Node* pChildNode = NULL;
    XML_Node* pChildNextNode = NULL;
    char* pValue = NULL;

    if (ppCurrentNode == NULL || (*ppCurrentNode) == NULL || pJsonType == NULL) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s analysisJsonType parameter error.\n",
            CONVERT_FORMAT_TAG);
        return CONVERT_FORMAT_ERROR;
    }

    pChildNode = (*ppCurrentNode)->childNode;
    if (pChildNode) {        //ORIGIN_JSON_OBJECT or ORIGIN_JSON_ARRAY.
        pChildNextNode = pChildNode->nextNode;
        if (pChildNextNode) {
            if (pChildNode->name_raw) {
                if (pChildNextNode->name_raw) {
                    if (strcmp(pChildNode->name_raw,
                        pChildNextNode->name_raw) == 0) {
                        *pJsonType = ORIGIN_JSON_ARRAY;
                    }
                    else {
                        *pJsonType = ORIGIN_JSON_OBJECT;
                    }
                }
                else {
                    *pJsonType = ORIGIN_JSON_OBJECT;
                }
            }
            else {
                *pJsonType = ORIGIN_JSON_OBJECT;
            }
        }
        else {
            if (strcmp(pChildNode->name_raw, ARRAY_VALUE) == 0) {
                *pJsonType = ORIGIN_JSON_ARRAY;
            }
            else {
                *pJsonType = ORIGIN_JSON_OBJECT;
            }
        }
    }
    else {
        //ORIGIN_JSON_STRING, ORIGIN_JSON_INTEGER, ORIGIN_JSON_REAL,
        //ORIGIN_JSON_BOOLEAN or ORIGIN_JSON_NULL.
        pValue = (*ppCurrentNode)->value_raw;
        if (pValue) {
            if (strcmp("true", pValue) == 0) {
                *pJsonType = ORIGIN_JSON_BOOLEAN;
            }
            else if (strcmp("false", pValue) == 0) {
                *pJsonType = ORIGIN_JSON_BOOLEAN;
            }
            else if (strcmp("null", pValue) == 0) {
                *pJsonType = ORIGIN_JSON_NULL;
            }
            else {    //ORIGIN_JSON_STRING, ORIGIN_JSON_INTEGER, ORIGIN_JSON_REAL
                *pJsonType = ORIGIN_JSON_STRING;
            }
        }
        else {
            *pJsonType = ORIGIN_JSON_STRING;
        }
    }

    return CONVERT_FORMAT_SUCCESS;
}

//[Out]ppRoot
//[In]hXml
//[In]ppCurrentNode
//[In]parentType
//[In]ppAppendJson
//[In]ppAppendJsonkey
int xmlToJson(json_t** ppRoot, XML_HANDLE hXml, XML_Node** ppCurrentNode,
    origin_json_type parentType, json_t** ppAppendJson, char** ppAppendJsonkey)
{
    int jsonResult = 0;
    int result = CONVERT_FORMAT_SUCCESS;
    XML_Node* pNextNode = NULL;
    origin_json_type currentJsonType = ORIGIN_JSON_OTHER;
    origin_json_type autoJsonType = ORIGIN_JSON_OTHER;
    json_t* pCurrentJson = NULL;
    char* pJsonKeyValue = NULL;

    result = getAttributeJsonType(hXml, ppCurrentNode, &currentJsonType);
    if (result != CONVERT_FORMAT_SUCCESS) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
            "%s file: %s, line:%d, xmlToJson. getAttributeJsonType.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        return CONVERT_FORMAT_ERROR;
    }
    else {
        switch (currentJsonType) {
        case ORIGIN_JSON_OBJECT:
        case ORIGIN_JSON_ARRAY:
        case ORIGIN_JSON_STRING:
        case ORIGIN_JSON_INTEGER:
        case ORIGIN_JSON_REAL:
        case ORIGIN_JSON_BOOLEAN:
        case ORIGIN_JSON_NULL:
            break;
        default:
            result = analysisJsonType(ppCurrentNode, &autoJsonType);
            if (result != CONVERT_FORMAT_SUCCESS) {
                return CONVERT_FORMAT_ERROR;
            }
            break;
        }
    }

    if (currentJsonType == ORIGIN_JSON_OTHER) {
        currentJsonType = autoJsonType;
    }
    switch (currentJsonType) {
    case ORIGIN_JSON_OBJECT:
        pJsonKeyValue = (*ppCurrentNode)->name_raw;
        if (parentType == ORIGIN_JSON_INIT) {
            pCurrentJson = *ppRoot;
        }
        else {
            pCurrentJson = json_object();
            jsonResult = -1;
            if (json_is_object(*ppAppendJson)) {
                jsonResult = json_object_set_new(*ppAppendJson,
                    pJsonKeyValue, pCurrentJson);
            }
            else if (json_is_array(*ppAppendJson)) {
                jsonResult = json_array_append_new(*ppAppendJson, pCurrentJson);
            }

            if (jsonResult != 0) {
                LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                    "%s file: %s, line:%d, xmlToJson. Cannot set JSON.\n",
                    CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                return CONVERT_FORMAT_ERROR;
            }
        }

        LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG, "%s xmlToJson. object. pKey:%s\n",
            CONVERT_FORMAT_TAG, pJsonKeyValue);

        if ((*ppCurrentNode)->childNode) {
            pNextNode = (*ppCurrentNode)->childNode;
            Idle();
            result = CONVERT_FORMAT_SUCCESS;
            if (parentType == ORIGIN_JSON_INIT) {
                result = xmlToJson(ppRoot, hXml, &pNextNode,
                    currentJsonType, &pCurrentJson, &pJsonKeyValue);
            }
            else {
                result = xmlToJson(ppRoot, hXml, &pNextNode,
                    currentJsonType, &pCurrentJson, &pJsonKeyValue);
            }

            if (result != CONVERT_FORMAT_SUCCESS) {
                LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                    "%s file: %s, line:%d, xmlToJson. Cannot set JSON.\n",
                    CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                return CONVERT_FORMAT_ERROR;
            }
        }
        break;
    case ORIGIN_JSON_ARRAY:
        pJsonKeyValue = (*ppCurrentNode)->name_raw;
        if (parentType == ORIGIN_JSON_INIT) {
            pCurrentJson = *ppRoot;
        }
        else {
            pCurrentJson = json_array();
            jsonResult = -1;
            if (json_is_object(*ppAppendJson)) {
                jsonResult = json_object_set_new(*ppAppendJson,
                    pJsonKeyValue, pCurrentJson);
            }
            else if (json_is_array(*ppAppendJson)) {
                jsonResult = json_array_append_new(*ppAppendJson, pCurrentJson);
            }

            if (jsonResult != 0) {
                LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                    "%s file: %s, line:%d, xmlToJson. Cannot set JSON.\n",
                    CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                return CONVERT_FORMAT_ERROR;
            }
        }

        LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG, "%s xmlToJson. array. pKey:%s.\n",
            CONVERT_FORMAT_TAG, pJsonKeyValue);
        if ((*ppCurrentNode)->childNode) {
            pNextNode = (*ppCurrentNode)->childNode;
            Idle();
            result = CONVERT_FORMAT_SUCCESS;
            if (parentType == ORIGIN_JSON_INIT) {
                result = xmlToJson(ppRoot, hXml, &pNextNode, currentJsonType,
                    &pCurrentJson, &pJsonKeyValue);
            }
            else {
                result = xmlToJson(ppRoot, hXml, &pNextNode,
                    currentJsonType, &pCurrentJson, &pJsonKeyValue);
            }

            if (result != CONVERT_FORMAT_SUCCESS) {
                LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                    "%s file: %s, line:%d, xmlToJson. Cannot set JSON.\n",
                    CONVERT_FORMAT_TAG, __FILE__, __LINE__);
                return CONVERT_FORMAT_ERROR;
            }
        }
        break;
    case ORIGIN_JSON_STRING:
        pJsonKeyValue = *ppAppendJsonkey;

        if (json_is_object(*ppAppendJson)) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                "%s xmlToJson. string object append name:%s, value:%s\n",
                CONVERT_FORMAT_TAG, (*ppCurrentNode)->name_raw,
                (*ppCurrentNode)->value_raw);

            if ((*ppCurrentNode)->value_raw) {
                jsonResult = json_object_set_new(*ppAppendJson, (*ppCurrentNode)->name_raw,
                    json_string((*ppCurrentNode)->value_raw));
            }
            else {
                jsonResult = json_object_set_new(*ppAppendJson, (*ppCurrentNode)->name_raw,
                    json_string(""));
            }
        }
        else if (json_is_array(*ppAppendJson)) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                "%s xmlToJson. string array append name:%s, value:%s\n",
                CONVERT_FORMAT_TAG, (*ppCurrentNode)->name_raw,
                (*ppCurrentNode)->value_raw);
            if ((*ppCurrentNode)->value_raw) {
                jsonResult = json_array_append_new(*ppAppendJson,
                    json_string((*ppCurrentNode)->value_raw));
            }
            else {
                jsonResult = json_array_append_new(*ppAppendJson, json_string(""));
            }
        }

        break;
    case ORIGIN_JSON_INTEGER:
        pJsonKeyValue = *ppAppendJsonkey;

        long longValue = 0;
        result = strToInteger((*ppCurrentNode)->value_raw, &longValue);
        if (result != CONVERT_FORMAT_SUCCESS) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, strToInteger error.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            return CONVERT_FORMAT_ERROR;
        }

        if (json_is_object(*ppAppendJson)) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                "%s xmlToJson. integer object append name:%s, value:%s\n",
                CONVERT_FORMAT_TAG, (*ppCurrentNode)->name_raw,
                (*ppCurrentNode)->value_raw);

            jsonResult = json_object_set_new(*ppAppendJson, (*ppCurrentNode)->name_raw,
                json_integer(longValue));
        }
        else if (json_is_array(*ppAppendJson))
        {
            LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                "%s xmlToJson. integer array append name:%s, value:%s\n",
                CONVERT_FORMAT_TAG, (*ppCurrentNode)->name_raw,
                (*ppCurrentNode)->value_raw);
            jsonResult = json_array_append_new(*ppAppendJson, json_integer(longValue));
        }

        break;
    case ORIGIN_JSON_REAL:
        pJsonKeyValue = *ppAppendJsonkey;

        double doubleValue = 0;
        result = strToReal((*ppCurrentNode)->value_raw, &doubleValue);
        if (result != CONVERT_FORMAT_SUCCESS) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, strToReal error.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            return CONVERT_FORMAT_ERROR;
        }

        if (json_is_object(*ppAppendJson)) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                "%s xmlToJson. real object append name:%s, value:%s\n",
                CONVERT_FORMAT_TAG, (*ppCurrentNode)->name_raw,
                (*ppCurrentNode)->value_raw);
            jsonResult = json_object_set_new(*ppAppendJson, (*ppCurrentNode)->name_raw,
                json_real(doubleValue));
        }
        else if (json_is_array(*ppAppendJson)) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                "%s xmlToJson. real array append value:%s\n",
                CONVERT_FORMAT_TAG, (*ppCurrentNode)->value_raw);
            jsonResult = json_array_append_new(*ppAppendJson, json_real(doubleValue));
        }

        break;
    case ORIGIN_JSON_BOOLEAN:
        pJsonKeyValue = *ppAppendJsonkey;

        if (strcmp("true", (*ppCurrentNode)->value_raw) == 0) {
            if (json_is_object(*ppAppendJson)) {
                LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                    "%s xmlToJson. boolean object append name:%s, value:true\n",
                    CONVERT_FORMAT_TAG, (*ppCurrentNode)->name_raw);
                jsonResult = json_object_set_new(*ppAppendJson, (*ppCurrentNode)->name_raw,
                    json_true());
            }
            else if (json_is_array(*ppAppendJson)) {
                LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                    "%s xmlToJson. boolean array append name:%s, value:true\n",
                    CONVERT_FORMAT_TAG, (*ppCurrentNode)->name_raw);
                jsonResult = json_array_append_new(*ppAppendJson, json_true());
            }
        }
        else if (strcmp("false", (*ppCurrentNode)->value_raw) == 0) {
            if (json_is_object(*ppAppendJson)) {
                LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                    "%s xmlToJson. boolean object append value:false\n",
                    CONVERT_FORMAT_TAG);
                jsonResult = json_object_set_new(*ppAppendJson, (*ppCurrentNode)->name_raw,
                    json_false());
            }
            else if (json_is_array(*ppAppendJson)) {
                LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                    "%s xmlToJson. boolean array append value:false\n",
                    CONVERT_FORMAT_TAG);
                jsonResult = json_array_append_new(*ppAppendJson, json_false());
            }
        }
        else {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, boolean error.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            return CONVERT_FORMAT_ERROR;
        }
        break;
    case ORIGIN_JSON_NULL:
        pJsonKeyValue = *ppAppendJsonkey;

        if (json_is_object(*ppAppendJson)) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                "%s xmlToJson. null object append name:%s, value:null\n",
                CONVERT_FORMAT_TAG, (*ppCurrentNode)->name_raw);
            jsonResult = json_object_set_new(*ppAppendJson, (*ppCurrentNode)->name_raw,
                json_null());
        }
        else if (json_is_array(*ppAppendJson)) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG,
                "%s xmlToJson. null array append value:null\n",
                CONVERT_FORMAT_TAG);
            jsonResult = json_array_append_new(*ppAppendJson, json_null());
        }
        break;
    default:
        pJsonKeyValue = *ppAppendJsonkey;
        LOG_PRINTF(DBG_CONVERT_FORMAT_INFO, "%s xmlToJson. other pJsonKeyValue:%p\n",
            CONVERT_FORMAT_TAG, pJsonKeyValue);
        if (json_is_object(*ppAppendJson)) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_INFO,
                "%s xmlToJson. other object append name:%s, value:%s\n",
                CONVERT_FORMAT_TAG, (*ppCurrentNode)->name_raw,
                (*ppCurrentNode)->value_raw);
            jsonResult = json_object_set_new(*ppAppendJson, (*ppCurrentNode)->name_raw,
                json_string((*ppCurrentNode)->value_raw));
        }
        else if (json_is_array(*ppAppendJson)) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_INFO,
                "%s xmlToJson. other array append value:%s\n",
                CONVERT_FORMAT_TAG, (*ppCurrentNode)->value_raw);
            jsonResult = json_array_append_new(*ppAppendJson,
                json_string((*ppCurrentNode)->value_raw));
        }
        break;
    }

    if (jsonResult != 0) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
            "%s file: %s, line:%d, xmlToJson. Cannot set JSON.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        return CONVERT_FORMAT_ERROR;
    }

    if ((*ppCurrentNode)->nextNode) {
        pNextNode = (*ppCurrentNode)->nextNode;
        result = xmlToJson(ppRoot, hXml, &pNextNode, parentType, ppAppendJson, &pJsonKeyValue);
        if (result != CONVERT_FORMAT_SUCCESS) {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, xmlToJson. Cannot set JSON.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            return CONVERT_FORMAT_ERROR;
        }
    }

    return CONVERT_FORMAT_SUCCESS;
}

void convertXmlToJson(const char* XmlDocument, char* pFileName)
{
    XML_HANDLE hXml = NULL;
    json_t* pRoot = NULL;
    json_t* pAppendJson = NULL;
    char* pAppendJsonkey = NULL;
    int errorCode = 0;
    int result = 0;

    LOG_PRINTF(DBG_CONVERT_FORMAT_DEBUG, "%s ConvertXmlToJson\n", CONVERT_FORMAT_TAG);

    hXml = XML_CreateXmlObject(XML_LOCAL_STRING, XmlDocument, 0, -1,
        CONV_CP437oseToUtf8String, CONV_Utf8ToCP437oseString, &errorCode);
    if (!hXml) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
            "%s file: %s, line:%d, XML_CreateXmlObject error:%d\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
        goto Exit;
    }

    XML_DumpXmlObject(hXml);

    XML_Node* xmlNode = XML_GetRootNode(hXml, &errorCode);
    if (!xmlNode) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
            "%s file: %s, line:%d, XML_GetRootNode error:%d\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__, errorCode);
        goto Exit;
    }

    origin_json_type currentJsonType = ORIGIN_JSON_OTHER;

    result = getAttributeJsonType(hXml, &xmlNode, &currentJsonType);
    if (result != CONVERT_FORMAT_SUCCESS) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, getAttributeJsonType.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        goto Exit;
    }

    if (currentJsonType == ORIGIN_JSON_OBJECT) {
        pRoot = json_object();
    }
    else if (currentJsonType == ORIGIN_JSON_ARRAY) {
        pRoot = json_array();
    }
    else {
        origin_json_type autoJsonType = ORIGIN_JSON_OTHER;
        analysisJsonType(&xmlNode, &autoJsonType);
        if (autoJsonType == ORIGIN_JSON_OBJECT) {
            pRoot = json_object();
        }
        else if (autoJsonType == ORIGIN_JSON_ARRAY) {
            pRoot = json_array();
        }
        else {
            LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
                "%s file: %s, line:%d, getAttributeJsonType. JSON TYPE ERROR.\n",
                CONVERT_FORMAT_TAG, __FILE__, __LINE__);
            goto Exit;
        }
    }

    if (!pRoot) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, value is NULL.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        goto Exit;
    }

    result = xmlToJson(&pRoot, hXml, &xmlNode, ORIGIN_JSON_INIT,
        &pAppendJson, &pAppendJsonkey);
    if (result != CONVERT_FORMAT_SUCCESS) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, xmlToJson error.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        goto Exit;
    }

    result = jsonAnalysisFromJson(pRoot);
    if (result != CONVERT_FORMAT_SUCCESS) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR,
            "%s file: %s, line:%d, jsonAnalysisFromJson error.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        goto Exit;
    }
    if (pFileName && strlen(pFileName) >= 1 && strlen(pFileName) <= 12) {
        result = json_dump_file(pRoot, pFileName, JSON_ENCODE_ANY | JSON_INDENT(2));
    }
    else {
        LOG_PRINTF(DBG_CONVERT_FORMAT_INFO, "%s File name:XML2JSON.TXT\n", CONVERT_FORMAT_TAG);
        result = json_dump_file(pRoot, "XML2JSON.TXT", JSON_ENCODE_ANY | JSON_INDENT(2));
    }
    if (result != 0) {
        LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s file: %s, line:%d, json_dump_file error.\n",
            CONVERT_FORMAT_TAG, __FILE__, __LINE__);
        goto Exit;
    }
    json_decref(pRoot);
    XML_ReleaseXmlObject(hXml, NULL);

    return;

Exit:
    LOG_PRINTF(DBG_CONVERT_FORMAT_ERROR, "%s [error]Exist.\n", CONVERT_FORMAT_TAG);
    if (pRoot)
        json_decref(pRoot);
    if (hXml)
        XML_ReleaseXmlObject(hXml, NULL);

    return;
}

Note:

For JSON <-> XML conversion, the JSON type is an object or array.

For XML -> JSON conversion, If there is no attribute type = in XML, the type is automatically determined. Also, for convenience, the numerical value is judged by a character string.

JSON typeJSON valueType of automatic judgment
ObjectA JSON object is a dictionary of key-value pairs.Object
ArrayA JSON array is an ordered collection of other JSON values.Object or Array
StringThe JSON string is a UTF-8 string.String
NumberJSON numbers are integer and real values.String
Boolean valueJSON boolean values are true and false values.Boolean
nullJSON null is a null value.null

Regarding the array, it is judged whether it is an array under the following conditions.

  • Use attribute type = "ARRAY"
  • Use <array_value> tag
  • Use multiple tags with the same name in succession

If you want to use a type other than the automatic judgment type, add the attribute type = to the XML.

See also

Last updated: 2022/01/26