Parsing XML Inner XML tags Objective-C - iphone

I would like to create an NSDictionary or (NSArray) full of NSDictionary objects for each station in the following XML:
<stations lastUpdate="1328986911319" version="2.0">
<station>
<id>1</id>
<name>River Street , Clerkenwell</name>
<terminalName>001023</terminalName>
<lat>51.52916347</lat>
<long>-0.109970527</long>
<installed>true</installed>
<locked>false</locked>
<installDate>1278947280000</installDate>
<removalDate/>
<temporary>false</temporary>
<nbBikes>12</nbBikes>
<nbEmptyDocks>7</nbEmptyDocks>
<nbDocks>19</nbDocks>
</station>
... more...
<station>
<id>260</id>
<name>Broadwick Street, Soho</name>
<terminalName>003489</terminalName>
<lat>51.5136846</lat>
<long>-0.135580879</long>
<installed>true</installed>
<locked>false</locked>
<installDate>1279711020000</installDate>
<removalDate/>
<temporary>false</temporary>
<nbBikes>12</nbBikes>
<nbEmptyDocks>4</nbEmptyDocks>
<nbDocks>18</nbDocks>
</station>
...
</stations>
What's the best way to achieve this? Right now I have an NSDictionary with one object and one key - "stations", but I want the NSDictionary (or NSArray) of NSDictionarys.
I'm using an XML parser by Troy Brant - http://troybrant.net/blog/2010/09/simple-xml-to-nsdictionary-converter/
I'm guessing it's going to involve some looping of some sort but I'm not really sure how to approach this problem. Any help or pointers in the right direction would be much appreciated.
Thanks.

