c++实现Xml和json互转

1、下载c语言的cJson库源码,库很小,只有两个文件cJSON.c和cJSON.h。下载地址:https://sourceforge.net/projects/cjson/

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;     
} 




  • 0
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
可以使用第三方库,比如RapidJSON。以下是一个示例: ```c++ #include "rapidjson/document.h" #include "rapidjson/writer.h" #include "rapidjson/stringbuffer.h" #include "rapidxml/rapidxml.hpp" #include "rapidxml/rapidxml_print.hpp" #include <iostream> #include <fstream> using namespace rapidjson; int main() { // 读取JSON文件 std::ifstream ifs("example.json"); std::string content((std::istreambuf_iterator<char>(ifs)), (std::istreambuf_iterator<char>())); // 解析JSON Document d; d.Parse(content.c_str()); // 创建XML文档 rapidxml::xml_document<> doc; // 创建根节点 rapidxml::xml_node<> *root = doc.allocate_node(rapidxml::node_element, "root"); doc.append_node(root); // 将JSON换为XML for (Value::ConstMemberIterator itr = d.MemberBegin(); itr != d.MemberEnd(); ++itr) { rapidxml::xml_node<> *node = doc.allocate_node(rapidxml::node_element, itr->name.GetString()); root->append_node(node); if (itr->value.IsObject()) { for (Value::ConstMemberIterator itr2 = itr->value.MemberBegin(); itr2 != itr->value.MemberEnd(); ++itr2) { rapidxml::xml_node<> *sub_node = doc.allocate_node(rapidxml::node_element, itr2->name.GetString()); sub_node->value(doc.allocate_string(itr2->value.GetString())); node->append_node(sub_node); } } else if (itr->value.IsArray()) { for (Value::ConstValueIterator itr2 = itr->value.Begin(); itr2 != itr->value.End(); ++itr2) { rapidxml::xml_node<> *sub_node = doc.allocate_node(rapidxml::node_element, "item"); sub_node->value(doc.allocate_string(itr2->GetString())); node->append_node(sub_node); } } else { node->value(doc.allocate_string(itr->value.GetString())); } } // 输出XML std::string result; rapidxml::print(std::back_inserter(result), doc, 0); std::cout << result << std::endl; return 0; } ``` 注意,代码中使用了RapidJSON和RapidXML两个库,需要先安装它们。
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值