概述
1、下载c语言的cJson库源码,库很小,只有两个文件cJSON.c和cJSON.h。下载地址:https://sourceforge.net/projects/cjson/
2、c++实现Xml和json互转
//#include "cmsDebug.h"
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <assert.h>
#include <time.h>
#include <iostream>
#include "cJSON.h"
using namespace std;
// 替换字符串
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;
}
// 依赖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("head key error!(nPosS:%d, nPosE:%d)n", nPosS, nPosE);
}
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);
if ((int)(nPos = strSubVal.find(""")) >= 0)
{
strSubVal = strSubVal.substr(0, nPos);
}
}
cJSON_AddItemToObject(jsonVal, ("-" + strSubKey).c_str(), cJSON_CreateString(strSubVal.c_str()));
if (nPos2 < 0)
break;
temp = temp.substr(nPos2+2);
}
}
//尾标签"</strKey>"
int nPosKeyE = pNext.find("</" + strKey + ">");
if (nPosKeyE < 0)
{
printf("strKey:%sn", strKey.c_str());
printf("nPosKeyE error(%d)!n", nPosKeyE);
printf("pNext:%sn", pNext.c_str());
return "";
}
// 获取节点内容,如<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;
}
// 依赖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;
}
int main (int argc, const char * argv[])
{
/*
<doc><a a1="1" a2="2">123</a></doc> 转 {"doc": {"a": {"-a1": "1","-a2": "2","#text": "123"}}}
*/
//string strXml = "<create_task_v id="ff80808166a666da0166cd48a5057a68" name="漏洞扫描_2018111111917"><forbid_interval></forbid_interval><target><name>-33033135</name><hosts>192.168.28.13</hosts><exclude_hosts></exclude_hosts></target><preferences><preference><scanner_name>task_priority</scanner_name><value>1</value></preference></preferences></create_task_v>";
//string strXml = "<doc><a a1="1" a2="2">123</a></doc>";
string strXml = "<create_task_v id="ff80808166a666da0166cd48a5057a68" name="漏洞扫描_2018111111917"><forbid_interval></forbid_interval><target><name>-33033135</name><hosts>192.168.28.13</hosts><exclude_hosts></exclude_hosts></target><preferences><preference><scanner_name>task_priority</scanner_name><value>1</value></preference><preference><scanner_name>guess_time</scanner_name><value>1200</value></preference><preference><scanner_name>max_hosts</scanner_name><value>100</value></preference><preference><scanner_name>max_checks</scanner_name><value></value></preference><preference><scanner_name>scan_span</scanner_name><value></value></preference><preference><scanner_name>scan_mode_os</scanner_name><value>yes</value></preference><preference><scanner_name>scan_notify</scanner_name><value>no</value></preference><preference><scanner_name>scan_notify_text</scanner_name><value></value></preference><preference><scanner_name>Services[entry]:Network read/write timeout :</scanner_name><value>1</value></preference><preference><scanner_name>Services[entry]:Network connection timeout :</scanner_name><value>2</value></preference><preference><scanner_name>Services[entry]:Network read/write timeout :</scanner_name><value>2</value></preference><preference><scanner_name>scan_mode_domain</scanner_name><value>no</value></preference><preference><scanner_name>plugins_timeout</scanner_name><value>40</value></preference><preference><scanner_name>scan_scanAfterNetConn</scanner_name><value>0</value></preference><preference><scanner_name>dependable</scanner_name><value>0</value></preference></preferences><source_iface></source_iface><host_live><mode>1</mode><port_range></port_range></host_live><port_scan><mode>1</mode><mode_inuse>0</mode_inuse><method>5</method><isr>1</isr><udp_scan>0</udp_scan><port_range_inuse>1</port_range_inuse><port_range>1-65535</port_range></port_scan><policy_id>4028fe023121e14a013146c535dd6cc7</policy_id><oid_list>8800103;103997;900239</oid_list><common_param><param><type>PARAM_TYPE_CGI</type><name>cgi_useproxyserver_addr</name><value></value></param><param><type>PARAM_TYPE_CGI</type><name>cgi_enableproxyserver</name><value>0</value></param><param><type>PARAM_TYPE_CGI</type><name>cgi_cgipath</name><value>/cgi-bin</value></param><param><type>PARAM_TYPE_CGI</type><name>cgi_httpport</name><value>80,8080,8888</value></param><param><type>PARAM_TYPE_CGI</type><name>cgi_enableusehead</name><value>false</value></param><param><type>PARAM_TYPE_CGI</type><name>cgi_enableuseget</name><value>true</value></param><param><type>PARAM_TYPE_CGI</type><name>cgi_useproxyserver_port</name><value>8000</value></param><param><type>PARAM_TYPE_BACKDOOR</type><name>backdoor_userporttable</name><value>20034,21554,6776,27374,1243,5780,5880,8011,12349,23432,7511,5418,5277,54320,31337,54321</value></param><param><type>PARAM_TYPE_BACKDOOR</type><name>backdoor_enableuserporttable</name><value>true</value></param><param><type>PARAM_TYPE_BACKDOOR</type><name>backdoor_enableapplyportscanresult</name><value>false</value></param></common_param><databaseset><param><type>PARAM_TYPE_DB2</type><name>db2_username</name><value>db2admin</value></param><param><type>PARAM_TYPE_DB2</type><name>db2_password</name><value>test1234</value></param><param><type>PARAM_TYPE_DB2</type><name>db2_port</name><value>50000</value></param><param><type>PARAM_TYPE_DB2</type><name>db2_DBname</name><value>DWCTRLDB</value></param><param><type>PARAM_TYPE_ORACLE</type><name>oracle_username</name><value>sys</value></param><param><type>PARAM_TYPE_ORACLE</type><name>oracle_password</name><value>manager</value></param><param><type>PARAM_TYPE_ORACLE</type><name>oracle_port</name><value>1521</value></param><param><type>PARAM_TYPE_ORACLE</type><name>oracle_DBname</name><value>orcl</value></param><param><type>PARAM_TYPE_SYBASE</type><name>sybase_username</name><value>sa</value></param><param><type>PARAM_TYPE_SYBASE</type><name>sybase_password</name><value>test1234</value></param><param><type>PARAM_TYPE_SYBASE</type><name>sybase_port</name><value>5000</value></param><param><type>PARAM_TYPE_SYBASE</type><name>sybase_DBname</name><value>master</value></param><param><type>PARAM_TYPE_MSSQL</type><name>mssql_username</name><value>sa</value></param><param><type>PARAM_TYPE_MSSQL</type><name>mssql_password</name><value>test1234</value></param><param><type>PARAM_TYPE_MSSQL</type><name>mssql_port</name><value>1433</value></param><param><type>PARAM_TYPE_MYSQL</type><name>mysql_username</name><value>root</value></param><param><type>PARAM_TYPE_MYSQL</type><name>mysql_password</name><value>test1234</value></param><param><type>PARAM_TYPE_MYSQL</type><name>mysql_port</name><value>3306</value></param><param><type>PARAM_TYPE_MYSQL</type><name>mysql_DBname</name><value>mysql</value></param></databaseset><passwordguess></passwordguess></create_task_v>";
printf("strXml:%sn", strXml.c_str());
string strJson = Xml2Json(strXml);
printf("strJson:%sn", strJson.c_str());
/*
{"doc": {"a": {"-a1": "1","-a2": "2","#text": "123"}}} 转 <doc><a a1="1" a2="2">123</a></doc>
*/
//string stringJson = "{"doc": {"a": {"-a1": "1","-a2": "2","#text": "123"}}}";
string stringJson = "{"create_task_v": {"name": "0170322174646","id": "ff8080815af054de015af56977390013","target": {"name": "776782979","hosts": "192.168.28.23","exclude_hosts": "ddd"}}}";
string stringXml = Json2Xml(stringJson);
printf("stringXml:%sn", stringXml.c_str());
return 0;
}
最后
以上就是眯眯眼八宝粥为你收集整理的c++实现Xml和json互转【转】的全部内容,希望文章能够帮你解决c++实现Xml和json互转【转】所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复