I have this json:
{
"treeview":[
{
"text":"blah",
"nodes":[
]
},
{
"text":"blah",
"nodes":[
]
},
{
"text":"blah",
"nodes":[
{
"text":"blah",
"nodes":[
{
"text":"foo",
"nodes":[
// I need to put data in here !!!
]
}
]
}
]
},
{
"text":"blah",
"nodes":[
]
},
{
"text":"foo",
"nodes":[
// Not here !
]
}
]
}
I need to put value on "nodes" element where i'm on level 2 and the "text" equals "foo".
Here's what I've tried so far:
var json = myJson;
// First approach
var selector = (JArray)json.SelectTokens($"$..treeview[?(#.text == 'foo')]");
// Second approach
var selector2 = (JArray)json.SelectToken($"$.treeview[?(#...text == 'foo')]");
selector.Add(new JObject(new JProperty("text", "myValue"));
I don't understand how the "dot" in the query works... I just know that when you type 2 "dot" it browse the entire JSON... Is there a way to query a particular indent level only ?
I figured it out, yes we can specify a level indentation when we want to query a json in text plain, here's how:
var json = myJson;
var selector = (JArray)json.SelectTokens($"$.treeview[*].nodes[*].nodes[(#.text =='foo')].nodes");
selector.Add(new JObject(new JProperty("text", "myValue")));
You can test it here: http://jsonpath.com/
copy past my json sample in the json section and add this in the jsonPath: $.treeview[*].nodes[*].nodes[*].text
That's how you can get the 'foo' value in the desired "level of identation" without specified any index in the arrays, just use this '*' instead of an int
You need to specify the correct path to the "nodes" array. Try this:
JObject json = JObject.Parse("{\"treeview\":[{\"text\":\"blah\",\"nodes\":[]},{\"text\":\"blah\",\"nodes\":[]},{\"text\":\"blah\",\"nodes\":[{\"text\":\"blah\",\"nodes\":[{\"text\":\"foo\",\"nodes\":[]}]}]},{\"text\":\"blah\",\"nodes\":[]},{\"text\":\"foo\",\"nodes\":[]}]}");
JArray array = (JArray)json.SelectToken("treeview[2].nodes[0].nodes[0].nodes");
array.Add(new JObject(new JProperty("text", "myValue")));
It is much easier to work with objects than just plain json text...
using Newtonsoft.Json package...
class Program
{
static void Main(string[] args)
{
var jsonstring = "{\"text\":\"blah\",\"nodes\":[{\"text\":\"foo\", \"nodes\": []}, {\"text\":\"bar\", \"nodes\": []}, {\"text\":\"foo\", \"nodes\": []}]}";
//This is the root node
var firstLevelNodes = JsonConvert.DeserializeObject<Node>(jsonstring);
//All the nodes in the root nodes node collection
var secondLevelNodes = firstLevelNodes.nodes;
//All of the nodes in the collections of the second level nodes
var thirdLevelNodes = secondLevelNodes.SelectMany(sln => sln.nodes);
Console.WriteLine("First Level Nodes: \n" + JsonConvert.SerializeObject(firstLevelNodes).PrettyPrint());
Console.WriteLine();
Console.WriteLine("Second Level Nodes: \n" + JsonConvert.SerializeObject(secondLevelNodes).PrettyPrint());
Console.WriteLine();
Console.WriteLine("Third Level Nodes: \n" + JsonConvert.SerializeObject(thirdLevelNodes).PrettyPrint());
secondLevelNodes.First().nodes = new List<Node> { new Node { text = "new node" , nodes = new List<Node>() } };
Console.WriteLine();
Console.WriteLine("Third Level Nodes (with new node): \n" + JsonConvert.SerializeObject(thirdLevelNodes).PrettyPrint());
Console.ReadLine();
}
}
public static class JSONExtensions
{
public static string PrettyPrint(this string json)
{
dynamic parsedJson = JsonConvert.DeserializeObject(json);
return JsonConvert.SerializeObject(parsedJson, Formatting.Indented);
}
}
[Serializable]
public class Node
{
public string text { get; set; }
public IEnumerable<Node> nodes { get; set; }
}
OUTPUT:
First Level Nodes:
{
"text": "blah",
"nodes": [
{
"text": "foo",
"nodes": []
},
{
"text": "bar",
"nodes": []
},
{
"text": "foo",
"nodes": []
}
]
}
Second Level Nodes:
[
{
"text": "foo",
"nodes": []
},
{
"text": "bar",
"nodes": []
},
{
"text": "foo",
"nodes": []
}
]
Third Level Nodes:
[]
Third Level Nodes (with new node):
[
{
"text": "new node",
"nodes": []
}
]
EDIT:
So if you only wanted the second level nodes that had the text foo just use..
var secondLevelFooNodes = secondLevelNodes.Where(sln=>sln.text == "foo");
//then use these nodes
EDIT2:
Using the your actual JSON object requires a TreeView Class as well...
class Program
{
static void Main(string[] args)
{
var jsonstring = "{\"treeview\":[{\"text\":\"blah\",\"nodes\":[]},{\"text\":\"blah\",\"nodes\":[]},{\"text\":\"blah\",\"nodes\":[{\"text\":\"blah\",\"nodes\":[{\"text\":\"foo\",\"nodes\":[]}]}]},{\"text\":\"blah\",\"nodes\":[]},{\"text\":\"foo\",\"nodes\":[]}]}";
//This is the root node
var treeView = JsonConvert.DeserializeObject<TreeView>(jsonstring);
//All the nodes in the root nodes node collection
var firstLevelNodes = treeView.treeview;
//All of the nodes in the collections of the first level nodes
var secondLevelNodes = firstLevelNodes.SelectMany(fln => fln.nodes);
//All of the nodes in the collections of the second level nodes
var thirdLevelNodes = secondLevelNodes.SelectMany(sln => sln.nodes);
Console.WriteLine("The TreeView: \n" + JsonConvert.SerializeObject(treeView, Formatting.Indented));
thirdLevelNodes.First(sln => sln.text == "foo").nodes = new List<Node> { new Node { text = "new node", nodes = new List<Node>() } };
Console.WriteLine();
Console.WriteLine("The TreeView (with new node): \n" + JsonConvert.SerializeObject(treeView, Formatting.Indented));
Console.ReadLine();
}
}
[Serializable]
public class Node
{
public string text { get; set; }
public IEnumerable<Node> nodes { get; set; }
}
[Serializable]
public class TreeView
{
public IEnumerable<Node> treeview { get; set; }
}
OUTPUT:
The TreeView:
{
"treeview": [
{
"text": "blah",
"nodes": []
},
{
"text": "blah",
"nodes": []
},
{
"text": "blah",
"nodes": [
{
"text": "blah",
"nodes": [
{
"text": "foo",
"nodes": []
}
]
}
]
},
{
"text": "blah",
"nodes": []
},
{
"text": "foo",
"nodes": []
}
]
}
The TreeView (with new node):
{
"treeview": [
{
"text": "blah",
"nodes": []
},
{
"text": "blah",
"nodes": []
},
{
"text": "blah",
"nodes": [
{
"text": "blah",
"nodes": [
{
"text": "foo",
"nodes": [
{
"text": "new node",
"nodes": []
}
]
}
]
}
]
},
{
"text": "blah",
"nodes": []
},
{
"text": "foo",
"nodes": []
}
]
}
Related
I have an array like this coming from API response and I want to filter by nested property products to returns product with only id 11
"assets": [
{
"name": "abc",
"products": [
{
"id": "11",
"status": true
},
{
"id": "14",
"status": null
}
]
},
{
"name": "xyz",
"products": [
{
"id": "11",
"status": true
},
{
"id": "28",
"status": null
}
]
},
{
"name": "123",
"products": [
{
"id": "48",
"status": null
}
]
},
{
"name": "456",
"products": [
{
"id": "11",
"status": true
}
]
}
]
the resulting output should look like this,
"assets": [
{
"name": "abc",
"products": [
{
"id": "11",
"status": true
}
]
},
{
"name": "xyz",
"products": [
{
"id": "11",
"status": true
}
]
},
{
"name": "123",
"products": []
},
{
"name": "456",
"products": [
{
"id": "11",
"status": true
}
]
}
]
I'm trying to return filter output with the C# LINQ method. but, getting an error when filtering a nested array with the following method
"Cannot convert lambda expression to intended delegate type because some of the return types in the block are not implicitly convertible to the delegate return type"
assets.Select(asset => asset.products.Where(product => product.id == "11")).ToArray();
You can just remove all items from every products array, whose id doesn't equal 11. Parse JSON to JObject, iterate over assets array, find products with id different from 11 and remove them form original array
var json = JObject.Parse(jsonString);
foreach (var asset in json["assets"])
{
var productsArray = asset["products"] as JArray;
if (productsArray == null)
continue;
var productsToRemove = productsArray
.Where(o => o?["id"]?.Value<int>() != 11)
.ToList();
foreach (var product in productsToRemove)
productsArray.Remove(product);
}
Console.WriteLine(json);
Instead of Select and Applying a, Where try to remove the Products that you do not want.
Following is a sample code.
class Program
{
static void Main(string[] args)
{
var json = #"
{
'assets': [
{
'name': 'abc',
'products': [
{
'id': '11',
'status': true
},
{
'id': '14',
'status': null
}
]
},
{
'name': 'xyz',
'products': [
{
'id': '11',
'status': true
},
{
'id': '28',
'status': null
}
]
},
{
'name': '123',
'products': [
{
'id': '48',
'status': null
}
]
},
{
'name': '456',
'products': [
{
'id': '11',
'status': true
}
]
}
]}";
var root = JsonConvert.DeserializeObject<Root>(json);
var assets = root.Assets;
assets.ForEach(a =>
{
a.Products.RemoveAll(p => p.Id != 11);
});
}
}
public partial class Root
{
[JsonProperty("assets")]
public List<Asset> Assets { get; set; }
}
public partial class Asset
{
[JsonProperty("name")]
public string Name { get; set; }
[JsonProperty("products")]
public List<Product> Products { get; set; }
}
public partial class Product
{
[JsonProperty("id")]
public long Id { get; set; }
[JsonProperty("status")]
public bool? Status { get; set; }
}
To filter the list, you will need to create a new list with products whose ID == YourId. Following linq query does the necessary steps to create the list you want.
Filter out any assets that dont have any product with ID == 11. This is necessary to skip nulls in the new list that will be generated (Where statement)
Create a collection / list of new assets that only have the products whose ID == 11 (Select statement)
var list = assets.Where(x => x.Products.Where(y => y.Id.Equals("11")).Count() > 0)
.Select(asset => {
return new Asset() {
Name = asset.Name,
Products = asset.Products.Where(x => x.Id == "11").ToList()
};
}).ToList();
// Create the RootObject that holds a list of all the arrays if you want.
Rootobject newAssetCollection = new Rootobject() { Assets = list };
Below is the Json that was printed
Console.WriteLine(JsonConvert.SerializeObject(newAssetCollection, Formatting.Indented));
{
"assets": [
{
"name": "abc",
"products": [
{
"id": "11",
"status": true
}
]
},
{
"name": "xyz",
"products": [
{
"id": "11",
"status": true
}
]
},
{
"name": "456",
"products": [
{
"id": "11",
"status": true
}
]
}
]
}
I've searched high and low for an exact example for how to populate a <select> control with <optgroup>, but I get various results. The documentation on select2.org states that the format should be like this:
{
"results": [
{
"text": "Group 1",
"children" : [
{
"id": 1,
"text": "Option 1.1"
},
{
"id": 2,
"text": "Option 1.2"
}
]
},
{
"text": "Group 2",
"children" : [
{
"id": 3,
"text": "Option 2.1"
},
{
"id": 4,
"text": "Option 2.2"
}
]
}
],
"pagination": {
"more": true
}
}
But my results throw an error stating that the 'ID' field is not present. I think it's due to the way I'm initializing the <select>, but I don't see another way.
First, my data is being pulled from a MS SQL db using a stored procedure. I don't have easy control over the data format, so I'm using Linq to create an object I then initialize the <select> with using .DataBind(). Here is the relevant code:
HTML:
<select id="MySelect" name="myselect" runat="server"></select>
Definitions for Parent and Child:
public class Parent : Child
{
public List<Child> children { get; set; }
}
public class Child
{
public string id { get; set; }
public string text { get; set; }
}
Linq statement:
var parents = myData
.Select(c => new Parent()
{
text = string.Format("{0} {1}", c.first_name, c.last_name),
id = c.ID.ToString(),
children = GetChildren(locations, c)
})
.ToArray();
// Convert to JSON
var json = JsonConvert.SerializeObject(new
{
results = parents
});
Linq result converted to JSON:
{
"results":[
{
"id":"2",
"text":"Parent 1 ",
"children":[
]
},
{
"id":"39",
"text":"Parent 2",
"children":[
{
"text":"Child 2.1",
"id":"62",
"Custom1":"196.00"
},
{
"text":"Child 2.2",
"id":"130",
"Custom1":"642.00"
},
{
"text":"Child 2.2",
"id":"61",
"Custom1":"0.00"
}
]
},
{
"id":"15",
"text":"Parent 3",
"children":[
{
"text":"Child 3.1",
"id":"13",
"Custom1":"40.00"
}
]
}
]
}
DataBind:
MySelect.DataSource = json;
MySelect.DataValueField = "id";
MySelect.DataTextField = "text";
MySelect.DataBind();
After all of this, the MySelect <select> renders with a dropdown containing only the parents and no <optgroup> elements in the actual HTML.
I have tried excluding the 'id' member from the <Parent> class, but then there is an error thrown from the .DataBind() that there is no 'id' even though the children all have ids.
I suspect that using .DataBind() isn't the way to handle this. I want to keep the code clean, short and quick.
How can I accomplish this?
I have DeserializeObject to a C# object however I have objects with dynamic object names so I have structured it like this:
public class RootObject
{
public string name { get; set; }
public TableLayout table{ get; set; }
}
public class TableLayout
{
public Attributes attributes { get; set; } //Static
public Info info { get; set; } //Static
[JsonExtensionData]
public Dictionary<string, JToken> item { get; set; }
}
So basically any dynamic objects that appear will be added to the dictionary and using JsonExtensionData will populate the rest of the property without creating the object classes. Here is my json:
string json = #"
{
"name": "Table 100",
"table": {
"attributes ": {
"id": "attributes",
"type": "attributes"
},
"info": {
"id": "info",
"type": "info"
},
"item-id12": {
"id": "item-id12",
"type": "Row"
"index": 0
},
"item-id16": {
"id": "item-id16",
"type": "Column"
"parentid": "item-id12"
},
"item-id21": {
"id": "item-id21",
"type": "Column",
"parentid": "item-id12"
}
}
}";
How can I use type ="row" and index value(increments to index 1 to evaluate next row) property to get all columns using parentId of column objects in my Dictionary.
Desired Output:
"item-id12": {
"id": "item-id12",
"type": "Row"
"index": 0
},
"item-id16": {
"id": "item-id16",
"type": "Column"
"parentid": "item-id12"
},
"item-id21": {
"id": "item-id21",
"type": "Column",
"parentid": "item-id12"
}
You can use linq to find your root object
var rootNode = json.table.item.Values
.FirstOrDefault(x => x["type"].Value<string>() == "Row" && x["index"].Value<int>() == 0);
if (rootNode == null)
return; // no such item
Now if this item exists use linq again and get all items from dictionary:
var childNodes = json.table.item.Values
.Where(x => x["parentid"]?.Value<string>() == rootNode["id"].Value<string>());
Next code
var output = new[] {rootNode}.Concat(childNodes);
foreach (var item in output)
Console.WriteLine(item);
will print
{
"id": "item-id12",
"type": "Row",
"index": 0
}
{
"id": "item-id16",
"type": "Column",
"parentid": "item-id12"
}
{
"id": "item-id21",
"type": "Column",
"parentid": "item-id12"
}
P.S. Your input json is invalid, it missing few commas
C# | .NET 4.5 | Entity Framework 5
I have data coming back from a SQL Query in the form of ID,ParentID,Name. I'd like to take that data and parse it into a Hierarchical JSON string. So far it seems to be much more of a daunting task than it should be. Since I'm using Entity the data comes back nicely to me as an IEnumerable. Now I believe I just need some form of recursion, but I'm not quite sure where to start. Any help is appreciated.
Data Returns as
id parentId name
1 1 TopLoc
2 1 Loc1
3 1 Loc2
4 2 Loc1A
Code is
public static string GetJsonLocationHierarchy(long locationID)
{
using (EntitiesSettings context = new EntitiesSettings())
{
// IEnumerable of ID,ParentID,Name
context.GetLocationHierarchy(locationID);
}
}
The end result I'd hope would be something like this:
{
"id": "1",
"parentId": "1",
"name": "TopLoc",
"children": [
{
"id": "2",
"parentId": "1",
"name": "Loc1",
"children": [
{
"id": "4",
"parentId": "2",
"name": "Loc1A",
"children": [
{}
]
}
]
},
{
"id": "3",
"parentId": "1",
"name": "Loc2",
"children": [
{}
]
}
]
}
One way to turn a flat table into a hierarchy is to put all your nodes into a dictionary. Then iterate over the dictionary, and for each node, look up its parent and add it to the parent's children. From there, you just need to find the root and serialize it.
Here is an example program to demonstrate the approach:
class Program
{
static void Main(string[] args)
{
IEnumerable<Location> locations = new List<Location>
{
new Location { Id = 1, ParentId = 1, Name = "TopLoc" },
new Location { Id = 2, ParentId = 1, Name = "Loc1" },
new Location { Id = 3, ParentId = 1, Name = "Loc2" },
new Location { Id = 4, ParentId = 2, Name = "Loc1A" },
};
Dictionary<int, Location> dict = locations.ToDictionary(loc => loc.Id);
foreach (Location loc in dict.Values)
{
if (loc.ParentId != loc.Id)
{
Location parent = dict[loc.ParentId];
parent.Children.Add(loc);
}
}
Location root = dict.Values.First(loc => loc.ParentId == loc.Id);
JsonSerializerSettings settings = new JsonSerializerSettings
{
ContractResolver = new CamelCasePropertyNamesContractResolver(),
Formatting = Formatting.Indented
};
string json = JsonConvert.SerializeObject(root, settings);
Console.WriteLine(json);
}
}
class Location
{
public Location()
{
Children = new List<Location>();
}
public int Id { get; set; }
public int ParentId { get; set; }
public string Name { get; set; }
public List<Location> Children { get; set; }
}
Here is the output:
{
"id": 1,
"parentId": 1,
"name": "TopLoc",
"children": [
{
"id": 2,
"parentId": 1,
"name": "Loc1",
"children": [
{
"id": 4,
"parentId": 2,
"name": "Loc1A",
"children": []
}
]
},
{
"id": 3,
"parentId": 1,
"name": "Loc2",
"children": []
}
]
}
I have an umbraco website with the following content structure:
(the text in brackets is the nodeTypeAlias)
[root]
- [child]
| - [module]
| | - [submodule]
| | - [submodule]
- [child]
| - [module]
| - [module]
| | - [submodule]
I am trying to export the above structure (together with the node's properties) into the following json file:
{
"root": {
"child": [
{
"id": "1",
"name": "Child 1",
"module": [
{
"id": "2",
"name": "Module 1",
"submodule": [
{
"id": "3",
"name": "Sub module 1"
},
{
"id": "4",
"name": "Sub module 3"
}
]
}
]
},
{
"id": "5",
"name": "Child 5",
"module": [
{
"id": "8",
"name": "Module 8"
},
{
"id": "6",
"name": "Module 6",
"submodule": [
{
"id": "7",
"name": "Sub module 7"
},
{
"id": "9",
"name": "Sub module 9"
}
]
}
]
}
]
}
}
So far I've wrote down the following code in Linqpad but the result is not the one that I was looking for.
List<Node> brands = new List<Node>()
{
new Node
{
id = 1,
name = "Brand 1",
type = "brand",
children = new List<Node>
{
new Node
{
id = 2,
name = "Shelf 1",
type = "shelf",
children = new List<Node>
{
new Node
{
id = 1,
name = "Bookcase 1",
type = "bookcase"
},
new Node
{
id = 2,
name = "Bookcase 2",
type = "bookcase"
},
new Node
{
id = 3,
name = "Bookcase 3",
type = "bookcase"
}
}
},
new Node
{
id = 3,
name = "Shelf 2",
type = "shelf",
children = new List<Node>
{
new Node
{
id=1,
type= "module",
name = "Module 1"
},
new Node
{
id=2,
type= "pdf",
name = "PDF 1"
},
new Node
{
id=3,
type= "link",
name = "Link 1"
},
new Node
{
id=4,
type= "link",
name = "Link 2"
},
}
}
}
},
new Node
{
id = 2,
name = "Brand 2",
type = "brand",
children = new List<Node>
{
new Node
{
id = 2,
name = "Shelf 1",
type = "shelf",
},
new Node
{
id = 3,
name = "Shelf 2",
type = "shelf",
}
}
}
};
Result container = new Result();
Action<List<Node>, Result> add = null;
add = (nodes, coll) =>
{
List<Result> list = null;
if(nodes != null && nodes.Count > 0)
{
nodes.Dump("nodes");
foreach(var node in nodes)
{
string key = node.type;
list = null;
if(coll.Children.ContainsKey(key))
{
list = coll.Children[key];
}
else
{
list = new List<Result>();
}
Result r = new Result();
r.Name = node.name;
add(node.children, r);
list.Add(r);
coll.Children[key] = list;
coll.Dump("coll");
}
}
};
add(brands, container);
container.Dump();
var serializer = new JavaScriptSerializer();
serializer.Serialize(container).Dump();
}
public class Result
{
public Result()
{
this.Children = new Dictionary<string, List<Result>>();
this.Properties = new Dictionary<string, string>();
}
public string Name {get;set;}
public Dictionary<string, string> Properties {get;set;}
public Dictionary<string, List<Result>> Children {get;set;}
}
public class Node
{
public string name{get;set;}
public string type {get;set;}
public int id {get;set;}
public List<Node> children{get;set;}
result:
{
"Name": null,
"Properties": {},
"Children": {
"brand": [
{
"Name": "Brand 1",
"Properties": {},
"Children": {
"shelf": [
{
"Name": "Shelf 1",
"Properties": {},
"Children": {
"bookcase": [
{
"Name": "Bookcase 1",
"Properties": {},
"Children": {}
},
{
"Name": "Bookcase 2",
"Properties": {},
"Children": {}
},
{
"Name": "Bookcase 3",
"Properties": {},
"Children": {}
}
]
}
},
{
"Name": "Shelf 2",
"Properties": {},
"Children": {
"module": [
{
"Name": "Module 1",
"Properties": {},
"Children": {}
}
],
"pdf": [
{
"Name": "PDF 1",
"Properties": {},
"Children": {}
}
],
"link": [
{
"Name": "Link 1",
"Properties": {},
"Children": {}
},
{
"Name": "Link 2",
"Properties": {},
"Children": {}
}
]
}
}
]
}
},
{
"Name": "Brand 2",
"Properties": {},
"Children": {
"shelf": [
{
"Name": "Shelf 1",
"Properties": {},
"Children": {}
},
{
"Name": "Shelf 2",
"Properties": {},
"Children": {}
}
]
}
}
]
}
}
Any idea?
Thanks.
This is very much the way that you would go about generating XML, but JSON is a little different. If you have updated your Umbraco to one of the later editions, then you use Razor to render JSON in this sort of way:
#{
var builder = new System.Text.StringBuilder();
foreach (var car in cars)
{
builder.Append("{");
builder.Append(Json.Encode("reg") + ":" + Json.Encode(car.Registration) + ",");
builder.Append(Json.Encode("model") + ":" + car.Model);
// INSERT OTHER VALUES HERE
builder.Append("}");
if (car.Registration != cars.Last().Registration)
{
builder.Append(",");
}
count++;
}
}
#Html.Raw(builder.ToString())
Another more interesting way is JSON.NET - a good option if you are using custom objects in your application. You populate your objects, and then pass them through JSON.NET. See here for more details.
Product product = new Product();
product.Name = "Apple";
product.Expiry = new DateTime(2008, 12, 28);
product.Price = 3.99M;
product.Sizes = new string[] { "Small", "Medium", "Large" };
string json = JsonConvert.SerializeObject(product);
//{
// "Name": "Apple",
// "Expiry": "2008-12-28T00:00:00",
// "Price": 3.99,
// "Sizes": [
// "Small",
// "Medium",
// "Large"
// ]
//}
Product deserializedProduct = JsonConvert.DeserializeObject(json);
The beauty of this library is that you can also create strings and convert them to JSON. The only caveat is that you have to watch your JavaScript when trying to read the JSON. Things like single (') and double (") quotes can break your code.
string json = #"{
""Name"": ""Apple"",
""Expiry"": "2008-12-28T00:00:00",
""Price"": 3.99,
""Sizes"": [
""Small"",
""Medium"",
""Large""
]
}";
JObject o = JObject.Parse(json);
string name = (string)o["Name"];
// Apple
JArray sizes = (JArray)o["Sizes"];
string smallest = (string)sizes[0];
// Small
Your code could work if you used the System.Xml namespace (XmlDocument, XmlAttributes, XmlNode). It is unclear as to which Node object you are using but I will assume it is Umbraco's Node (I would work with a new DynamicNode() instead btw) and in which case you cannot just create them like that with populated properties. You have to create one in the Umbraco database before reading its values.
Hopefully this should give you something to go on with. Happy coding.