c++实现Xml和json互转
2016-06-28 10:55
459 查看
1、下载c语言的cJson库源码,库很小,只有两个文件cJSON.c和cJSON.h。下载地址:https://sourceforge.net/projects/cjson/
2、c++实现Xml和json互转
2.1、头文件
2.2、xml转json
2.3、json转xml
2、c++实现Xml和json互转
2.1、头文件
#include "XmlJsonTransfer.h" //#include "cmsDebug.h" #include "WebSocket/src/cJSON.h" #include <stdlib.h> #include <string.h> #include <stdio.h> #include <assert.h> #include <time.h> #include <iostream> using namespace std;
2.2、xml转json
// 依赖cJSon,递归 /* <doc><a a1="1" a2="2">123</a></doc> 转 {"doc": {"a": {"-a1": "1","-a2": "2","#text": "123"}}} */ string Xml2Json(string strXml) { string pNext = strXml; cJSON * reJson = cJSON_CreateObject(); cJSON * jsonArray = cJSON_CreateArray(); string strArrayKey = ""; int nPos = 0; while ((nPos = pNext.find("<")) >= 0) { // 获取第一个节点,如:<doc><a a1="1" a2="2">123</a></doc> int nPosS = pNext.find("<"); int nPosE = pNext.find(">"); if (nPosS < 0 || nPosE < 0) { printf("key error!"); } string strKey = pNext.substr(nPosS+1, nPosE-nPosS-1); // 解释属性,如:<a a1="1" a2="2"> cJSON * jsonVal = NULL; if ((nPos = strKey.find("=")) > 0) { jsonVal = cJSON_CreateObject(); int nPos = strKey.find(" "); string temp = strKey.substr(nPos+1); strKey = strKey.substr(0, nPos); while((nPos = temp.find("=")) > 0) { int nPos1 = temp.find("="); int nPos2 = temp.find("\" ", nPos1 + 1); string strSubKey = temp.substr(0, nPos1); string strSubVal = temp.substr(nPos1+1); if (nPos2 > 0) strSubVal = temp.substr(nPos1+1, nPos2-nPos1-1); // 去除转义字符 \" if ((int)(nPos = strSubVal.find("\"")) >= 0) { int nEnd = strSubVal.find("\\", nPos+1); strSubVal = strSubVal.substr(nPos+1, nEnd-nPos-1); } cJSON_AddItemToObject(jsonVal, ("-" + strSubKey).c_str(), cJSON_CreateString(strSubVal.c_str())); if (nPos2 < 0) break; temp = temp.substr(nPos2+2); } } int nPosKeyE = pNext.find("</" + strKey + ">"); if (nPosKeyE < 0) { printf("key error!"); } // 获取节点内容,如<a a1="1" a2="2">123</a> 或 123 string strVal = pNext.substr(nPosE+1, nPosKeyE-nPosE-1); if ((nPos = strVal.find("<")) >= 0) { // 包含子节点,如<a a1="1" a2="2">123</a> strVal = Xml2Json(strVal); if (jsonVal) { if (strVal != "") cJSON_AddItemToObject(jsonVal, "#text", cJSON_Parse(strVal.c_str())); } else { jsonVal = cJSON_Parse(strVal.c_str()); } } else { // 不包含子节点,如123 if (jsonVal) { if (strVal != "") cJSON_AddItemToObject(jsonVal, "#text", cJSON_CreateString(strVal.c_str())); } else { jsonVal = cJSON_CreateString(strVal.c_str()); } } // 获取下一个节点 pNext = pNext.substr(nPosKeyE + strKey.size() + 3); // 根据下一节点判断是否为数组 int nPosNext = pNext.find("<"); int nPosNextSame = pNext.find("<" + strKey + ">"); if (strArrayKey != "" || (nPosNext>=0 && nPosNextSame>=0 && nPosNext==nPosNextSame)) { // 数组 cJSON_AddItemToArray(jsonArray, jsonVal); strArrayKey = strKey; } else { // 非数组 cJSON_AddItemToObject(reJson, strKey.c_str(), jsonVal); } } if (strArrayKey != "") { cJSON_AddItemToObject(reJson, strArrayKey.c_str(), jsonArray); } string strJson = cJSON_Print(reJson); if(reJson) { cJSON_Delete(reJson); reJson = NULL; } return strJson; }
2.3、json转xml
// 依赖cJSon,递归 /* {"doc": {"a": {"-a1": "1","-a2": "2","#text": "123"}}} 转 <doc><a a1="1" a2="2">123</a></doc> */ string Json2Xml(string strJson) { string strXml = ""; cJSON *root = cJSON_Parse(strJson.c_str()); if (!root) { printf("strJson error!"); return ""; } cJSON *pNext = root->child; if (!pNext) { return strJson; } int nPos = 0; while (pNext) { string strChild = cJSON_Print(pNext); string strVal = Json2Xml(strChild); if (pNext->string != NULL) { string strKey = pNext->string; if ((nPos=strKey.find("-")) == 0) { // 属性项 strXml.append(" "); strXml.append(strKey.substr(1)); strXml.append("="); strXml.append(strVal); if (pNext->next == NULL) strXml.append(">"); } else if ((nPos=strKey.find("#")) == 0) { // 值 strXml.append(">"); strXml.append(strVal); } else if ((int)(strVal.find("=")) > 0 /*&& (int)(strVal.find("<")) < 0*/) { // 包含属性项的键值对 strXml.append("<" + strKey); strXml.append(strVal); strXml.append("</" + strKey + ">"); } else { // 修正底层无键的值数组的键,如:把<JUAN_XJ_preKey>123</JUAN_XJ_preKey>中的JUAN_XJ_preKey修正 if ((int)strVal.find("JUAN_XJ_preKey") >= 0) { replace_all(strVal, "JUAN_XJ_preKey", strKey); strXml.append(strVal); } else { strXml.append("<" + strKey + ">"); strXml.append(strVal); strXml.append("</" + strKey + ">"); } } } else { // 不包含键的值数组, 如:["123", "456"],暂时转为<JUAN_XJ_preKey>123</JUAN_XJ_preKey> string strPreKey = "JUAN_XJ_preKey"; strXml.append("<" + strPreKey + ">"); strXml.append(strVal); strXml.append("</" + strPreKey + ">"); } pNext = pNext->next; } return strXml; }2.4、辅助函数
// 替换字符串 string& replace_all(string& str, const string& old_value, const string& new_value) { while(true) { string::size_type pos(0); if((pos=str.find(old_value)) != string::npos) str.replace(pos,old_value.length(),new_value); else break; } return str; }
相关文章推荐
- 使用C++实现JNI接口需要注意的事项
- 关于指针的一些事情
- 使用 Python 处理 JSON 格式的数据
- XML 与 JSON 优劣对比
- c++ primer 第五版 笔记前言
- share_ptr的几个注意点
- VBA将excel数据表生成JSON文件
- As3.0 xml + Loader应用代码
- 网马生成器 MS Internet Explorer XML Parsing Buffer Overflow Exploit (vista) 0day
- ext读取两种结构的xml的代码
- 实例解析Ruby程序中调用REXML来解析XML格式数据的用法
- Ruby中XML格式数据处理库REXML的使用方法指南
- newtonsoft.json解析天气数据出错解决方法
- Lua中调用C++函数示例
- Lua教程(一):在C++中嵌入Lua脚本
- C#中如何使用 XmlReader 读取XML文件
- C#针对xml基本操作及保存配置文件应用实例
- Ruby使用REXML库来解析xml格式数据的方法