I also use the XMLReader it is very easy to understand
I have looked at your xml, and I am assuming you wanted to use the array of station tags.
Here is my solution:
NSDictionary *dictXML= [XMLReader dictionaryForXMLString:testXMLString error:&parseError];
NSArray *arrStation = [[dictXML objectForKey:#"stations"] objectForKey:#"station"];//this would return the array of station dictionaries
Now that you have the array of station tags you can do what you want for example displaying all id:
for(int i=0;i<[arrStation count];i++){
NSDictionary *aStation = [arrStation objectAtIndex:i];
NSLog(#"id = %#",[aStation objectForKey:#"id"]);
}
also you can write less code using the fast enumeration loop:
for(NSDictionary *aStation in arrStation){
NSLog(#"id = %#",[aStation objectForKey:#"id"]);
}
hope that helps :)

The best way would be to create subclasses of NSObject that map to each tag. That would be way more cleaner than using Dictionaries and Arrays.

Related

SBJson parsing help iphone

im currently trying to parse some json data on the iphone.
I have been trawling the web for examples, but none seem to suit my purpose, i am using SBJson.
What I want is to be able to get an NSArray of Titles, Artisits, Status, etc. so that I can display them on a table view. Any help would be great, so far all i get is an array of "Values".
JSON = {"values":
[
{"Status":"N", "Filename":"RD207T04", "Title":"Simple Man (Explicit)", "Artist":"DIAFRIX F/DANIEL MERRIWE", "Release":"May11"},
{"Status":"N", "Filename":"CR221T27", "Title":"Midnight City", "Artist":"M83", "Release":"Dec11"},
{"Status":"N", "Filename":"ED211T03", "Title":"I\"ll Be Your Man", "Artist":"JAMES BLUNT", "Release":"Jul11"}
]}
You don't want an array of titles, artists, etc. You want the array of NSDictionarys represented by the values key. Then you can do:
cell.textLabel.text = [[valuesArray objectAtIndex:indexPath.row]valueForKey:#"Title"]];
inside your cellForRowAtIndexPath: delegate method. If you do not have this already, this is how to get that array:
NSArray *valuesArray = [[myJsonString JSONValue]objectForKey:#"values"];
Thanks mate, I was definately over complicating things:
The end code was this:
NSArray *valuesArray = [[playlist JSONValue] objectForKey:#"values"];
NSString *test = [[valuesArray objectAtIndex:0]valueForKey:#"Title"];
NSLog(#"test = %#", test);
Now all I have to do is iterate through the set :)

NSMutableDictionary representation for JSON

I have one genuine question which I am facing at this point and I am sure someone might be able to help me.
I have a JSON Post which looks like:
{
"CustomerAccount":{
"CustomerUID":"String content",
"UserName":"String content",
"Password":"String content",
"OldPassword":"String content",
"Email":"String content",
"QuestionUID":2147483647,
"QuestionAnswer":"String content",
"EAlerts":true
}
}
Now I have a dictionay which set's value of CustomerUID, UserName, etc.. Now if I want to bind a upper level to bind all that to CustomerAccount and send as my JSONRepresentation, is there any easier way than actually creating a new dictionary and setting a value of key "CustomerAccount" in this example? I am sure there might be a better way of doing that.
Thanks.
Not entirely sure I follow, but is this what you want maybe:
NSDictionary *dictA = <dictionary_with_customeruid_etc>;
NSDictionary *customerAccountDict = [NSDictionary dictionaryWithObjectsAndKeys:dictA, #"CustomerAccount", nil];
But I'm not sure I follow your question entirely so maybe you want something else. Please let us know a bit more about what you're trying to do.
I don't really understand your question but ill give it a try.
You can easily parse the JSON string to a NSDictionary using JSONKit https://github.com/johnezang/JSONKit
JSONKit is a very fast and lightweight library and you can parse the string and get the wanted value like this:
NSDictionary *dict = [jsonString objectFromJSONString];
NSString *value = [dict valueForKey:#"key"];
To actually set a value in your JSON string you should use rangeOfString: .location to get the range if the existing value then replaceOccurenciesOfString:[jsonString substringWithRange:NSMakeRange(loc,len)] withString:VALUE.

parsing JSON object and sub-elements on iphone app

I am building an app that uses a UPC data base API. I am getting back a JSON object, example from here: http://www.simpleupc.com/api/methods/FetchNutritionFactsByUPC.php
{
"success":true,
"usedExternal":false,
"result"
{
"calories_per_serving":"150",
"cholesterol_per_serving":"15",
"cholesterol_uom":"Mg",
"dvp_calcium":"30",
"dvp_cholesterol":"4",
"dvp_iron":"2",
"dvp_protein":"17",
"dvp_saturated_fat":"8",
"dvp_sodium":"10",
"dvp_total_fat":"4",
"dvp_vitamin_a":"10","
"dvp_vitamin_c":"0",
"dvp_vitamin_d":"25",
"fat_calories_per_serving":"25",
"fiber_per_serving":"<1",
"fiber_uom":"G",
"ingredients":"Fat Free Milk, Milk, Sugar, Cocoa (Processed With Alkali),
Salt, Carrageenan, Vanillin (Artificial Flavor),
Lactase Enzyme, Vitamin A Palmitate And Vitamin D3.",
"protein_per_serving":"8",
"protein_uom":"G",
"size":"240",
"units":"mL",
"servings_per_container":"8",
"sodium_per_serving":"230",
"sodium_uom":"Mg",
"total_fat_per_serving":"2.5",
"total_fat_uom":"G",
"trans_fat_per_serving":"0",
"trans_fat_uom":"G",
"upc":"041383096013"
}
}
My problem is with parsing the "ingredients" element, which is a sub list of the object dictionary.
How would you suggest parsing the ingredients list? If I could get it to an NSArray, assuming commas are separators, that would have been great.
I tried to do this, but looks like its just a string, so no way to parse it.
Any suggestion would be more than welcome. Thanks!
//Thats the whole JSON object
NSDictionary *json_dict = [theResponseString JSONValue];
//Getting "results" which has all the product info
NSArray *myArray = [[NSArray alloc] init];
myArray = [json_dict valueForKey:#"result"];
Now how do I get "ingredients" from myArray in an array form?
You're getting result as an array, but (in JSON terminology) it's not an array. It's an object, so use an NSDictionary. Something like this:1
NSDictionary *result = [json_dict objectForKey:#"result"];
Then you can get the inner ingredients object from that:
NSString *ingredients = [result objectForKey:#"ingredients"];
Edited as per #Bavarious' comment.
1Apologies for glaring errors, as I'm not terribly well-versed in Objective-C. You might need to allocate memory for the returned NSDictionary and NSString pointers; I'm not sure.
Here's all you need to do:
NSDictionary *json_dict = [theResponseString JSONValue];
// Use a key path to access the nested element.
NSArray *myArray = [json_dict valueForKeyPath:#"result.ingredients"];
EDIT
Whoops, Matt's right. Here's how to deal with the string value:
// Use a key path to access the nested element.
NSString *s = [json_dict valueForKeyPath:#"result.ingredients"];
NSArray *ingredients = [s componentsSeparatedByString:#", "];
Note that you might need to trim the '.' character off the last element of the array.

Get objects from a NSDictionary

I get from an URL this result :
NSString *result = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
it looks like this :
[{"modele":"Audi TT Coup\u00e9 2.0 TFSI","modele_annee":null,"annee":"2007","cilindre":"4 cyl","boite":"BVM","transmision":"Traction","carburant":"ES"},
{"modele":"Audi TT Coup\u00e9 2.0 TFSI","modele_annee":null,"annee":"2007","cilindre":"4 cyl","boite":"BVM","transmision":"Traction","carburant":"ES"}]
So it contains 2 dictionaries. I need to take the objects from all the keys from this result. How can I do this?
I tried this : NSDictionary vehiculesPossedeDictionary=(NSDictionary *)result;
and then this : [vehiculesPossedeDictinary objectForKey:#"modele"]; but this is not working.
Please help me... Thanks in advance
What you have is a JSON string which describes an "array" containing two "objects". This needs to be converted to Objective-C objects using a JSON parser, and when converted will be an NSArray containing two NSDictionarys.
You aren't going to be able to get your dictionary directly from a string of JSON. You are going to have to going to have to run it through a JSON parser first.
At this point, there is not one build into the iOS SDK, so you will have to download a third-party tool and include it in your project.
There are a number of different JSON parser, include TouchJSON, YAJL, etc. that you can find and compare. Personally, I am using JSONKit.
#MatthewGillingham suggests JSONKit. I imagine it does fine, but I've always used its competitor json-framework. No real reason, I just found it first and learned it first. I do think its interface is somewhat simpler, but plenty of people do fine with JSONKit too.
Using json-framework:
require JSON.h
...and then
NSString *myJsonString = #"[{'whatever': 'this contains'}, {'whatever', 'more content'}]";
NSArray *data = [myJsonString JSONValue];
foreach (NSDictionary *item in data) {
NSString *val = [item objectForKey:#"whatever"];
//val will contain "this contains" on the first time through
//this loop, then "more content" the second time.
}
If you have array of dictionary just assign objects in array to dictionary like
NSDictionary *dictionary = [array objectAtIndes:0];
and then use this dictionary to get values.

JSON API iphone

I need plenty of help in hanlding the JSON respond I will be getting through a web service API. It's forward geo-coding.
How do I get the number of results that was returned to me?
Also getting the the value of the result, say the 'address'.
The respond JSON data is as follow. Thanks a lot.
[
{"total":63},{
"t":"1",
"lable":"Gek Poh Shopping Centre",
"address":"762 Jurong West Street 75. (S)640762",
"street":"Jurong West Street 75",
"zip":"640762",
"long":"103.6980151847",
"lat":"1.348986165348",
"x":"355149.0357","y":
"149142.5301",
"is_prem":"0",
"pid":"47120",
"aid":"115810",
"lid":"245690",
"has_biz":"1",
"is_main_building":"1",
"id":"245690",
"cat_id":"80"
},
{
"t":"1",
"lable":"Gek Poh Ville Community Club (CC)",
"address":"1 Jurong West Street 74. (S)649149",
"street":"Jurong West Street 74",
"zip":"649149",
"long":"103.69890252806",
"lat":"1.3489703630875",
"x":"355247.7723",
"y":"149140.7302",
"is_prem":"0",
"pid":"2979",
"aid":"116734",
"lid":"127311",
"has_biz":"1",
"is_main_building":"1",
"id":"127311",
"cat_id":"14"
}
]
There's SBJson just download it and copy all the files in SBJson Group to your project and include "SBJson.h"
If your JSON data is in a NSString (dataString), you can do this:
SBJsonParser *parser = [[SBJsonParser alloc] init];
NSArray *dataArray = [parser objectWithString:dataString];
for (NSDictionary *childDic in dataArray) {
NSString *str = [childDic objectForKey:#"address"]; // Here you will get the address
}
Just a sample, Hope it helps
JSON is quite simple do deal with, once you get the hang of it. There are several JSON packages for iPhone, SBjson being one of the more popular ones.
JSON consists of values, objects, and arrays. In your example you have an array (denoted by the [] brackets) containing several objects (denoted by the {} brackets). Each object, in turn, contains several name/value pairs. With most iPhone JSON parsers the arrays will translate into NSArray objects and the objects will translate into NSDictionary objects. Individual values (not surrounded by any brackets) come through as NSString (for quoted values) or NSNumber (for numerical values not within quotes).
Once you have the result of a JSON parse you "peel the onion" a layer at a time to find your data.
To find out which type you have at any layer use isKindOfClass:
if ( [anObject isKindOfClass:[NSDictionary class]] ) ...