I have to comply with a Restful request call using Swift 3 that unfortunately contains duplicate keys as shown below. I originally placed the data in a dictionary to pass into a JSON serialization call.
[
"mid":"3",
"attributes":[
"carID":["a":54123,"b":424,"c":"13242"],
"update":"true"
"update":"gold"
]
]
Notice that update occurs twice, which causes this error:
fatal error: Dictionary literal contains duplicate keys
I've reviewed this question but doesn't seem to have a pertinent answer.
I thought about using an array but I think it would lose the key value pair relationship that I need for the JSON serialization.
I've seen some articles on using structs but I'm not sure that would address the duplicate key issue
Any recommendations? I'm unable to change the parameter names in the request as it is a third party product.
BTW, I don't think my question is a duplicate of How to avoid duplicate key error in swift when iterating over a dictionary – Ssswift. That example should truly be a struct/class since it is one key value pair (age:age value) that should be in a class or struct. My example has a repeating key with each of the two instances of the repeating key having different meanings (should they update, and what the updated member type should be). I don't see how it would be applicable but am open to enlightenment on it.
Thanks
Related
I got an anonymous array which I want to deserialize, here the example of the first array object
[
{ "time":"08:55:54",
"date":"2016-05-27",
"timestamp":1464332154807,
"level":3,
"message":"registerResourcePath ('', '/sap/bc/ui5_ui5/ui2/ushell/resources/')",
"details":"","component":"sap.ui.ModuleSystem"},
{"time":"08:55:54","date":"2016-05-27","timestamp":1464332154808,"level":3,"message":"URL prefixes set to:","details":"","component":"sap.ui.ModuleSystem"},
{"time":"08:55:54","date":"2016-05-27","timestamp":1464332154808,"level":3,"message":" (default) : /sap/bc/ui5_ui5/ui2/ushell/resources/","details":"","component":"sap.ui.ModuleSystem"}
]
I tried deserializing using CL_TREX_JSON_SERIALIZER, but it is corrupt and does not work with my JSON, here is why
Then I tried /UI2/CL_JSON, but it needs a "structure" that perfectly fits the object given by the JSON Object. "Structure" means in my case an internal table of objects with the attributes time, date, timestamp, level, messageanddetails. And there was the problem: it does not properly handle references and uses class description to describe the field assigned to the field-symbol. Since I can not have a list of objects but only a list of references to objects that solution also doesn't works.
As a third attempt I tried with the CALL TRANSFORMATION as described by Horst Keller, but with this method I was not able to read in an anonymous array, and here is why
My major points:
I do not want to change the JSON, since that is what I get from sap.ui.log
I prefere to use built-in functionality and not a thirdparty framework
Your problem comes out not from the anonymity of array, but from the awkwardness of SAP JSON (De)serializer, which doesn't respect double quotes, which enclose JSON attributes. The issue is thoroughly described in this answer.
If you don't want to change your JSON on-the-fly, the only way you have is to change CL_TREX_JSON_DESERIALIZER class like this.
/UI5/CL_JSON_PARSER parses JSONs with unknown format.
Note that it's got "for internal use" written on it so many times that you probably should take it seriously and clone its code to fixate it.
I'm using JsonCpp v0.6.0 to parse the following JSON string:
{
"3.7":"de305d54-75b4-431b-adb2-eb6b9e546011",
"3.7":"de305d54-75b4-431b-adb2-eb6b9e546012",
"3.8":"de305d54-75b4-431b-adb2-eb6b9e546013"
}
as follows:
Json::Value root;
Json::Reader reader;
// value contains the JSON string
if (!reader.parse(value, root, false))
{
// parse error
}
After the call to parse, root contains two entries in a map:
[0] first = "3.7", second = "de305d54-75b4-431b-adb2-eb6b9e546012",
[1] first = "3.8", second = "de305d54-75b4-431b-adb2-eb6b9e546013",
i.e. the first JSON record has been overwritten by the second. No errors are reported.
Is this behaviour expected? Is it correct?
I thought that an error might have been reported indicating that there is a duplicate key in the JSON string.
Like the JSON RFC sad the object names (keys) should be unique.
The names within an object SHOULD be unique.
Also the RFC defines if they are not, the behavior is unpredictable.
See this quote from the RFC:
An object whose names are all unique is interoperable in the sense
that all software implementations receiving that object will agree on
the name-value mappings. When the names within an object are not
unique, the behavior of software that receives such an object is
unpredictable. Many implementations report the last name/value pair
only. Other implementations report an error or fail to parse the
object, and some implementations report all of the name/value pairs,
including duplicates.
I agree with what you say, but I think JsonCpp tries to be a helpful tool, not something that tries to scrape by with minimal conformance to the RFCs.
It would make more sense if it either maintained the structure of the input stream, and supported duplicate keys, or (and this is what the OP and I'd expect) if it doesn't like it, to flag an error.
Silently changing the structure is unhelpful, as a check for the validity of the JSON input would have to be made with some other JSON tool prior to sending it to JsonCpp.
According to the following post;
Does JSON syntax allow duplicate keys in an object?
Keys with the same name in JSON are valid, but most parsers will override the value with the last value it finds. Is there anyway in a json schema to detect duplicate names and throw an error? I want all json keys to have unique names in an object.
Json-schema works with valid JSON objects, so there is nothing it can do to prevent duplicate keys.
I would suggest you to use a jsonlint as a preprocess before validating with json-schema validator. It will depend on your programming language but here you have some choices:
javascript.
PHP
Python
Is it possible to check for the existence of a key before Flex 4.5 JSON throws an exception for key not found? I have some json data where some keys are not always present.
I am using CallResponder...
The issue is that when you try accessing callResponder.lastResponse.key - and, say, key is not always present in your json, Flex won't be able to parse it. This happens even if you check if (callResponder.lastResponse.key) - the error occurs on the if line, in that case
(See old error dump here)
The answer provided below works for cases where the keys are top level nodes in the JSON. However, its seems unable to parse existence for child keys. I had not expected there to be a difference between parsing for top level nodes and child nodes, but apparently that is the case.
For clarity's sake (as I did not mention I am trying to parse for child keys in my original question), I've created a new question here that specifically asks how to parse for child keys, using the method below -- or another method, if need be: Flex 4.5 How do you check for JSON child node key existence (using hasOwnProperty or other methods)
How do you process your JSON data?
In my memory, I use JSON.decode(String), and got an array. For each object, you can use obj.hasOwnProperty(key) to check whether it's present.
Is this valid JSON?
{
"name": "foo",
"name": "bar"
}
If so, how should it be interpreted?
It's technically legal, but strongly discouraged, according to the RFC:
The names within an object SHOULD be unique.
You can go one of two routes:
The JavaScript route: In JavaScript, this is illegal. Since JSON is supposed to be a subset, reject the input as invalid.
The Postel/Python route: Overwrite the "var" entry with the latest value.
According to RFC 4627, duplicate names are discouraged. See section 2.2. Objects:
The names within an object SHOULD be unique.
The above URL also refers us to RFC 2119, which specifies how the word SHOULD is interpreted:
SHOULD
This word, or the adjective "RECOMMENDED", mean that there
may exist valid reasons in particular circumstances to ignore a
particular item, but the full implications must be understood and
carefully weighed before choosing a different course.
However, many parsers & JSON APIs implement this as SHOULD ALWAYS, and throw an error or ignore multiple values upon encountering duplicate properties. This includes jQuery.parseJSON() as well as .NET's JSON serialization.
It is not valid JSON as there are two name variables. Take a read of this to help you understand JSON a bit better.
JSon object, like any other object, can not have two attribute with same name. That's illegal in the same way as having same key twice in a map.
JSONObject would throw an exception if you have two keys with same name in one object. You may want to alter your object so that keys are not repeated under same object.
In this case the change would be to make your json key name have value as an array
No, is not. You have two attributes with the same label/name/title. Here is a very simple and short explanation of the JSON