bunny83 / simplejson Goto Github PK
View Code? Open in Web Editor NEWA simple JSON parser in C#
License: MIT License
A simple JSON parser in C#
License: MIT License
I like this simple-to-use JSON library. But is there documentation on what does what?
in
public struct KeyEnumerator {
...
public JSONNode Current { get { return m_Enumerator.Current.Key; } }
...
}
Type of Key is string and converting it to JSONNode modify key name and should be
public string Current { get { return m_Enumerator.Current.Key; } }
Hi
In ParseElement() the following code is used
if (double.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out val))
return val;
else
return token;
However all:
Double.TryParse(Int64.MaxValue.ToString(),out Double d)
(Double)Int64.MaxValue
Int64.MaxValue == Double.Parse(Int64.MaxValue.ToString())
happily return true and a value 9.2233720368547758E+18
Where Int64.MaxValue is 9223372036854775807 (very close but incorrect and 7 off).
The new longAsString does not seem to help here as the conversion is already performed.
Not sure if this is solvable (other then keeping numbers as strings until they are requested with an As** Method).
Maybe for plain numbers, checking presence of the decimal separator and the length in characters might work.
Hi,
I could not find how to use as_array and get the array size if I have out["BankList"] like {"BankList":[{"Name": "Bank 1"}, {"Name": "Bank 2"}]. better to see some examples if possible.
is there any provision of extracting the key of a JSONNode ?
When doing node["somekey"].ToString()
on a JSONNode where the value is already a string, the string is returned wrapped into double quotes, so .ToString()
currently returns a literal "abc"
instead of an expected abc
string.
That happens in WriteToStringBuilder()
of class JSONString
, that explicitly does
aSB.Append('\"').Append(Escape(m_Data)).Append('\"');
Is there a rationale for this? I was using .ToString()
as an easy way to make sure to get a string representation, no matter what the actualy type may have been. However, the unexpected quotes lead to errors e.g. in comparing with expected values, or further parsing the string, so I find myself .Trim()
ing them away.
Actual behaviour: string values are returned wrapped in quotes.
Expected behaviour: the string should be returned without quotes.
Thanks for considering.
Say my JSON looks like
0:{0:{"forces":{"soldiers":2,"bombers":0,"fighters":0,"mother_ships":[],"flag_ships":[],"super_flag_ships":[]}
After I convert it to JSONNode it will look like
[[{"forces":{"soldiers":2,"bombers":0,"fighters":0,"mother_ships":[],"flag_ships":[],"super_flag_ships":[]}
It only does this to 0. So it treats 0 as empty I guess.
if the key is 1 then it will convert the int key to a 1 string
"1":{"1":{"forces":{"soldiers":2,"bombers":0,"fighters":0,"mother_ships":[],"flag_ships":[],"super_flag_ships":[]}
So idk may just be my bad understanding of something.
Hi friend, thanks for being a community-positive person and donating your time and work on SimpleJSON along with your other Unity code utils! I wish more people in this world were like you, and will proudly credit you in our 501(c)(3) project PLAN (plan-systems.org).
Thanks again!
Drew O'Meara
PLAN Systems
Hi
I changed the code of ParseElement a bit so it has some checks on long values near their min/max (see https://wvdvegt.wordpress.com/2018/04/26/double-precision-issues/ for details on the issue):
private static JSONNode ParseElement(string token, bool quoted)
{
...
double val;
if (double.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out val))
return val;
else
return token;
}
into
private static JSONNode ParseElement(string token, bool quoted)
{
...
//! Patched start.
Boolean isLong = (longAsString && long.TryParse(token, out long lval));
if (double.TryParse(token, NumberStyles.Float, CultureInfo.InvariantCulture, out double rval))
{
if (isLong && !rval.ToString("F0").Equals(token))
return token;
else
return rval;
}
else
return token;
//! Patched end.
}
Fix can probably optimized a bit by mainly using the rval.ToString("F0").Equals(token) check
Line 366 in b0dd3c0
Converting to DateTime and Decimal types are missing, I suggest following code but I'm not sure if it will work correctly.
public virtual decimal AsDecimal {
get {
decimal v = 0.0M;
if (decimal.TryParse(Value, NumberStyles.Float, CultureInfo.InvariantCulture, out v))
return v;
return 0.0M;
}
set {
Value = value.ToString(CultureInfo.InvariantCulture);
}
}
public virtual DateTime AsDateTime {
get {
DateTime d = DateTime.MinValue;
if (DateTime.TryParse(Value, CultureInfo.InvariantCulture, DateTimeStyles.None, out d))
return d;
return DateTime.MinValue;
}
set {
Value = value.ToString(CultureInfo.InvariantCulture);
}
}
Code
JSONObject data = new JSONObject();
data.Add("floatTest", 0.11f);
Debug.Log("Result 1: " + data.ToString());
var N = JSON.Parse(data2.ToString());
Debug.Log("Result 2: " + N["floatTest"]);
Log
Result 1: {"floatTest":0,109999999403954}
Result 2: 0
A. Comma is problem for json formatting.
B. Precision?
If you have a string array like this:
"categories": [ "A", "B" ]
which you read like this:
JSONArray arr = o["categories"].AsArray; foreach (JSONNode cat in arr) { Debug.Log(cat); }
You get "A", "B" -- not A, B -- i.e. the quotes are part of cat. AFAIK they shouldn't be, as the type of the array elements is string. Or am I missing something here?
Hi
For a swagger related project I need to detect the absence of some keys (like 'error').
What is the correct way to check the absence of keys?
I have JSON
{"data":{"login":{"authentication":{"accessToken":"eyJhbGciOiJSUzI1"}}}}
SimpleJSON.JSON.Parse does not create child nodes. What could be the problem?
Hello there,
I found your very useful SimpleJSON script and I expect it will save me a lot of time. Thank you! I wondered if you could demonstrate how to use it in a foreach and switch statement way. Something like this:
var UserSettings = JSON.Parse(json_string);
// Merge UserSettings into DefaultSettings
foreach ( var rootElement in UserSettings)
{
switch (rootElement.Key)
{
case "ClockType":
AirSimSettings.GetSettings().ClockType = rootElement.Value;
break;
case "ClockSpeed":
AirSimSettings.GetSettings().ClockSpeed = rootElement.Value.AsDouble;
break;
case "Recording":
foreach (var sub1 in UserSettings["Recording"])
{
switch (sub1.Key)
{
case "RecordOnMove":
AirSimSettings.GetSettings().Recording.RecordOnMove = sub1.Value.AsBool;
break;
case "RecordInterval":
AirSimSettings.GetSettings().Recording.RecordInterval = sub1.Value.AsDouble;
break;
case "Cameras":
AirSimSettings.GetSettings().Recording.Cameras.Clear();
foreach (var sub2 in UserSettings["Recording"]["Cameras"])
{
var camsettings = sub2.Value.AsArray;
foreach (var cs in camsettings)
{
AirSimSettings.CamerasSettings NewRecordingCameraSetting = new AirSimSettings.CamerasSettings
{
CameraName = "0",
ImageType = 0,
PixelAsFloat = false,
Compress = true
};
foreach (var cam in cs.Value)
{
switch (cam.Key)
{
case "CameraName":
NewRecordingCameraSetting.CameraName = cam.Value;
break;
case "ImageType":
NewRecordingCameraSetting.ImageType = cam.Value.AsInt;
break;
case "PixelAsFloat":
NewRecordingCameraSetting.PixelAsFloat = cam.Value.AsBool;
break;
case "Compress":
NewRecordingCameraSetting.Compress = cam.Value.AsBool;
break;
}
}
AirSimSettings.GetSettings().Recording.Cameras.Add(NewRecordingCameraSetting);
}
}
break; // Cameras
}
}
break; // Recording
}
Is this the correct way if one wanted to first parse the root elements of the JSON data structure. And then also do subsequent parsing of sub elements? A little example of this would be helpful. :)
It'd be nice to see an example of parsing JSON to Unity types
Parsing array from file. All strings are as quoted strings. Should be without quotes.
How to get the Key of JsonNode?
May I suggest you add versioning tags to this repo? I would do a pull request for you but, I don't think I can create tags through a pr.
This will help with knowing which version of the code that a person has in their project, when using a package manager like UPM
Looking through the changelog, and using semver versioning logic, I established the following version tags:
if you run the following git command, you can generate the tags as I did above:
git tag v3.0.0 fbc442b
git tag v4.0.0 846ca8d
git tag v4.1.0 64f113b
git tag v4.2.0 4a62c09
git tag v4.3.0 68cce51
git tag v4.4.0 2ab789d
git tag v4.5.0 a13f411
git tag v4.6.0 975804e
git tag v4.7.0 75fd269
git push --tags
And if the latest is ready for release, I suggest you tag it v4.7.1
(bump patch since it's all bug fixes in there)
When I download the files I have an error in SimpleJSON.cs.
The non-generic type 'Stack' cannot be used with type arguments
Stack<JSONNode> stack = new Stack<JSONNode>();
operator '==' cannot be applied to operands of type 'method group' and 'int'
if (stack.Count == 0)
if (stack.Count > 0)
Say my JSONNode looks like this
ActiveGroups["Groups"]["Steubers"]["Names"][0] = "John";
ActiveGroups["Groups"]["Steubers"]["Names"][1] = "Paul";
ActiveGroups["Groups"]["Steubers"]["Names"][2] = "Robert";
ActiveGroups["Groups"]["Steubers"]["Names"][3] = "Cindy";
ActiveGroups["Groups"]["Steubers"]["PlayersLeft"][0] = "John";
ActiveGroups["Groups"]["Steubers"]["PlayersLeft"][1] = "Paul";
ActiveGroups["Groups"]["Steubers"]["PlayersLeft"][2] = "Robert";
ActiveGroups["Groups"]["Steubers"]["PlayersLeft"][3] = "Cindy";
ActiveGroups["Groups"]["Steubers"]["NamesLeft"][0] = "John";
ActiveGroups["Groups"]["Steubers"]["NamesLeft"][1] = "Paul";
ActiveGroups["Groups"]["Steubers"]["NamesLeft"][2] = "Robert";
ActiveGroups["Groups"]["Steubers"]["NamesLeft"][3] = "Cindy";
ActiveGroups["Groups"][GameSettings.CurrentSelectedGroupName]["PlayersLeft"].Remove(2);
This will remove key 2 from Names, PlayersLeft and NamesLeft
should only be removing it from PlayersLeft
JSONNode json = JSON.Parser("{"id":"1","name":"name-1","data":"["{"dataId":"1001"}]"}");
String val = (String)json["id"]; //return 1
String val2 = json["id"].ToString(); // return "1"
if modify code
internal override void WriteToStringBuilder(StringBuilder aSB, int aIndent, int aIndentInc, JSONTextMode aMode) { //aSB.Append('\"').Append(Escape(m_Data)).Append('\"'); aSB.Append(Escape(m_Data)); }
so
String val = (String)json["data"]; // return ""
String val2 = json["data"].ToString(); // return \"[\"{\"dataId\":\"1001\"}]\"
There is a problem with empty elements in an array.
How to reproduce:
string s = "{ \"arr\":[\"a\",\"\",\"c\"]}";
var n = SimpleJSON.JSONNode.Parse(s);
var arr = n["arr"].AsArray;
UnityEngine.Debug.Log(string.Format("Items count: '{0}'", arr.Count));
foreach (var item in arr)
{
UnityEngine.Debug.Log(string.Format("Item: '{0}'", item));
}
Real output:
Items count: '2'
Item: '"a"'
Item: '"c"'
Expected output:
Items count: '3'
Item: '"a"'
Item: '""'
Item: '"c"'
It will be great if you take a look. Thanks!
Hey I was on the 2012 version and just found out about the new updates, but unfortunately my game's level files are made using binary from that version, so they can't load (something error binary type 104). Is there any sort of easy way to up-convert an existing binary JSON file? I would love to use the new improvements.
Thanks.
Hi Bunny83,
I'm suggesting to move the change comment logs present in the topmost part of the source files to a dedicated CHANGELOG file.
This will help to reduce source file size also makes LICENSE text clean and visible.
Thanks,
RB.
Currently, the default serialization produces
"key" : "value"
(note: two spaces)
and the compact one produces
"key":"value"
(note: no space)
I'd like to see a third option here that produces another commonly seen format (the most common one I'm seeing at least):
"key": "value"
(note: single space after the colon).
Line 1009 in 6fc5622
I'd be happy to make a PR but wanted to
"key": "value"
Hi
I've had some issues with json input that is either an object or array and plain values like 32 and 42.45
JSON.Parse() does not seem to return anything (it shows { }, an empty object) with the plain values. Is it not supported (it is legal JSON and is part of the JSON standard a.t.m.) or am i doing anything wrong.
Hi
I have a problem when I try to parse a file with JSON an Android device.
The line 58 of the file below return a warning "Unsupported encoding: 'iso-8859-1,application/json'".
And the line 65 return a null value.
The JSON file that I download with the WWW function :
What can I change to make it work ?
Marie
I use it for my Discord bot, and I use thia class for better managing datas what I get from the mysql database. So, when I download the ID of a user and I serialize it than want to get back the user it it give me back a similar, but not the same ID.
Here is a sample code what is my problem:
var results = new Dictionary<string, object>();
results.Add("UlongValue", (ulong)570588935458127888);
var jsonObj = JSON.Parse(JsonConvert.SerializeObject(results, Formatting.None));
Console.WriteLine(jsonObj["UlongValue"].AsULong); //It's give back 570588935458127872
Console.WriteLine(jsonObj["UlongValue"].AsLong); //It's give back 570588935458127872
Console.WriteLine(jsonObj["UlongValue"].Value); //It's give back 5.705889354581279E+17
Console.WriteLine(jsonObj.ToString()); //It's give back {"UlongValue":5.705889354581279E+17}
If I think rigthly it store the data in double, and this is the problem.
Can dictionary parse to JNode?
// now what i have to do
var json = SerializeToJson(dict);
var N = JSON.parse(json);
// what i want
var N = JSON.parse(dict);
Until now I was using this SimpleJSON script repo: https://github.com/HenrikPoulsen/SimpleJSON/blob/master/SimpleJSON.cs
Before switching over to trying your SimpleJSON scripts in a project as it looked better supported and also had a means of checking for keys in a JSONNode
When pulling a JSON in from the web, I was using a check to see if the JSON was null, this worked with their version, but when using yours I tried both jsonnode.IsNull which always returned false, or when using if(jsonnode == null) it would always be false too as your script gives me """" when reading an empty returned JSONNode.
I am wondering if there is anything that can be done about this? I had to roll back to the HenrikPoulsen version linked above to get the null checks working again in our code, but their version is missing .key definitions when trying to use a helper script to check if a JSONNode contains a key.. so having this fixed would be great!
The JSON we receive is null effectively as when grabbing the value from Visual Studio and pasting it into a JSON reader online or VS Code, we have to remove all the \ and " speech marks from the string anyway so looks like the Henrik version has some more robust is JSON null checks?
Can you publish this as a package via https://openupm.com/?
Instructions can be found here:
https://openupm.com/docs/adding-upm-package.html#upm-package-criteria
Currently, a package with this name already exists, but it looks like it's a fork with some modifications.
https://openupm.com/packages/com.bunny83.simplejson/
Also, unfortunately, that specific bundle doesn't even work :(
Hi,
I'm from the Unity wiki (same usename) and someone pointed me here regarding this issue:
see: opless/SimpleJSON#1
Shall we merge any changes and come up to parity with licenses etc?
how?
and thanks
Hi, found one issue. I parsed one json file in Unity and got different results. I'm in a confusion.
AsInt=0 But AsBool=True
AsBool should be False!!!!!
My JSON file:
TestSV01_NodeTree.zip
My test code of a JSONNode:
Debug.Log(input.GetType());
Debug.Log(input.Value.GetType());
Debug.Log(input.Value["DefaultValue"].GetType());
Debug.Log(input.Value["DefaultValue"].AsInt);
Debug.Log(input.Value["DefaultValue"].AsBool);
My LOG:
System.Collections.Generic.KeyValuePair`2[System.String,BESimpleJSON.JSONNode]
BESimpleJSON.JSONObject
BESimpleJSON.JSONNumber
0
True
Using SimpleJSON in custom packages either results in
My proposed solutions are
Runtime/SimpleJSON
. Add a .gitignore
file to the SimpleJSON repo ignoring any *.meta
files. When changes are made to SimpleJSON, they can be pulled to the repo inside the Unity Package repo, then the Unity Package can push those changes to it's own repo.I have a scenario like so:
var newNode = new JSONObject();
newNode.Add(someKeyInAVar, null);
DoSomethingWithNode(newNode); // Needs to set newNodes internal node value to be new JSONData() || JSONObject()
So currently I cannot find any way to be able to basically create a property, but then update its value at a later point, so is this possible or would I need to create some form of bespoke LazyCreator
style JSON node?
Is it possible to add a method that returns the keys of JSONObject? I'm sure that Dictionary has this property.
And is it possible to add AsLong for JSONNode?
Thank you
The implicit string -> JSONNode operator doesn't check for null string, and creates a JSONString with null value (null m_Data), which will later cause an exception/crash in Escape() when it is serialized.
Suggested fix, replace this:
public static implicit operator JSONNode(string s)
{
return new JSONString(s);
}
with this:
public static implicit operator JSONNode(string s)
{
return (s == null) ? (JSONNode) JSONNull.CreateOrGet() : new JSONString(s);
}
I have my data split over several files and I wondered if there's an easy way to merge the JSONs, or if I have to iterate over all keys myself.
I suggest replace ',' for '.' in double/float type. In JSON we can use '.' without quote. There will be lighter files.
1: { "txt": "mod1", 1: { "timeline": 12.3,
//now we must use "timeline": "12,3",
Not sure if you are the maintainer but there seems to be an issue where if you have an array which contains a null entry, that null is omitted from the parsed results, so checking the count of someArray
would give 1 not 2.
{
"someArray": ["1", null]
}
Hi
I'm using simpleJSON to cache some name value pairs.
My declaration is
private static JSONNode names = new JSONObject();
However when i call
names["id"] = "value";
all I see is virtual methods of JSONNode being called (as if class hierarchy is broken). Not sure that is the intended behavior. I fixed it for now by:
private static JSONObject names = new JSONObject();
Hi Bunny83。 I am coming again。
The same question as before。
But this time I modified the sample code and it works.
sample1
`
String jsonString = "{\"id\":\"1\",\"name\":\"name-1\"}";
JSONNode j = JSON.Parse(jsonText);
String id1 = j["id"]; // return 1
String id2 = (String)j["id"]; // return 1
String id3 = j["id"].ToString(); // return "1"
String name1 = j["name"]; // return name-1
String name2 = (String)j["name"]; // return name-1
String name3 = j["name"].ToString(); // return "name-1"
`
sample2
`
using (StreamReader sr = new StreamReader("D:\\json.txt"))
{
JSONNode j = JSON.Parse(sr.ReadToEnd());
String id1 = j["id"]; // return 111
String id2 = (String)j["id"]; // return 111
String id3 = j["id"].ToString(); // return "111"
String name1 = j["name"]; // return json.text.name
String name2 = (String)j["name"]; // return json.text.name
String name3 = j["name"].ToString(); // return "json.text.name"
}
`
file "json.txt" content {"id":"111","name":"json.text.name"}
개미 몬스터 2종을 제작하기 위한 브랜치입니다.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.