I´m making an application with dart / flutter and I need to keep the escape keys from the json server api response, how can I do that?
Example:
JSON reponse:
{"\"\"example\"\"": "value\'"}
Goal (after .fromJson and json.decode):
Class.example = "\"\"example\"\"";
Class.value = "value\'";
If you do jsonDecode(r'{"\"\"example\"\"": "value\'"}'), then you get a map with the key ""example"" and the value value' (the quotes are part of the string content here, not delimiters).
The backslashes are removed, which is to be expected because that's what the JSON specification says should happen. The escaped quotes are retained. The key does not become just example.
If you want to retain the backslashes too, then you don't actually want JSON decoding, because JSON decoding treats \" inside a string literal as introducing the character ".
If you wanted a string containing \"\"example\"\" from JSON decoding, then the original source needed to be "\\\"\\\"example\\\"\\\"".
So, if the sender of the JSON wanted you to see backslashes, they should have included and escaped those backslashes too.
If you JSON encode the string back, you get the backslashes again (at least for "), since jsonEncode('""example""') is "\"\"example\"\"".
If you really want access to the source code of the JSON input, I'd use a non-standard JSON parser, one which allows you to access the source instead of only the parsed value.
Example:
import "package:jsontool/jsontool.dart";
/// Parses [source] as JSON, but retains source escapes in strings.
Object? readJsonSourceStrings(String source) {
return _readJson(JsonReader.fromString(source));
}
Object? _readJson(JsonReader<StringSlice> reader) {
if (reader.tryObject()) {
var map = <String, Object?>{};
while (reader.hasNextKey()) {
var keySlice = reader.nextKeySource()!;
var key = keySlice.substring(1, keySlice.length - 1);
map[key] = _readJson(reader);
}
return map;
}
if (reader.tryArray()) {
var list = <Object?>[];
while (reader.hasNext()) {
list.add(_readJson(reader));
}
return list;
}
if (reader.checkString()) {
var slice = reader.expectAnyValueSource();
return slice.substring(1, slice.length - 1);
}
return reader.tryNum() ?? reader.tryBool() ??
(reader.tryNull() ? null : (throw "Unreachable"));
}
void main() {
var m = readJsonSourceStrings(r'''{"\"\"example\"\"":"value\'"}''');
print(m); // {\"\"example\"\": value\'}
}
(Disclaimer: I wrote the jsontool package.)
Related
I have a server set up to send messages over a local host port. I am trying to decode the serialized json messages sent by the server and get this error.
Error decoding message: kotlinx.serialization.json.internal.JsonDecodingException: Unexpected JSON token at offset 55: Expected EOF after parsing, but had instead at path: $
JSON input: .....mber":13,"Timestamp":5769784} .....
The Racer State messages are formatted in JSON as follows: { “SensorId”: “value”, “RacerBibNumber” : “value”, “Timestamp” : “value” }, where the value’s are character string representations of the field values. I have also tried changing my RacerStatus Class to take String instead of Int but to a similar error. Am I missing something here? The symbol that is missing in the error was not able to be copied over so I know it's not UTF-8.
I have also added
val inputString = bytes.toString(Charsets.UTF_8)
println("Received input: $inputString")
This gets
Received input: {"SensorId":0,"RacerBibNumber":5254,"Timestamp":3000203}
with a bunch of extraneous symbols at the end.
data class RacerStatus(
var SensorId: Int,
var RacerBibNumber: Int,
var Timestamp: Int
) {
fun encode(): ByteArray {
return Json.encodeToString(serializer(), this).toByteArray()
}
companion object {
fun decode(bytes: ByteArray): RacerStatus {
print(bytes[0])
try {
val mstream = ByteArrayInputStream(bytes)
return Json.decodeFromStream<RacerStatus>(mstream)
} catch (e: SerializationException) {
println("Error decoding message: $e")
return RacerStatus(0, 0, 0)
}
// return Json.decodeFromString(serializer(), mstream.readBytes().toString())
}
}
}
So I found an answer to my question. I added a regex to include just the json components I know my json contains.
val str = bytes.toString(Charsets.UTF_8)
val re = Regex("[^A-Za-z0-9{}:,\"\"]")
return Json.decodeFromString<RacerStatus>(re.replace(str,""))
I thought that Charsets.UTF_8 would remove the misc characters but it did not. Is there a more intiuative solution? Also is there a regex that would cover all possible values in json?
I am using SQFlite to store data locally, I have a table in which I have a field called 'json', this field is of type TEXT and stores a json converted to String, such as: '{name: Eduardo, Age: 23, Sex: male}'.
Up to this point, everything works fine.
But then I need to consult this information from the database and how it is stored in a text type format flutter recognizes it as a string. I don't know how to convert it back to an object.
I know that I can build a function to solve this, in the case that the information stored in the json always complies with the same structure. But in my case, the information contained by the json will be variable.
Is there a way to solve this problem?
you can Simply use json.decode function from the dart:convert package.
example:
import 'dart:convert';
main() {
final jsonString = '{"key1": 1, "key2": "hello"}';
final decodedMap = json.decode(jsonString);
// we can now use the decodedMap as a normal map
print(decodedMap['key1']);
}
check those links for more details
https://api.dart.dev/stable/2.10.3/dart-convert/json-constant.html
https://api.dart.dev/stable/2.4.0/dart-convert/dart-convert-library.html
if you have issue that your json keys doesn't have quotes then try this code it transform the unquoted String to a quoted String and then decode it , it's 100% working
final string1 = '{name : "Eduardo", numbers : [12, 23], country: us }';
// remove all quotes from the string values
final string2=string1.replaceAll("\"", "");
// now we add quotes to both keys and Strings values
final quotedString = string2.replaceAllMapped(RegExp(r'\b\w+\b'), (match) {
return '"${match.group(0)}"';
});
// decoding it as a normal json
final decoded = json.decode(quotedString);
print(decoded);
#EduardoColon If the keys are not quoted, then it's not JSON, it's your own custom key-value format. JSON keys have to be quoted. See https://json.org for the "official" JSON syntax.
This question already has answers here:
Additional text encountered after finished reading JSON content:
(2 answers)
Closed 4 years ago.
I am trying to use Json.NET to parse a file of comma-separated JSON objects:
{
JSON ...
},
{
JSON ...
},
{
JSON ...
}
The code below works fine if the stream contains no separators (i.e., commas above removed). However, commas produce an infinite loop where Json.NET keeps reading an "Undefined" token even after end of file was reached:
using (StreamReader fReader = File.OpenText("filename.json"))
using (JsonTextReader jReader = new JsonTextReader(fReader))
{
jReader.SupportMultipleContent = true;
while (jReader.Read())
{
var jToken = JToken.ReadFrom(jReader);
if (jToken is JObject)
Console.WriteLine("JSON object: " + ((JObject)jToken).ToString());
}
}
I tried skipping the comma by reading ahead and using JsonTextReader's Skip() method, but this doesn't work: JsonTextReader apparently buffers ahead, eating up the comma, which gives it indigestion.
It's hard to believe that I'd be the first to run into this problem, but despite searching here for a good bit, I haven't found any relevant posts (at least for C# and Json.NET). Is it really necessary to hack this up from scratch?
ETA: As per Brian Rogers' comment below, Json.NET 11.0.1 and above handle comma-separated JSON, so the above works fine now, commas or not.
One way to approach this would be make it a list. For example, you can add "[" "]" to either end of "comma separated Json" to convert it to a list and then deserialize it.
For example, consider the following code which has a Json Objects separated by Comma (for sake of simplicity, have created a simple json, but could work otherwise too)
var jsonString = #"{User:'anu viswan', Location:'India'},{User:'User2', Location:'India'}";
If you add "[" "]" to either end, and then serialize it, you could get a collection of RootObjects.
var result = JsonConvert.DeserializeObject<RootObject[]>($"[{jsonString}]");
In this particular case, RootObject is defined as
public class RootObject
{
public string User { get; set; }
public string Location { get; set; }
}
You can similarly convert the Json to a collection based on your Object definition.
I am trying to parse some JSON objects which is made just of (string,string) pairs, in order to emulate Resjson behaviour. The file I am parsing contains this.
{
"greeting":"Hello world",
"_greeting.comment":"Hello comment.",
"_greeting.source":"Original Hello",
}
Please note the last comma is incorrect, and I also used http://jsonlint.com/ to test JSON syntax. It tells me it is incorrect, as I expected. My - slightly modified - code is :
string path = #"d:\resjson\example.resjson";
string jsonText = File.ReadAllText(path);
IDictionary<string, string> dict;
try
{
dict = JsonConvert.DeserializeObject<IDictionary<string, string>>(jsonText);
}
catch(Exception ex)
{
// code never reaches here
}
My above code returns the IDictionary with the 3 keys as if the formatting was correct. If I serialize back, the string obtained is without the last comma.
My questions are :
Is Newtonsoft.Json so permissive that it allows users slight errors ?
If so, can I set the permissiveness so that it is more strict ?
Is there a way to check if a string is valid JSON format, using
Newtonsoft.Json with and/or without the permissiveness?
what is the difference between json string and parsed json string?
for eg in javascript suppose i have a string in the json format say [{},{}]
parsing this string will also produce the same thing.
So why do we need to parse?
It's just serialization/deserialization.
In Javscript code you normally work with the object, as that lets you easily get its properties, etc, while a JSON string doesn't do you much good.
var jsonobj = { "arr": [ 5, 2 ], "str": "foo" };
console.log(jsonobj.arr[1] + jsonobj.str);
// 2foo
var jsonstr = JSON.stringify(jsonobj);
// cannot do much with this
To send it to the server via an Ajax call, though, you need to serialize (stringify) it first. Likewise, you need to deserialize (parse) from a string into an object when receiving JSON back from the server.
Great question. The difference is transfer format.
JSON is only the 'Notation' of a JavaScript Object, it is not actually the JavaScript 'object-literal' itself. So as the data is received in JSON, it is just a string to be interpreted, evaluated, parsed, in order to become an actual JavaScript 'Object-Literal.
There is one physical difference between the two, and that is quotation marks. It makes sense, that JSON needs to be a string to be transferred. Here is how:
//A JavaScript Object-Literal
var anObj = { member: 'value'}
//A JSON representation of that object
var aJSON = { "member":"value" }
Hope that helps. All the best! Nash
I think a parsed json string should be the string data into the actual javascript objects and data arrays (or whichever language the json string contains)
The JSON object contains methods for parsing JSON and converting values to JSON.
It can't be called or constructed, and aside from its two method properties it has no interesting functionality of its own.
JSONParser parser = new JSONParser();
Object object = parser.parse(Message.toString());
JSONObject arObj = (JSONObject) object;