Reading json with a key in unity 3d - c#

Iam making a dictionary game in unity 3d. And i have a json file about all the definitions and examples of all vocabulary.Each word has key is the word it self ( which i highlighted). how can i get the value of each word(key). I have created an oject for json.
for example: i have a word "a cappella" it give me back:
a cappella
1: adverb
definition :without musical accompaniment
example : they performed a cappella
2 :adjective
definition :sung without instrumental accompaniment
example : they sang an a cappella Mass.
many thanks
Here is the model I use for the JSON
public class VocabularyModel : MonoBehavior
{
public string Word { get; set; }
public string WordId {get; set; }
public Meaning[] Meanings { get; set; }
public Label[] Labels { get; set; }
}
json String
{
"a cappella": {
"word": "a cappella",
"wordset_id": "5feb6f679a",
"meanings": [
{
"id": "492099d426",
"def": "without musical accompaniment",
"example": "they performed a cappella",
"speech_part": "adverb"
},
{
"id": "0bf8d49e2e",
"def": "sung without instrumental accompaniment",
"example": "they sang an a cappella Mass",
"speech_part": "adjective"
}
]
},
"AD": {
"word": "AD",
"wordset_id": "76c6ebfae9",
"meanings": [
{
"id": "4c21c72afa",
"def": "in the Christian era",
"speech_part": "adverb",
"synonyms": [
"A.D.",
"anno Domini"
]
}
]
},
"A.D.": {
"word": "A.D.",
"wordset_id": "b7e9d406a0",
"meanings": [
{
"id": "a7482f3e30",
"def": "in the Christian era",
"speech_part": "adverb",
"synonyms": [
"AD"
]
}
]
}
}

Are you using a library or you wrote the code yourself?
In the second case, I'd suggest to use Json.NET from Newtonsoft.
You can deserialize the JSON to a JObject and then treat it as if it was a dictionary.
To do this, you can structure your JSON in the following way:
{
"a_cappella" : {
"word" : "a cappella",
"wordId" : "123",
"meanings" : {...},
"labels" : {...}
}
"building" : {
"word" : "building",
"wordId" : "124",
"meanings" : {...},
"labels" : {...}
}
}
Then you deserialize into a JObject and search what you need:
var json = // here is your json string
var dictionary = JsonConvert.DeserializeObject(json);
if (dictionary.ContainsKey("a_cappella")){
return dictionary["a_cappella"].ToObject<VocabularyModel>();
}

Related

How to deserialize a json array with multiple data types?

I now need to deserialize a JSON that looks like this:
{
"arguments": {
"game": [
"--username",
"--version",
"--assetsDir",
{
"rules": [
{
"action": "allow",
"features": {
"is_demo_user": true
}
}
],
"value": "--demo"
},
{
"rules": [
{
"action": "allow",
"features": {
"has_custom_resolution": true
}
}
],
"value": [
"--width",
"--height"
]
}
]
}
}
As you can see, the array named "game" has both "value" and "object" in it. (But the fact is WORSE than this example, the number of elements is NOT certain)
And the data type of arguments.game[*].value is NOT certain, too.
I used to use classes to describe it, but deserialization failed.
Can't seem to describe an array with multiple element types with a class?
I am using Json.NET. Is there any way to deserialize this "game" array.
Thanks.
Is it a requirement to deserialize to an instance of a class? You could use an ExpandoObject:
using System.Dynamic;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
Console.WriteLine("Hello, World!");
string json = #"{
""arguments"": {
""game"": [
""--username"",
""--version"",
""--assetsDir"",
{
""rules"": [
{
""action"": ""allow"",
""features"": {
""is_demo_user"": true
}
}
],
""value"": ""--demo""
},
{
""rules"": [
{
""action"": ""allow"",
""features"": {
""has_custom_resolution"": true
}
}
],
""value"": [
""--width"",
""--height""
]
}
]
}
}";
var expConverter = new ExpandoObjectConverter();
dynamic obj = JsonConvert.DeserializeObject<ExpandoObject>(json, expConverter);
The obj variable will contain the result of the JSON conversion, then you can traverse the dynamic object in code.
For example, to get a list of strings under 'game':
IList<object> list = new List<object>(obj.arguments.game);
foreach (object str in list)
{
if (str as string != null)
{
Console.WriteLine(str as string);
}
}

How do I get info from an object with an array of objects in a json for Unity?

