My current project is an iPhone App to be used for Boy Scout record tracking. The initial release will just contain the requirements for all ranks and merit badges. After that release, I will work on adding the capability to check off completion of each requirement. That will entail creating some custom UITableViewCells and using Core Data. Something a little bit advanced for me right now. My first goal was to get up to speed on Objective-C and the basics of UITableView. My guide for this journey has been Bill Dudney and Chris Adamson’s book iPhone SDK Development (The Pragmatic Programmers). I have been reading the book and trying out code for the better part of a week before I decided it was time to jump into my app. The basic layout will be a series of UITableViews in a Navigation based app, similar to the iPhone Mail app. First screen is just a list of Rank and Merit Badges. Selecting one of these takes you down another level showing a list of all the BSA ranks or merit badges, depending on the user’s choice. Stepping down one more level displays the requirements for their selection. Requirements were pulled from the BSA website and processed into individual XML files using Ruby and Hpricot.
After basic screen layout was completed using code samples from the iPhone SDK Development book, I was ready to start parsing the XML files to populate the screens. The ranks.xml file is just a listing of all the ranks with name and image attribute.
1 2 3 4 5 6 7 8 9 10 | |
Mine is simple, just an XML element, rank, which has two attributes, name
and img. The first thing to do before parsing your XML, make sure your XML
is valid. I spent several hours trying to determine why parsing my file was
failing. I assumed I had coded something wrong. After trying several things, I
finally took a close look and noticed something was missing. Here is the
original:
1 2 3 4 5 6 7 8 9 10 | |
Do you see what is wrong? It is missing the closing '>' after the ‘img’ attribute.
Use an XML validator like The W3C Markup Validation Service to catch
mistakes like these. Starting out with a valid XML file will make parsing a lot easier.
The predominant use of NSXMLParser is for parsing internet based XML sources like Twitter. The first step is to open your XML source.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | |
This sample code from Dudley and Adamson’s book shows that you open a
NSURLConnection which starts downloading the data. didReceiveData receives
updates as they come in and appends to tweetsData. Only after
connectionDidFinishLoading is called does the parsing start. You create a
NSXMLParser and set the delegate to self.
Elements hold most of the information in an XML document. When NSXMLParser
traverses an element in an XML document, it sends at least three separate
message to its delegate, in the following order:
1 2 | |
The parser could send parser:foundCharacters multiple times depending on XML
data size.
To handle these messages, your code must implement these methods to parse your specific XML format:
1 2 3 4 5 6 | |
My parser is slightly different in that my XML file is bundled locally with
the app. I don’t have to do the NSURLConnection code, so the NSXMLParser
instantiation is slightly different.
1 2 3 4 5 6 7 | |
Here is my delegate code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | |
I didn’t have to implement foundCharacters or didEndElement because my XML
files do not contain any element value data, just element attributes which is
easily processed in didStartElement. Here is the result:
