ChoETL json to csv with multiple arrays - c#

If I have a sample json like this and I want to use choETL to convert json to csv, how do i write both arrays to one file?
{
"Id": "123456",
"Request": [
{
"firstName": "A",
"lastName": "B",
}
],
"Response": [
{
"SId": "123"
}
]
}
Csv file should be something like
Id,firstName,lastName,SId
123456,A,B,123

Here is how you can produce the expected CSV from the json by using ChoETL
using (var r = ChoJSONReader.LoadText(json)
.WithField("Id")
.WithField("firstName", jsonPath:"Request[0].firstName", isArray:false)
.WithField("lastName", jsonPath:"Request[0].lastName", isArray:false)
.WithField("SId", jsonPath:"Response[0].SId", isArray:false)
)
{
using (var w = new ChoCSVWriter(Console.Out).WithFirstLineHeader())
w.Write(r);
}
Output:
Id,firstName,lastName,SId
123456,A,B,123
Sample fiddle: https://dotnetfiddle.net/CnBX3C
UPDATE:
If the array is dynamic, here is one way to produce the CSV output by Request json array field
Sample JSON:
{
"Id": "123456",
"Request": [
{
"firstName": "A",
"lastName": "B",
},
{
"firstName": "A1",
"lastName": "B1",
}
],
"Response": [
{
"SId": "123"
},
{
"SId": "1234"
}
]
}
Here is the code to parse the json by Request json array field
using (var r = ChoJSONReader.LoadText(json)
.Configure(c => c.FlattenNode = true).Configure(c => c.FlattenByNodeName = "Request")
)
{
using (var w = new ChoCSVWriter(Console.Out).WithFirstLineHeader())
w.Write(r);
}
Output:
Id,Response_0_SId,Response_1_SId,RequestfirstName,RequestlastName
123456,123,1234,A,B
123456,123,1234,A1,B
Sample fiddle: https://dotnetfiddle.net/CnBX3C

Related

Find all Id's in json object