I have a JSON file setup as such
{
"cards": [
{
"id": "sand_bags",
"type": "Structure",
"name": "Sand Bags",
"values": [
{
"civilian": 1,
"fiend": -1
}
],
"effectTexts": [
{
"civilian": "Add +1 to your BUNKER.",
"fiend": "Send any CIVILIAN'S +1 STRUCTURE to the SCRAPYARD."
}
],
"flavorTexts": [
{
"civilian": "They're just heavy bags with sand. Not much else to say, but they'll slow down an attack from a fiend. Good luck, you'll need it!",
"fiend": "You've spotted a pretty bad STRUCTURE in this BUNKER. Time to do some damage."
}
],
"staysOnField": [
{
"civilian": true,
"fiend": false
}
],
"amountInDeck": 5
}
]
}
I also have a Cards script
[Serializable]
public class Cards
{
public Card[] cards;
}
[Serializable]
public class Card
{
public string id;
public string type;
public string name;
public int amountInDeck;
}
public class Values
{
public int civilian;
public int fiend;
}
I then have a CardEffects script that I'm using for my functions.
public class CardEffects : MonoBehaviour
{
public TextAsset jsonFile;
public Values values;
void Start()
{
Cards cardsInJson = JsonUtility.FromJson<Cards>(jsonFile.text);
foreach (Card card in cardsInJson.cards)
{
Debug.Log("Card name: " + card.name + " with " + values.civilian + " in the deck.");
}
}
}
I have searched all over trying to figure out how to even get the array of objects of "values". I got this far and the value printed is always 0 regardless of the information in "values" in the JSON. If I make the class Serializable, I'm able to change the values and it works but I want the values to be whatever they were declared as in the JSON. Is there a better way to do this?
Please keep in mind I'm new to C# and Unity. I usually code in JS in which using JSON files are no big deal for me and thought it was the best way to go.
Your json and your classes doesn't match. Not only that your json isn't even valid Json. Below I will give you your correct json and class.
{
"cards": [
{
"id": "sand_bags",
"type": "Structure",
"name": "Sand Bags",
"values": [
{
"civilian": 1,
"fiend": -1
}
],
"effectTexts": [
{
"civilian": "Add +1 to your BUNKER.",
"fiend": "Send any CIVILIAN'S +1 STRUCTURE to the SCRAPYARD."
}
],
"flavorTexts": [
{
"civilian": "They're just heavy bags with sand. Not much else to say, but they'll slow down an attack from a fiend. Good luck, you'll need it!",
"fiend": "You've spotted a pretty bad STRUCTURE in this BUNKER. Time to do some damage."
}
],
"staysOnField": [
{
"civilian": true,
"fiend": false
}
],
"amountInDeck": 5
}
] // <---- This was missing
}
For that Json this is how your card class will have to look like:
public Card
{
public string id { get; set; }
public string type { get; set; }
public string name { get; set; }
public Values[] values { get; set; }
public Values[] effectTexts { get; set; }
public Values[] staysOnField { get; set; }
public int amountInDeck { get; set; }
}
And your Values class have to look like this:
public class Values
{
public object civilian;
public object fiend;
}
I suggest MiniJson.
You can just copy paste the script to your project and you are ready to go.
The then can call Json.Deserialize(string json) passing your string in. For the case of an array you can do for example:
IList myJsonElements = (IList)Json.Deserialize(string json);
Find working snippet:
using System;
using Newtonsoft.Json;
namespace ConsoleApp3
{
class Program
{
static void Main(string[] args) {
string myJson = "{\"cards\": [{\"id\": \"sand_bags\",\"type\": \"Structure\",\"name\": \"Sand Bags\",\"values\": [{\"civilian\": 1,\"fiend\": -1}],\"effectTexts\": [{\"civilian\": \"Add +1 to your BUNKER.\",\"fiend\": \"Send any CIVILIAN'S +1 STRUCTURE to the SCRAPYARD.\"}],\"flavorTexts\": [{\"civilian\": \"They're just heavy bags with sand. Not much else to say, but they'll slow down an attack from a fiend. Good luck, you'll need it!\",\"fiend\":\"You've spotted a pretty bad STRUCTURE in this BUNKER. Time to do some damage.\"}],\"staysOnField\": [{\"civilian\": true,\"fiend\": false}],\"amountInDeck\": 5}]}";
var myJsonElements = MiniJSON.Json.Deserialize(myJson);
Console.WriteLine(myJsonElements.ToString());
string json = JsonConvert.SerializeObject(myJsonElements, Formatting.Indented);
Console.WriteLine(json);
Console.ReadLine();
}
}
}

LUIS Add Utterance in code JSON POST failing

Following this example:
https://learn.microsoft.com/en-us/azure/cognitive-services/luis/luis-quickstart-cs-add-utterance
I am trying to send an utterance to my LUIS App.
It keeps on failing with this response message:
{
"error": {
"code": "BadArgument",
"message": "Failed to parse example labeling objects. Parameter name: exampleLabelObjects"
}
}
My input body is:
{
"text": "hi, what can I help you with?",
"intentName": "Help",
"entityLabels": []
}
And according too the link if you send an utterance without any entity labels the above is correct.
The entityLabels field is required. If you don't want to label any
entities, provide an empty list as shown in the following example:
[
{
"text": "go to Seattle",
"intentName": "BookFlight",
"entityLabels": [
{
"entityName": "Location::LocationTo",
"startCharIndex": 6,
"endCharIndex": 12
}
]
},
{
"text": "book a flight",
"intentName": "BookFlight",
"entityLabels": []
}
]
The C# to build the object is as follows:
public class LUISUtterItem
{
public string utterances;
public string text;
public string intentName;
public List<exampleLabelObjects> entityLabels;
}
public class exampleLabelObjects
{
public string entityName;
public int startCharIndex;
public int endCharIndex;
}
I call it using:
LUISUtterItem itm = new LUISUtterItem();
//itm.utterances = materialArray[1];
itm.text = materialArray[1];
itm.intentName = materialArray[2];
itm.entityLabels = new List<exampleLabelObjects>();
I have also tried not including an "entityLabels" object, as well as a string list that just gets initiated with the same result.
Any help will be appreciated.
So it seems like all you have to include in the body is "[]" around it and it worked:
[{
"text": "hi, what can I help you with?",
"intentName": "Help",
"entityLabels": []
}]
I faced the same issue. Solved by sending the body as:
{
"text": "hi",
"intentName": "Greetings"
}
Don't put entityLabel if it is not needed.

