JSON<->XML変換 サンプルプログラムです。

 本サンプルでは、下記を実行することができます。

  • JSON文字列を解析し、XMLに変換する。その後、ファイルに保存する。
  • XMLドキュメントを解析し、JSON文字列に変換する。その後、ファイルに保存する。

 本サンプルに使用するには、次のライブラリをアプリケーションプログラムにリンクとインクルード・ファイル・ディレクトリーにディレクトリーを追加してください。

ヘッダファイル:
lib.h : システム18.0以降
jansson.h
jansson_config.h
jansson_log.h
XML.h
CodeConversion.h : ver.1.1.1以降
ライブラリファイル:
libJansson.a
libXML.a
libCodeConversion.a : ver.1.1.1以降
libSTARTUPOPH5000.a : システム18.0以降

(注意)

 ライブラリファイルの追加を行うときは上記の順番に合わせてリンクしてください。

    インクルード・ファイル・ディレクトリーを追加するときは次の手順でプロジェクトを変更してください。
    1. e² studioの[プロジェクト・エクスプローラー]ビューでプロジェクトを選択し、[プロジェクト]メニューの[プロパティ]をクリックして[プロパティ]画面を表示します。

    2. [C/C++ ビルド]→[設定]→[ツール設定]→[Compiler: ソース]→[ ボタン]の順にクリックします。

    3. [インクルード・ファイル・ディレクトリー]画面が表示されたら、[ディレクトリー]のフィールドに、次の書式でディレクトリーを入力し、[OK]をクリックします。

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


    4. [OK]をクリックして[プロパティ]画面を閉じます。

sampleConvertJsonToXml()

 次のJSON文字列を解析し、XMLに変換します。その後、ファイルに保存します。

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()

 次のXMLドキュメントを解析し、JSON文字列に変換します。その後、ファイルに保存します。

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>


サンプル: 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
          }
        }
     */
}

サンプル: 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_ */

サンプル: 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_Utf8ToSjisString(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_Utf8ToSjisString(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_Utf8ToSjisString((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_SjisToUtf8String((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_SjisToUtf8String, CONV_Utf8ToSjisString, &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_SjisToUtf8String, CONV_Utf8ToSjisString, &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;
}

(注意)

 JSON<->XML変換に関しては、JSON型がオブジェクト or 配列が対象です。

 XML->JSON変換に関しては、XMLに属性のtype=がない場合は、自動で型を決めています。また、利便性を考慮して、数値は文字列で判定しています。

JSON型JSON値自動判定の型
オブジェクトJSONオブジェクトは、キーと値のペアの辞書です。オブジェクト
配列JSON配列は、他のJSON値の順序付けられたコレクションです。オブジェクト or 配列
文字列JSON文字列は、UTF-8の文字列です。文字列
数値JSON数値は、整数と実数の値です。文字列
ブール値JSONブール値は、true, falseの値です。ブール値
nullJSON nullは、null値です。null

 配列に関しては、下記条件で配列かどうか判定しています。

  • 属性のtype="ARRAY"を使う
  • <array_value>のタグを使う
  • 同じ名前のタグを複数以上続けて使用する

 自動判定の型以外を使用したい場合は、XMLに属性のtype=を追加してください。

関連事項

最終更新日:2022/01/26