I want to know if the next value is valid as a JSON format
1223452234
I am using AFNetworking in my iOS app and allow the parse of it with
readingOptions: .AllowFragments
And it works... but it is a valid JSON? what's the name of that kind of things?
Thanks
To my knowledge you must be in an array or object type for the root element.
This means you could have something like this if you really wanted it to be as "small and simple" as possible.
[
12341234
]
or this if you need keys.
{
"test": 321321312
}
I don't think the numbers by themselves are valid and they're definitely not standard.
Related
I have been teaching myself how to parse JSON using SwiftyJSON and the fab PokeApi.co I thought I was getting the hang of it, until I tried to get an array back of a Pokemon's different types. The JSON returned looks like this:
...
],
"base_experience": 155,
"types": [
{
"slot": 2,
"type": {
"url": "https://pokeapi.co/api/v2/type/3/",
"name": "flying"
}
},
{
"slot": 1,
"type": {
"url": "https://pokeapi.co/api/v2/type/1/",
"name": "normal"
}
}
]
}
I need to grab an array of the value for "name" within "types" and then "type". I tried lots of different suggestions from here, the SwiftyJSON guide on their Github and various other sources, and the only thing I could get to work is this:
let typesArray = json["types"].arrayValue.map({$0["type"]["name"].stringValue})
for item in typesArray {
self.currentPokemon.pokemonTypes.append(item.firstUppercased)
print("Added \(item)")
}
I am happy that I have got it to work, but I am desperately trying to get my head around parsing JSON and this just doesn't make sense to me! Could anybody please explain to me what is going on? Is there a clearer/ more readable way of doing this?
Thank you for your time!
JSON
First things first... I think you need to make sure you really understand JSON before you can wrap your head around what you are doing here. JSON objects are essentially a Key / Value object. The Key is a string and the value can be many things: array of more JSON objects, or even as simple as a string.
Best Practices
So one thing I like to do when I have to parse through JSON for any response is create an enum of strings that will have all of the "Keys" in the json. Note that if you do not assign a calue to any case and the type is String when you do pokemonApiParams.name.rawValue it will automatically return the stringified version of your case!
enum pokemonApiParams: String {
case baseExperience
case types
case slot
case type
case url
case name
}
Now when you are working with your JSON you can use this enum to help make things clearer. This is especially nice if your API response ever changed a key. You could just change the enum value and everything would work! Another reason why this is a "best practice" is it takes out these "magic strings" from your code and keeps everything in one logistical place that you can refer to later!
// This would give you 155 in your example
json[pokemonApiParams.baseExperience.rawValue]
Working through your example
Now to the part you were having trouble understanding.
First let's reconstruct your "types array" piece by piece...
let typesArray = json[pokemonApiParams.types.rawValue]
This guy creates a json object that contains the array of "types" in your response. Basic SwiftyJSON objects are great but you can be a little more specific here to get some more usage, hence why your example uses .arrayValue.
let typesArray = json[pokemonApiParams.types.rawValue].arrayValue
Now we have a JSON array object and we could go through it using various different looping functions. However you use the .map function next. This guy is super useful once you get used to it and use it some more!
Understanding .map
Basically we can map each element in our array to be something else, in this case we are using a short hand to go through the array and get only the "name" attribute of each type. So we are mapping from a [JSON] -> String.
The $0 is the shorthand I was talking about. Imagine this as your index in a for loop. The map function will walk through the entirety of the array and $0 is the object in the array that is being looked at.
Check out the map documentation too!
Putting it all together
Looking at your response each types object has a slot and a type.
So back to your example (but using our enum!):
let typesArray = json[pokemonApiParams.types.rawValue].arrayValue
.map {
$0[pokemonApiParams.type][pokemonApiParams.name.rawValue].stringValue
}
Now your typesArray is an array of strings. Another way to write this (which would be a little clearer and maybe easier to understand) is:
let typesArray = json[pokemonApiParams.types.rawValue].arrayValue
.map { (types: JSON) -> String in
types[pokemonApiParams.type.rawValue][pokemonApiParams.name.rawValue].stringValue
}
This is clearer because we have to specify our object (types) instead of using the $0 shorthand and we specify what we are returning (String).
Hopefully this is all correct and clear!
Happy coding and go catch 'em all!
I would like to know if the following message is well parsed according to json format, I think it is but the application that needs to process it complains about it with the following error
[ERR]tx data JSON file error
The code in the file is this one
{"tx":
{
"moteeui":"fa789f0000000000",
"txmsgid":"000000000152",
"trycount":"5",
"txsynch" : "false",
"ackreq" : "true",
"userdata":
{
"port":"10",
"payload":"ABCABC"
}
}
}
Thanks in advance,
regards!
I have tried also the following snippet
[{
"mote": "202020",
"payload": "ABCB",
"port": 2,
"trycount": 5,
"txmsgid": ""
}]
I have validated with JSONLint and I get an error saying
[ERR]tx data JSON parsing error: 3 object item(s) left unpacked
Does it ring a bell?
Thanks again
Yes, it is correct.
For your info, JSONLint is a good site for checking the validity of JSON.
However, you may want to rethink setting numeric values as strings. ie, it is a better idea to say:
"trycount":5
rather than
"trycount":"5"
As the former indicates to whatever application is consuming the JSON that the value should be parsed as a number.
Similarly with the boolean values, it's better practise to use:
"txsynch" : false
rather than
"txsynch" : "false"
It won't cause an error in your JSON parser to pass these as strings, it is just better practise.
The error in the parser could be for many different reasons.
I have this kind of json data. And language am using his jquery
{
"Vitals":[
{
"Bp Systolic":"",
"Bp Diastolic":"",
"Weight":"",
"Height":"",
"BMI":""
}
],
"Lab":[
{
"Lipid_profile":[{
"Total Cholestrol":"",
"TRIGLYCERIDES":""
}],
"blood":[{
"A1C":[{ "sample" }],
"ALBUMIN":"",
"CALCIUM":"",
"Glucose":"",
"POTTASIUM":""
}]
}]
}
I want to access the A1C. What will be the efficient way of doing this. I know we can access it by iterating through the json. I am just looking for the efficient way.
Update:
as you guys said i have tried this, But am getting it as undefined
$.get('sample.json',function(data){
alert(data.toSource()); //all data
alert(data.Lab.blood); //undefined
});
Easiest and cleanest way would be to convert the json-string to an object and then access it with jsonObj.Lab.blood.A1C in any language I would say.
Otherwise you could use regEx to find it or substing to get it but both of these solutions would be ugly if you ask me.
You can parse the response into a JSON object and access the path 'obj.blood.A1C' as Erik and Sasse said, or you can search for the specific string with a regExp like
\"A1C\":\[\{ \"([^\"]*)\"
That will return you the contents of the token A1C value into the first matching result group.
If you tell us the programing language maybe we will be able to be a bit more specific.
we are looking at using the unparseable curft approach to our json as an extra level of security.
In looking at the approaches, I've come across google's while(1); and facebook's for(;;); and then another mention of {}&&
I've seen comments surrounding the while(1); that say the 1 being numeric can get clobbered, so my approach was going to be the for(;;);.
Then I came across the {}&&, which renders the json as invalid yet it can still be parsed/eval'ed. See this article for reference: http://www.sitepen.com/blog/2008/09/25/security-in-ajax/
What are your approaches? and what do your functions look like for making the ajax call with the unparseable curft?
I just always use a root object. As noted:
It is only possible to hijack JSON data with a root that is an array.
When the root is a primitive, primitive values do not trigger a
constructor. When the root is an object, it is not valid JavaScript
syntax, and therefore can’t be parsed.
Note that having a root primitive (e.g. your response is just 5) is not valid JSON. Section 2 of the RFC says:
A JSON text is a serialized object or array.
JSON-text = object / array
This isn't much of a burden, as I (and many sites) typically use an envelope format. E.g.:
{
"header": {...},
"data": {...}
}
or:
{
"status": {...},
"data": {...}
}
etc.
In that case, any array would just be the value of data, so you can serve syntactically valid JSON without any hijacking risk.
This could be the most basic json question ever. I'm creating a WCF REST service and have a HelloWorld test function that just returns a string. I'm testing the service in fiddler and the reponse body I'm getting back is:
"HelloWorld"
I also created a function that would just return a number (double) and the response body is:
1.0
Are those valid json responses? Are simple return types just returned in plain text like that (no markup with the brackets)?
Valid JSON responses start with either a { for an object or [ for a list of objects.
Native types are not valid JSON if not encapsulated. Try JSONlint to check validity.
RFC 4672, says no. Which doesn't mean it can't work, but it isn't strictly standards compliant. (Of course, neither are all the JSON readers...)
To quote from Section 2, "JSON Grammar":
A JSON text is a sequence of tokens. The set of tokens includes six
structural characters, strings, numbers, and three literal names.
A JSON text is a serialized object or array.
JSON-text = object / array
Only objects / maps, and arrays, at the top level.
According to the official website, you need to use a syntax like this:
You need to declare what you want beetween {}, like this:
{
"test": "HelloWorld"
}
No. The following is, for example:
{
"Foo": "HelloWorld"
}
You can try JSONLint to see what validates and what does not.