Deserialize JSON value without name

How can I deserialize a string in C# that only have values and no name. It looks like this: The problem is that this stream of string does not have name and uses array.
{
"result": {
"14400": [
[
1502985600,
262.18,
262.18,
257,
257,
1096.0131
],
[
1503000000,
257,
261.33,
254.8,
257,
1130.5897
]
],
"14405": [
[
1503014400,
258.03,
261.5,
257.01,
257.01,
520.7805
],
[
1503028800,
258,
260.98,
252.4,
259.56,
298.5658
],
]
]
}
}
Just create a class like
public class Root
{
public Dictionary<int,List<List<double>>> Result { get; set; }
}
and deserialize as
var res = JsonConvert.DeserializeObject<Root>(json);
I see it's an array, you could create a method to parse the class out of given JArray.
The Jason data
public void methpod()
{
string json ="Your jason value "
var factory = new Factory();
var suggest = factory.Create(json);
Console.WriteLine(suggest);
}
Make a class as suggested :
public class Factory
{
public Evan Create(string json)
{
var array = JArray.Parse(json);
string search = array[0].ToString();
string[] terms = array[1].ToArray().Select(item => item.ToString()).ToArray();
return new Evan{Search = search, Terms = terms};
}
}
and another
public class Evan
{
public string Search { get; set; }
public IEnumerable<string> Terms { get; set; }
public override string ToString()
{
return string.Format("Search={0},Terms=[{1}]",
Search, string.Join(",", Terms));
}
}
Tip
If you have JSON that you want to deserialize, and you don't have the class to deserialize it into, Visual Studio 2019 can automatically generate the class you need:
Copy the JSON that you need to deserialize.
Create a class file and delete the template code.
Choose Edit > Paste Special > Paste JSON as Classes.
The result is a class that you can use for your deserialization target

JSON Get List of attributes values

I have the following JSON, and I want to take a list of IDs with its values
For example in LINQ something like this: result.Select(x=>x.id)
I tried this:
var inner = outer["pictures"].Value<JArray>().ToList();
I have a list there but with all attributes but I am not able to select just IDs since it is an anonymous list.
outer
{{
"id": "669654603",
"pictures": [
{
"id": "659745-MLA25600661898_052017",
"url": "http://mla-s2-p.mlstatic.com/659745-MLA25600661898_052017-O.jpg",
"secure_url": "https://mla-s2-p.mlstatic.com/659745-MLA25600661898_052017-O.jpg",
"size": "500x365",
"max_size": "625x457",
"quality": ""
},
{
"id": "908422-MLA25658267858_062017",
"url": "http://mla-s2-p.mlstatic.com/908422-MLA25658267858_062017-O.jpg",
"secure_url": "https://mla-s2-p.mlstatic.com/908422-MLA25658267858_062017-O.jpg",
"size": "47x47",
"max_size": "47x47",
"quality": ""
},
{
"id": "794138-MLA25658267889_062017",
"url": "http://mla-s2-p.mlstatic.com/794138-MLA25658267889_062017-O.jpg",
"secure_url": "https://mla-s2-p.mlstatic.com/794138-MLA25658267889_062017-O.jpg",
"size": "40x40",
"max_size": "40x40",
"quality": ""
}
]
}}
When working with Newtonsoft JSON you can do it like this:
var values = JObject.Parse(jsonString)["pictures"].Select(p => p["id"].Value<string>()).ToList();
In order to be valid your json should not contain double curly brackets:
{
"id": "669654603",
"pictures": [ ... ]
}
You can parse it without additional classes:
var ids = JObject.Parse(json)["pictures"].Select(p => (string)p["id"]);
Output:
[
"659745-MLA25600661898_052017",
"908422-MLA25658267858_062017",
"794138-MLA25658267889_062017"
]
Or you can create several classes to hold your json data:
public class Container
{
public List<Picture> Pictures { get; set; }
}
public class Picture
{
public string Id { get; set; }
// you can add other properties here
}
And use strongly-typed parsing:
var ids = JsonConvert.DeserializeObject<Container>(json).Pictures.Select(p => p.Id);

Categories

Resources