I have a long tree json document, here is the part of it
"childs": [
{
"id": "id1",
"name": "name1",
"childs": []
},
{
"id": "id2",
"name": "name21",
"childs": [
{
"id": "id3",
"name": "name123124",
"childs": [
{
"id": "id4",
"name": "namewe1231",
"childs": [
{
"id": "id5",
"name": "name123123",
"childs": [
{
"id": "id5",
`
i need to save all id from this document for local storage like:
id1
id2
id3
id4 etc...
is it even possible? JObject and dynamic variable didnt help me.
heres code i've been trying to compile but it returned me just first id from tree
`
string source = File.ReadAllText(jsonModelPath);
dynamic data = JObject.Parse(source);
File.WriteAllText(path, data.id);
`
you can try something like this
string[] ids = JObject.Parse(json)
.Descendants()
.OfType<JProperty>()
.Where(a => a.Name == "id")
.Select(a => a.Value.ToString())
.ToArray();
or you can put all ids in one line
string strIds = string.Join(" ",ids);
or each id in the new line
string strIds = string.Join("\n",ids);
and save
File.WriteAllText(path, strIds);

How can I search a JSON file in C# by a key value, and then obtain a subsequent key + value?

I have 3 JSON files that all contain the same data structure, however different data.
The structure for all 3 files is as follows:
{
"TokenId": "0",
"rank": "2804"
},
{
"TokenId": "1",
"rank": "977"
},
{
"TokenId": "2",
"rank": "4085"
}
I am trying to create a new JSON file from these 3 files that has the following structure, and yes, they all have the same tokenID values, but slightly different rank values:
{
"TokenId": "0",
"File1Rank": "2804",
"File2Rank": "2802",
"File3Rank": "2809"
},
{
"TokenId": "1",
"File1Rank": "977",
"File2Rank": "983",
"File3Rank": "999"
},
{
"TokenId": "2",
"File1Rank": "4085",
"File2Rank": "4089",
"File3Rank": "4100"
}
How can I search by the tokenId value in each file to obtain the rank value? I can iterate through each valuea in each file to get both values, but I am struggling to create or update the new JSON correctly. The logic I feel I need is if the TokenId is equal to a certain value, then add the rank key/value, but I have not been able to find the answer on how I can do this.
You can use the newtonsoft json library to parse and update the json files.
If your source file structure is:
{
"Tokens": [
{
"TokenId": "0",
"rank": "2804"
},
{
"TokenId": "1",
"rank": "977"
},
{
"TokenId": "2",
"rank": "4085"
}
]
}
Pseudo code:
using Newtonsoft.Json
using Newtonsoft.Json.Linq
void Main()
{
dynamic objFinal = JObject.Parse("{ 'Tokens':[] }");
JArray finalArray = (JArray)objFinal["Tokens"];
DirectoryInfo dir = new DirectoryInfo(#"D:\Projects\JsonFiles\");
foreach(var file in dir.GetFiles("*.json"))
{
dynamic objJson = JObject.Parse(File.ReadAllText(file.FullName));
JArray tokens = (JArray)objJson["Tokens"];
foreach(JToken token in tokens)
{
JToken searchResult = finalArray.Where(t=> Convert.ToString(t["TokenId"])==Convert.ToString(token["TokenId"])).FirstOrDefault();
if(searchResult==null)
{
//push new tokenid
JArray newFileRanks = new JArray();
newFileRanks.Add(token["rank"]);
dynamic newToken = new JObject();
newToken["TokenId"] = token["TokenId"];
newToken["fileRanks"] = newFileRanks;
finalArray.Add(newToken);
}
else
{
//append to fileRanks
JArray existingFileRanks = (JArray)searchResult["fileRanks"];
dynamic fileRankExists = existingFileRanks.Where(t=> Convert.ToString(t)==Convert.ToString(token["rank"])).FirstOrDefault();
if(fileRankExists==null)
{
existingFileRanks.Add(token["rank"]);
}
}
}
}
Console.Write(JsonConvert.SerializeObject(objFinal));
}
Final output:
{
"Tokens": [
{
"TokenId": "0",
"fileRanks": [ "2804", "2801" ]
},
{
"TokenId": "1",
"fileRanks": [ "977", "972" ]
},
{
"TokenId": "2",
"fileRanks": [ "4085", "4083" ]
}
]
}

How to get all value of particular key in JSON?

I have a JSON structure that contains different levels. How to iterate the JSON and get all values of a particular key in JSON in C#
Below is my JSON file
{
"name": "EPM Company",
"id": "kpfwzgmhpm",
"type": "root",
"childern": [
{
"cid": "67",
"cname": "cname1",
"childern": [
{
"reading": [
{
"id": 121,
"name": "test1"
},
{
"id": 1121,
"name": "test11"
}
]
}
]
},
{
"cid": "454",
"cname": "cname14",
"childern": [
{
"reading": [
{
"id": 454,
"name": "test14"
},
{
"id": 21,
"name": "test141"
}
]
}
]
}
]
}
This is the JSON format. I am trying to get the value in the below format.
{
"name": "EPM Company",
"id": "kpfwzgmhpm",
"value": [
{
"id": 121,
"name": "test1",
"cid": "67",
"cname": "cname1"
},
{
"id": 1121,
"name": "test11",
"cid": "67",
"cname": "cname1"
},
{
"id": 124234,
"cname": "test12342",
"cid": "67",
"name": "cname1"
},
{
"id": 454,
"name": "test14",
"cid": "454",
"cname": "cname14"
},
{
"id": 21,
"name": "test141",
"cid": "454",
"cname": "cname14"
},
{
"id": 121,
"name": "test123122",
"cid": "454",
"cname": "cname14"
}
]
}
fetching all the reading key and its value-added to array with its cid and came. is it possible?
advanced thanks for the help
my code in c# is
public string SensorList(string entireData)
{
if (string.IsNullOrEmpty(entireData))
{
return string.Empty;
}
var returnObj = new Jobject ();
JObject o = JObject.Parse(entireData);
var childern = o["children"];
returnObj.Add("name" = o ["name"];
returnObj.Add("id" = o ["id"];
returnObj.Add("value" = o ["value"];
var valuearry = new JArray();
foreach(var data in childern)
{
foreach(var reading in data["reading"])
{
var valobj = new Jobject ();
valobj.Add( "cid",data["id"])
valobj.Add( "cname",data["name"])
valobj.Add( "name",reading["id"])
valobj.Add( "id",reading["name"])
valuearry.add()
if(data.containsKey("children"))
{
var sensorInfo = SensorList(data["children"]);
}
}
returnObj.Add("value",valuearry);
// var output = sensorInfo.SelectMany(x => ((JObject)x).Properties().Select(y => new JObject {
// new JProperty("id",y.Name),
// new JProperty("name",y.Value["name"])
// })).ToList();
// var returnArray = new JArray(output);
return returnObj.ToString();
}
}
recurring part is not working and take too much time for other long JSON file

Filtering JArray

How to query in JArray?
I have JArray as follow:
"data": [
{
"type": "A",
"serverTime": "2020-08-14T12:49:18.893+07:00"
},
{
"type": "A",
"serverTime": "2020-08-14T12:50:08.021+07:00"
},
{
"serverTime": "2020-08-14T12:50:08.021+07:00",
"type": "C",
}
I expect to get a new JArray that already filtered by type = A
please help
string jsonString = "{'data':[{'type':'A','serverTime':'2020-08-14T12:49:18.893+07:00'},{'type':'A','serverTime':'2020-08-14T12:50:08.021+07:00'},{'type':'C','serverTime':'2020-08-14T12:50:08.021+07:00'}]}";
////Note: You must convert to JObject
var jsonObject = JObject.Parse(jsonString);
var getArray = jsonObject["data"].Where(p => p["type"].ToString() == "A");
OR
JArray exampleArray = JArray.Parse(#"[
{""type"": ""A"", ""serverTime"": ""2020-08-14T12:49:18.893+07:00""},
{""type"": ""A"", ""serverTime"": ""2020-08-14T12:50:08.021+07:00""},
{""type"": ""C"", ""serverTime"": ""2020-08-14T12:50:08.021+07:00""}
]");
var result = exampleArray.Where(x => x["type"]?.ToString() == "A");
Your json format is wrong,
The right one
{
"data": [
{
"type": "A",
"serverTime": "2020-08-14T12:49:18.893+07:00"
},
{
"type": "A",
"serverTime": "2020-08-14T12:50:08.021+07:00"
},
{
"type": "C",
"serverTime": "2020-08-14T12:50:08.021+07:00"
}
]
}

JSON Enum list deserialization

I have JSON Like below
{
"_id": "0FEB6D4B-8DA5-4143-B926-11A7AE4F3B12",
"device": {
"name": "test",
"family": "test"
},
"channels": [
{
"mcl": 33,
"vtype": "FLOAT",
"category": " Current"
},
{
"tag": "OperationMode",
"vtype": "BYTE",
"enums": [
{
"0": "Off"
},
{
"1": "On"
},
{
"2": "ByPass"
}
]
}
]
}
I am using Json.net to deserialize the JSON to C# object. I am not able to manage to convert the enum list. I validated if this is valid JSON. I tried with custom converter & string converter but reader value is null. Any quick help appreciated.
JObject jR = JObject.Parse(YourJsonString);
JArray oR = (JArray)jR["channels"];
JArray jA = (JArray)oR[1]["enums"];
foreach (var item in jA)
{
Dictionary<string,string> enums = Newtonsoft.Json.JsonConvert.DeserializeObject<Dictionary<string,string>>(item.ToString());
foreach (var en in enums)
{
Console.WriteLine(en.Value);
}
}
Fiddler: https://dotnetfiddle.net/ziSep1

Categories