clarifying my question, I would like to use JToken.SelectTokens Method (String) from Namespace: Newtonsoft.Json.Linq. How can I use method SelectTokens("") to get number of children for every node "174637"(unit_id) and "174638"(unit_id) ?. For first node I'm supposed to get 1 and for second 2.
I've tried like this:
foreach (var test in unit_ids) { //takes every unit_id, one by one
var children_of_unit_id = test.SelectTokens("*.[*]").count();
}
But It gives me nothing.
"174637": {
"1": {
"value_symbol": "3",
"exam_session_number": 1,
"exam_id": 207983,
"value_description": {
"en": "satisfactory",
}
}
}
"174638": {
"1": {
"value_symbol": "3",
"exam_session_number": 1,
"exam_id": 207984,
"value_description": {
"en": "satisfactory",
}
}
"2": {
"value_symbol": "3",
"exam_session_number": 2,
"exam_id": 207985,
"value_description": {
"en": "satisfactory",
}
}
}
EDITED
This is original Json:
{
"grades": {
"course_units_grades": {
"173565": {
"1": {
"value_symbol": "3,5",
"exam_session_number": 1,
"exam_id": 208798,
"value_description": {
"en": "satisfactory plus",
"pl": "dst+"
}
}
},
"173566": {
"1": {
"value_symbol": "2",
"exam_session_number": 1,
"exam_id": 208797,
"value_description": {
"en": "unsatisfactory",
}
},
"2": {
"value_symbol": "3",
"exam_session_number": 2,
"exam_id": 208797,
"value_description": {
"en": "satisfactory",
}
}
}
},
"course_grades": {}
}
}
So It looks like this:
foreach (var t in json_grade)//take every "grades" element, one by one
{
var test = t.SelectTokens("['grades'].['course_units_grades']");
foreach (var unit_ids in test)
{
foreach (var test in unit_ids) { //takes every unit_id, one by one
var children_of_unit_id = test.SelectTokens("*.[*]").count();
}
}
}
You can try one of these 2 ways :
foreach (var test in unit_ids)
{
var approach1 = test.Children().Children().Count();
var approach2 = test.First.SelectTokens("*").Count();
}
Dotnetfiddle Demo
Try this:
var token = JToken.Parse(j)["unit_id"][0].ToList().Count;
Sample JSON:
{
"174637": [
{
"1": {
"value_symbol": "3",
"exam_session_number": "1",
"exam_id": "207983",
"value_description": {
"en": "value_description"
}
}
}
],
"174638": [
{
"1": {
"value_symbol": "3",
"exam_session_number": "1",
"exam_id": "207983",
"value_description": {
"en": "value_description"
}
},
"2": {
"value_symbol": "3",
"exam_session_number": "1",
"exam_id": "207983",
"value_description": {
"en": "value_description"
}
}
}
]
}
Related
I have json text like this:
{
"course_editions": {
"2014/SL": [
{
"grades": {
"course_units_grades": {
"159715": {
"1": {
"value_symbol": "4",
"exam_session_number": 1,
"exam_id": 198172,
"value_description": {
"en": "good",
}
}
}
},
"course_grades": {}
}
},
{
"grades": {
"course_units_grades": {
"159796": {
"1": {
"value_symbol": "5",
"exam_session_number": 1,
"exam_id": 198259,
"value_description": {
"en": "very good",
}
}
}
},
"course_grades": {}
}
},
I would like to use JToken.SelectTokens Method from Namespace: Newtonsoft.Json.Linq
I've tried like this:
string json_response = GetResponse(sign(url_courses));
var courses_tokens = JObject.Parse(json_response).SelectTokens("['course_editions'].['2014/SL'].[*].['grades'].*")
It doesn't work. I would like to get only these numbers after course_unit_grades and before "1". So in this example only: "159715" and "159796" to be able to use all of them, one by one in
foreach(var lp in courses_tokens) {
}
This is one possible way :
var jobj = JObject.Parse(json);
var coursesTokens = jobj.SelectTokens("course_editions.2014/SL[*].grades.course_units_grades")
.Select(o => o.First) //get the first child of `course_units_grades`
.Cast<JProperty>() //cast to JProperty
.Select(o => o.Name); //get the name of the property
foreach (string coursesToken in coursesTokens)
{
Console.WriteLine(coursesToken);
}
Dotnetfiddle Demo
given json sample at the bottom, the output is as follow :
159715
159796
json sample :
var json = #"{
'course_editions': {
'2014/SL': [
{
'grades': {
'course_units_grades': {
'159715': {
'1': {
'value_symbol': '4',
'exam_session_number': 1,
'exam_id': 198172,
'value_description': {
'en': 'good'
}
}
}
},
'course_grades': {}
}
},
{
'grades': {
'course_units_grades': {
'159796': {
'1': {
'value_symbol': '5',
'exam_session_number': 1,
'exam_id': 198259,
'value_description': {
'en': 'very good'
}
}
}
},
'course_grades': {}
}
}
]
}
}";
Given 2 JSON strings:
[
{
"id":"BA",
"description":"BrandA",
"values":[
{
"id":"CategoryA",
"description":"CategoryA"
},
{
"id":"CategoryB",
"description":"CategoryB"
},
{
"id":"CategoryC",
"description":"CategoryC"
},
{
"id":"CategoryD",
"description":"CategoryD"
},
{
"id":"CategoryE",
"description":"CategoryE"
},
{
"id":"CategoryF",
"description":"CategoryF"
},
{
"id":"CategoryG",
"description":"CategoryG"
},
{
"id":"CategoryH",
"description":"CategoryH"
}
]
},
{
"id":"BB",
"description":"BrandB",
"values":[
{
"id":"CategoryA",
"description":"CategoryA"
},
{
"id":"CategoryB",
"description":"CategoryB"
},
{
"id":"CategoryC",
"description":"CategoryC"
}
]
}
]
AND
[
{
"id":"BA",
"description":"BrandA",
"values":[
{
"id":"CategoryA",
"description":"CategoryA"
},
{
"id":"CategoryC",
"description":"CategoryC"
}
]
},
{
"id":"BB",
"description":"BrandB",
"values":[
{
"id":"CategoryB",
"description":"CategoryB"
}
]
}
]
First one is the original. The second are the values that I want to remove from the original. So basically, if there is a match on brand and category between first and second JSON, regardless of the order of the elements, I want that match to be removed.
The expected result would be someting like this:
[
{
"id":"BA",
"description":"BrandA",
"values":[
{
"id":"CategoryB",
"description":"CategoryB"
},
{
"id":"CategoryD",
"description":"CategoryD"
},
{
"id":"CategoryE",
"description":"CategoryE"
},
{
"id":"CategoryF",
"description":"CategoryF"
},
{
"id":"CategoryG",
"description":"CategoryG"
},
{
"id":"CategoryH",
"description":"CategoryH"
}
]
},
{
"id":"BB",
"description":"BrandB",
"values":[
{
"id":"CategoryA",
"description":"CategoryA"
},
{
"id":"CategoryC",
"description":"CategoryC"
}
]
}
]
Catagory A and C in Brand A were removed as well as Category B in Brand B.
Based in some research, I was using https://github.com/wbish/jsondiffpatch.net, tried to work with it's functions, but so far I didn't manage to achieve the result I want. Also, to solve this by processing JSON direcly is not a must. If there is a simpler solution to achieve that by converting them to lists and use something like LINQ for example, it works for me as well (tried that, but didn't manage to find a way to do this comparison).
Thanks in advance.
If performance does not matter, the JsonSerializer and LINQ can be used:
Model
public class JsonModel
{
public class ValueModel
{
public string Id { get; set; }
public string Description { get; set; }
}
public string Id { get; set; }
public string Description { get; set; }
public IEnumerable<ValueModel> Values { get; set; }
}
Deserialize and LINQ
string json1Str = #"[...]";
string json2Str = #"[...]";
var opt = new System.Text.Json.JsonSerializerOptions { PropertyNameCaseInsensitive = true };
var json1 = System.Text.Json.JsonSerializer.Deserialize<List<JsonModel>>(json1Str, opt);
var json2 = System.Text.Json.JsonSerializer.Deserialize<List<JsonModel>>(json2Str, opt);
var result = json1.
Join(json2, j1 => j1.Id, j2 => j2.Id, (j1, j2) => new JsonModel
{
Id = j1.Id,
Description = j1.Description,
Values = j1.Values.Where(j1 => !j2.Values.Select(val => val.Id).Contains(j1.Id))
});
Console.WriteLine(System.Text.Json.JsonSerializer.Serialize(result, new System.Text.Json.JsonSerializerOptions { WriteIndented = true }));
}
Result
[
{
"Id": "BA",
"Description": "BrandA",
"Values": [
{
"Id": "CategoryB",
"Description": "CategoryB"
},
{
"Id": "CategoryD",
"Description": "CategoryD"
},
{
"Id": "CategoryE",
"Description": "CategoryE"
},
{
"Id": "CategoryF",
"Description": "CategoryF"
},
{
"Id": "CategoryG",
"Description": "CategoryG"
},
{
"Id": "CategoryH",
"Description": "CategoryH"
}
]
},
{
"Id": "BB",
"Description": "BrandB",
"Values": [
{
"Id": "CategoryA",
"Description": "CategoryA"
},
{
"Id": "CategoryC",
"Description": "CategoryC"
}
]
}
]
I am using the Nest SDK to produce queries to Elasticsearch and am confused by what appears to be invalid JSON getting accepted by the Elasticsearch server.
My Query generation code is as follows:
protected SearchRequest testSearchRequest()
{
QueryContainer MyFilter = new QueryContainer();
List<string> strings = new List<string>() { "a", "b", "c", "d", "e" };
foreach (string s in strings)
{
MyFilter = MyFilter || new TermQuery { Field = s, Value = "value_" + s };
}
return new SearchRequest("index-1,index-2")
{
From = 0,
Size = 10,
Query = new TermQuery { Field = "test", Value = "testvalue" } && MyFilter
};
}
I am debugging the Request in two ways as I thought it might have been a problem getting the request data, both the DebugInformation property on the Search Result and the result.ApiCall.RequestBodyInBytes value show the same result:
{
"from": 0,
"query": {
"bool": {
"must": [
{
"term": {
"test": {
"value": "testvalue"
}
},
{
"bool": {
"should": [
{
"term": {
"a": {
"value": "value_a"
}
},
{
"term": {
"b": {
"value": "value_b"
}
},
{
"term": {
"c": {
"value": "value_c"
}
},
{
"term": {
"d": {
"value": "value_d"
}
},
{
"term": {
"e": {
"value": "value_e"
}
}
]
}
]
},
"size": 10
}
}
It seems to me that the Terms generated by my loop are incorrectly being parsed with extra square brackets and invalid braces?
What is strange is that I get a HealthyResponse from Elasticsearch.
If I try using this string in the Kibana console it states that this is an invalid request.
Here is my JSON file that my C# WinForm application will need to access. Based on your account name (Windows AD Login), you will have access to specific files from the application.
Based on the suggestions of other developers, I was encouraged to use Newtonsoft.Json
My question is how do I get the values for the key "file"
[
{
"accountName": "admin.lastname",
"files": [
{
"file": "department1.assistant.division.manager.js"
},
{
"file": "department1.division.manager.js"
},
{
"file": "department2.assistant.division.manager.1.js"
},
{
"file": "department2.assistant.division.manager.2.js"
},
{
"file": "department2.division.manager.js"
},
{
"file": "department3.js"
},
{
"file": "department4.assistant.division.manager.1.js"
},
{
"file": "department4.assistant.division.manager.2.js"
},
{
"file": "department4.division.manager.js"
},
{
"file": "department5.assistant.division.manager.1.js"
},
{
"file": "department5.division.manager.js"
},
{
"file": "department6.division.manager.js"
},
{
"file": "department7.division.manager.js"
},
{
"file": "department8.division.manager.js"
},
{
"file": "department9.division.manager.js"
},
{
"file": "department10.js"
},
{
"file": "department11.division.manager.js"
},
{
"file": "department12.assistant.division.manager.1.js"
},
{
"file": "department12.assistant.division.manager.2.js"
},
{
"file": "department12.assistant.division.manager.3.js"
},
{
"file": "department12.assistant.division.manager.4.js"
},
{
"file": "department12.division.manager.js"
},
{
"file": "department13.js"
}
]
},
{
"accountName": "firstname.lastname",
"files": [
{
"file": "department1.assistant.division.manager.js"
},
{
"file": "department1.division.manager.js"
},
{
"file": "department2.assistant.division.manager.1.js"
},
{
"file": "department2.assistant.division.manager.2.js"
},
{
"file": "department2.division.manager.js"
},
{
"file": "department3.js"
},
{
"file": "department4.assistant.division.manager.1.js"
},
{
"file": "department4.assistant.division.manager.2.js"
},
{
"file": "department4.division.manager.js"
},
{
"file": "department5.assistant.division.manager.1.js"
},
{
"file": "department5.division.manager.js"
},
{
"file": "department6.division.manager.js"
},
{
"file": "department7.division.manager.js"
},
{
"file": "department8.division.manager.js"
},
{
"file": "department9.division.manager.js"
},
{
"file": "department10.js"
},
{
"file": "department11.division.manager.js"
},
{
"file": "department12.assistant.division.manager.1.js"
},
{
"file": "department12.assistant.division.manager.2.js"
},
{
"file": "department12.assistant.division.manager.3.js"
},
{
"file": "department12.assistant.division.manager.4.js"
},
{
"file": "department12.division.manager.js"
},
{
"file": "department13.js"
}
]
},
{
"accountName": "jason.bourne",
"files": [
{
"file": "department1.assistant.division.manager.js"
},
{
"file": "department1.division.manager.js"
},
{
"file": "department2.assistant.division.manager.1.js"
},
{
"file": "department2.assistant.division.manager.2.js"
},
{
"file": "department2.division.manager.js"
},
{
"file": "department3.js"
},
{
"file": "department4.assistant.division.manager.1.js"
},
{
"file": "department4.assistant.division.manager.2.js"
},
{
"file": "department4.division.manager.js"
},
{
"file": "department5.assistant.division.manager.1.js"
},
{
"file": "department5.division.manager.js"
},
{
"file": "department6.division.manager.js"
},
{
"file": "department7.division.manager.js"
},
{
"file": "department8.division.manager.js"
},
{
"file": "department9.division.manager.js"
},
{
"file": "department10.js"
},
{
"file": "department11.division.manager.js"
},
{
"file": "department12.assistant.division.manager.1.js"
},
{
"file": "department12.assistant.division.manager.2.js"
},
{
"file": "department12.assistant.division.manager.3.js"
},
{
"file": "department12.assistant.division.manager.4.js"
},
{
"file": "department12.division.manager.js"
},
{
"file": "department13.js"
}
]
},
{
"accountName": "admin.bourne",
"files": [
{
"file": "department1.assistant.division.manager.js"
},
{
"file": "department1.division.manager.js"
},
{
"file": "department2.assistant.division.manager.1.js"
},
{
"file": "department2.assistant.division.manager.2.js"
},
{
"file": "department2.division.manager.js"
},
{
"file": "department3.js"
},
{
"file": "department4.assistant.division.manager.1.js"
},
{
"file": "department4.assistant.division.manager.2.js"
},
{
"file": "department4.division.manager.js"
},
{
"file": "department5.assistant.division.manager.1.js"
},
{
"file": "department5.division.manager.js"
},
{
"file": "department6.division.manager.js"
},
{
"file": "department7.division.manager.js"
},
{
"file": "department8.division.manager.js"
},
{
"file": "department9.division.manager.js"
},
{
"file": "department10.js"
},
{
"file": "department11.division.manager.js"
},
{
"file": "department12.assistant.division.manager.1.js"
},
{
"file": "department12.assistant.division.manager.2.js"
},
{
"file": "department12.assistant.division.manager.3.js"
},
{
"file": "department12.assistant.division.manager.4.js"
},
{
"file": "department12.division.manager.js"
},
{
"file": "department13.js"
}
]
}
]
Here is my C# code and what I tried so far but I am stuck
public void loadAccessControl(String fileName)
{
var locationInformation = System.Environment.CurrentDirectory + Path.DirectorySeparatorChar + fileName;
using (StreamReader file = File.OpenText(locationInformation))
using (JsonTextReader reader = new JsonTextReader(file))
{
JArray o = (JArray)JToken.ReadFrom(reader);
items = o;
MessageBox.Show(items.ToString());
}
foreach (var item in items.Children())
{
var itemProperties = item.Children<JProperty>();
var myElement = itemProperties.FirstOrDefault(x => x.Name == "accountName");
var myElementValue = myElement.Value; ////This is a JValue type
if (myElementValue.ToString().Contains(Environment.UserName))
{
MessageBox.Show("Authorized");
authorizedAccess = true;
myElement = itemProperties.FirstOrDefault(x => x.Name == "files");
myElementValue = myElement.Value; ////This is a JValue type
break;
}
}
}
As I said before, I am new to using Newtonsoft's library so if there is a better way, please let me know.
Get from Newtonsoft.Json from NuGet.
Add class File.cs:
using Newtonsoft.Json;
namespace Accounts
{
class File
{
[JsonProperty("file")]
public string Filename { get; set; }
}
}
Add class Account.cs:
using Newtonsoft.Json;
using System.Collections.Generic;
namespace Accounts
{
class Account
{
[JsonProperty("accountName")]
public string AccountName { get; set; }
[JsonProperty("files")]
public List<File> Files { get; set; }
}
}
Add class Program.cs:
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace Accounts
{
class Program
{
static void Main(string[] args)
{
const string filename = "accounts.json";
List<Account> accounts = JsonConvert.DeserializeObject<List<Account>>(System.IO.File.ReadAllText(filename));
foreach (Account account in accounts)
{
Console.WriteLine(account.AccountName);
foreach (File file in account.Files)
{
Console.WriteLine(file.Filename);
}
Console.WriteLine();
}
}
}
}
You can use either of these options:
Creating custom Models
public class Account
{
public string AccountName { get; set; }
public List<FileItem> Files { get; set; }
}
public class FileItem
{
public string File { get; set; }
}
And then use:
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<List<Account>>(jsonText);
Without Creating Custom Models
var result = Newtonsoft.Json.JsonConvert.DeserializeObject<JArray>(jsonText)
.Select(a => new
{
Account = a.Value<string>("accountName"),
Files = a.Value<JArray>("files")
.Select(f => new { File = f.Value<string>("file") }).ToList()
}).ToList();
Try the bellow code to deserialize object graph. then you can query the data easily
public class AccessControlFile
{
public string file { get; set; }
}
public class RootObject
{
public string accountName { get; set; }
public List<AccessControlFile> files { get; set; }
}
class Program
{
static void Main(string[] args)
{
var jsonString = ""; // load from remote service or from a local file
var obj = JsonConvert.DeserializeObject<List<RootObject>>(jsonString);
}
}
I have json text like this:
{
"course_editions": {
"2014/SL": [
{
"grades": {
"course_units_grades": {
"159715": {
"1": {
"value_symbol": "4",
"exam_session_number": 1,
"exam_id": 198172,
"value_description": {
"en": "good",
}
}
}
},
"course_grades": {}
}
},
{
"grades": {
"course_units_grades": {
"159796": {
"1": {
"value_symbol": "5",
"exam_session_number": 1,
"exam_id": 198259,
"value_description": {
"en": "very good",
}
}
}
},
"course_grades": {}
}
},
I would like to use JToken.SelectTokens Method from Namespace: Newtonsoft.Json.Linq
I've tried like this:
string json_response = GetResponse(sign(url_courses));
var courses_tokens = JObject.Parse(json_response).SelectTokens("['course_editions'].['2014/SL'].[*].['grades'].*")
It doesn't work. I would like to get only these numbers after course_unit_grades and before "1". So in this example only: "159715" and "159796" to be able to use all of them, one by one in
foreach(var lp in courses_tokens) {
}
This is one possible way :
var jobj = JObject.Parse(json);
var coursesTokens = jobj.SelectTokens("course_editions.2014/SL[*].grades.course_units_grades")
.Select(o => o.First) //get the first child of `course_units_grades`
.Cast<JProperty>() //cast to JProperty
.Select(o => o.Name); //get the name of the property
foreach (string coursesToken in coursesTokens)
{
Console.WriteLine(coursesToken);
}
Dotnetfiddle Demo
given json sample at the bottom, the output is as follow :
159715
159796
json sample :
var json = #"{
'course_editions': {
'2014/SL': [
{
'grades': {
'course_units_grades': {
'159715': {
'1': {
'value_symbol': '4',
'exam_session_number': 1,
'exam_id': 198172,
'value_description': {
'en': 'good'
}
}
}
},
'course_grades': {}
}
},
{
'grades': {
'course_units_grades': {
'159796': {
'1': {
'value_symbol': '5',
'exam_session_number': 1,
'exam_id': 198259,
'value_description': {
'en': 'very good'
}
}
}
},
'course_grades': {}
}
}
]
}
}";