我正在尝试将嵌套的Json数组字符串转换为dataTable。我的代码工作正常,创建了精细的数据表。但现在客户需求发生了变化,我正在努力寻找出路来获得以下结构。
要求是每当Json Value是一个数组时,数据应该作为单独的行。
非常感谢任何帮助!!
示例JSON结构:
{" A":" A0" ," B" :{" B2" :" B2- Val"," B3" :[{" B30" :" B30 - Val1" " B31" :" B31 - Val1"}]}," C":[" C0"," C1"]}
当前DataTable输出结构:
必需的DataTable结构:
原始C#代码:
public DataTable JsonStringToDataTable(string jsonString)
{
LoggingUtil.LogMessage("GetReceiver :: JsonStringToDataTable :: Enters", LogLevel.Debug);
DataTable dt = new DataTable();
List<string> lstColumnName = new List<string>();
List<string> lstRowData = new List<string>();
try
{
lstColumnName = ConvertJsonToList(jsonString, false);
foreach (string AddColumnName in lstColumnName)
{
DataColumnCollection columns = dt.Columns;
string colName = AddColumnName.ToLower();
if (!columns.Contains(colName))
{
dt.Columns.Add(colName);
}
}
lstRowData = ConvertJsonToList(jsonString, true);
DataRow nr = dt.NewRow();
for (int i = 0; i < lstRowData.Count; i++)
{
try
{
string RowColumns = lstColumnName[i];
string RowDataString = lstRowData[i];
nr[RowColumns] = RowDataString;
}
catch (Exception ex)
{
//continue;
throw ex;
}
}
dt.Rows.Add(nr);
}
catch (Exception ex)
{
LoggingUtil.LogMessage("GetReceiver :: JsonStringToDataTable :: Error while creating datatable from JSON string :: " + ex.Message, LogLevel.Debug);
throw ex;
}
finally
{
LoggingUtil.LogMessage("GetReceiver :: JsonStringToDataTable :: Exits", LogLevel.Debug);
}
return dt;
}
public static List<string> ConvertJsonToList(string jsonString, bool isValue)
{
LoggingUtil.LogMessage("GetReceiver :: ConvertJsonToList :: Enters", LogLevel.Debug);
DataTable dt = new DataTable();
var jObj = JObject.Parse(jsonString);
List<string> lstData = new List<string>();
try
{
if (isValue)
{
lstData = AddJsonObjects(jObj, "JSON", lstData, true, false);
}
else
{
lstData = AddJsonObjects(jObj, "JSON", lstData, false, false);
}
}
catch (Exception ex)
{
LoggingUtil.LogMessage("GetReceiver :: ConvertJsonToList :: Error :: " + ex.Message, LogLevel.Debug);
throw ex;
}
finally
{
LoggingUtil.LogMessage("GetReceiver :: ConvertJsonToList :: Exits", LogLevel.Debug);
}
return lstData;
}
public static List<string> AddJsonObjects(JObject jObj, string name, List<string> ColumnsName, bool isValue, bool isArrayObject)
{
foreach (var property in jObj.Properties())
{
string strName = name + "." + property.Name;
if (isArrayObject && !isValue)
{
ColumnsName = AddTokenValues(property.Value, strName, ColumnsName, isValue, true);
}
else
{
ColumnsName = AddTokenValues(property.Value, property.Name, ColumnsName, isValue, false);
}
}
return ColumnsName;
}
public static List<string> AddTokenValues(JToken token, string name, List<string> ColumnsName, bool isValue, bool isArrayObject)
{
if (token is JValue)
{
if (isValue)
{
string value = string.Empty;
if (token.Type != JTokenType.Null)
{
value = ((JValue)token).Value.ToString();
}
ColumnsName.Add(value);
}
else
{
ColumnsName.Add(name);
}
}
else if (token is JArray)
{
ColumnsName = AddArrayValues((JArray)token, name, ColumnsName, isValue);
}
else if (token is JObject)
{
ColumnsName = AddJsonObjects((JObject)token, name, ColumnsName, isValue, true);
}
return ColumnsName;
}
public static List<string> AddArrayValues(JArray array, string name, List<string> dataList, bool isValue)
{
for (var i = 0; i < array.Count; i++)
{
dataList = AddTokenValues(array[i], string.Format("[{0}]", name + "[" + i.ToString() + "]"), dataList, isValue, true);
}
return dataList;
}
答案 0 :(得分:1)
这里你去 - 它不漂亮,需要进一步测试和清理(例如对类中的单独关注并摆脱那些全局变量!)但它会为你提供你所追求的东西。将下面的代码粘贴到新的控制台应用程序中(粘贴Program.cs的内容)并添加System.Web.Extensions作为参考。
祝你好运!using System;
using System.Collections.Generic;
using System.Data;
using System.Web.Script.Serialization;
namespace ConsoleApplication1
{
class Program
{
private static DataTable dt;
private static Dictionary<string, int> columnRowManager;
static void Main(string[] args)
{
//var json = "[{'firstName':'John', 'lastName':'Doe'},{'firstName':'Anna', 'lastName':'Smith'},{'firstName':'Peter','lastName': 'Jones'} ]";
//var json = "{ 'glossary': { 'title': 'example glossary','GlossDiv': { 'title': 'S','GlossList': { 'GlossEntry': { 'ID': 'SGML','SortAs': 'SGML','GlossTerm': 'Standard Generalized Markup Language','Acronym': 'SGML','Abbrev': 'ISO 8879:1986','GlossDef': { 'para': 'A meta-markup language, used to create markup languages such as DocBook.','GlossSeeAlso': ['GML', 'XML'] },'GlossSee': 'markup' } } } } }";
var json = "{ 'A': 'A0' , 'B' : { 'B2' : 'B2 - Val', 'B3' : [{'B30' : 'B30 - Val1' ,'B31' : 'B31 - Val1'}]}, 'C': ['C0', 'C1']}";
var jss = new JavaScriptSerializer();
dt = new DataTable();
columnRowManager = new Dictionary<string, int>();
try
{
// Deal with an object root
var dict = jss.Deserialize<Dictionary<string, object>>(json);
GetColumnsAndRowsFromJsonDictionary(dict);
}
catch (InvalidOperationException ioX)
{
// Deal with an Array Root
var dictionaries = jss.Deserialize<Dictionary<string, object>[]>(json);
foreach (var dict in dictionaries)
{
GetColumnsAndRowsFromJsonDictionary(dict);
}
}
DumpTableToConsole();
}
private static void DumpTableToConsole()
{
WriteColumnsToConsole();
WriteRowsToConsole();
Console.ReadKey();
}
private static void WriteRowsToConsole()
{
// Write out the Rows
foreach (DataRow row in dt.Rows)
{
foreach (DataColumn col in dt.Columns)
{
Console.Write(row[col.ColumnName].ToString().PadRight(12) + ",");
}
Console.WriteLine();
}
}
private static void WriteColumnsToConsole()
{
foreach (DataColumn col in dt.Columns)
{
Console.Write(col.ColumnName.PadRight(12) + ",");
}
Console.WriteLine();
Console.WriteLine("-------------------------------------------------------------------------------");
}
private static void AddDataToTable(string column, string cellValue)
{
AddColumnIfNew(column);
int targetRowPosition = DetermineTargetRow(column);
AddRowIfRequired(targetRowPosition);
dt.Rows[targetRowPosition - 1][column] = cellValue;
}
private static void AddRowIfRequired(int targetRowPosition)
{
if (dt.Rows.Count < targetRowPosition)
{
dt.Rows.Add();
}
}
private static int DetermineTargetRow(string column)
{
int targetRowPosition;
columnRowManager.TryGetValue(column, out targetRowPosition);
targetRowPosition++;
columnRowManager[column] = targetRowPosition;
return targetRowPosition;
}
private static void AddColumnIfNew(string column)
{
if (!dt.Columns.Contains(column))
{
dt.Columns.Add(new DataColumn(column, typeof(String)));
columnRowManager.Add(column, 0);
}
}
private static void GetColumnsAndRowsFromJsonDictionary(Dictionary<string, object> dictionary)
{
// Catch the curse of recursion - null is your friend (enemy!)
if (dictionary == null) return;
foreach (var kvp in dictionary)
{
if (kvp.Value.GetType() == typeof(Dictionary<string, object>))
{
// Process an embedded dictionary (hierarchy)
var subDictionary = kvp.Value as Dictionary<string, object>;
GetColumnsAndRowsFromJsonDictionary(subDictionary);
}
else if (kvp.Value.GetType() == typeof(System.Collections.ArrayList))
{
ProcessArrayList(kvp);
}
else if (kvp.Value.GetType() == typeof(String))
{
AddDataToTable(kvp.Key, kvp.Value.ToString());
}
else
{
throw new NotSupportedException(string.Format("Err2: Type '{0}' not supported", kvp.Value.GetType().ToString()));
}
}
}
private static void ProcessArrayList(KeyValuePair<string, object> kvp)
{
// Process each independant item in the array list
foreach (var arrItem in kvp.Value as System.Collections.ArrayList)
{
if (arrItem.GetType() == typeof(String))
{
AddDataToTable(kvp.Key, arrItem.ToString());
}
else if (arrItem.GetType() == typeof(Dictionary<string, object>))
{
var subArrDictionary = arrItem as Dictionary<string, object>;
GetColumnsAndRowsFromJsonDictionary(subArrDictionary);
}
else
{
throw new NotSupportedException(string.Format("Err1: Type '{0}' not supported", arrItem.GetType().ToString()));
}
}
}
}
}