Reading XML files is one of the common tasks we perform in our application, In this tutorial let’s see how we can use NSXMLParser to parse XML in our iPhone app.
Introduction
NSXMLParser is a forward only reader or an event driven parser. What it means is, an event is raised whenever the parser comes across a start of an element, value, CDATA and so on. The delegate of NSXMLParser can then implement these events to capture XML data. Some of the events are raised multiple times like the start of an element, value of an element and so on. Since NSXMLParser is known as an event driven parser, we can only read data at the present node and cannot go back. The iPhone only supports NSXMLParserand not NSXMLDocument, which loads the whole XML tree in memory.
Introduction
NSXMLParser is a forward only reader or an event driven parser. What it means is, an event is raised whenever the parser comes across a start of an element, value, CDATA and so on. The delegate of NSXMLParser can then implement these events to capture XML data. Some of the events are raised multiple times like the start of an element, value of an element and so on. Since NSXMLParser is known as an event driven parser, we can only read data at the present node and cannot go back. The iPhone only supports NSXMLParserand not NSXMLDocument, which loads the whole XML tree in memory.
Books Application
To understand how to use an instance of NSXMLParser, let’s create a simple navigation based application where we will list the title of the book in the table view and upon selecting a title, display the detail information in a detail view. Click here to see the sample XML file, used in this application.
To understand how to use an instance of NSXMLParser, let’s create a simple navigation based application where we will list the title of the book in the table view and upon selecting a title, display the detail information in a detail view. Click here to see the sample XML file, used in this application.
Create a new application in XCode by selecting Navigation-Based Application, I have named my app XML. Since the NSXMLParser is a forward only parser or an event driven parser, we need to store the data locally, which can be used later. To store this data, we will create a class which replicates the elements and attributes in the XML file. An instance of this class represents one single Book element in the XML file. I have named this class “Book” and its source code is listed below
Notice that the name of the property is the same as the element name in the XML file. Since the XML file has n number of Book elements, we need an array to hold all the books we read, so we declare an array in the application delegate and this is how the source code changes
The Delegate
To keep the source code clean, we will also declare a delegate, which will be used by the instance of NSXMLParser and this how its source code looks like
To keep the source code clean, we will also declare a delegate, which will be used by the instance of NSXMLParser and this how its source code looks like
Let’s look at how the variables will be used. currentElementValue holds the current element value, appDelegate so we can access the array which holds the list of books and finally a reference to the Book class itself. Notice that we do not keep track of the current element name being processed, because the event will tell us that. Finally, we have a constructor called initXMLParser and let’s see what it does
Very simple, gets a reference to the application delegate and returns itself.
Parsing the XML File
Now that we have everything set up, let’s look at the code to read the XML file
Now that we have everything set up, let’s look at the code to read the XML file
The code is very simple, we create an instance of NSURL, create an instance of NSXMLParser, initialize the delegate, assign the delegate and start parsing by passing theparse message. It returns YES, if the parsing is successful, NO if there is an error or if the operation is aborted.
Parsing the start of an element
The delegate of the parser does not have to implement all the methods that it raises, so we can pick and choose which events we care about. If we do not want to handle the event when the parser starts reading the document, we can choose to ignore it by not implementing it. We will only implement three methods which is called when the parser encounters the start of an element, end of an element or value of an element.
Parsing the start of an element
The delegate of the parser does not have to implement all the methods that it raises, so we can pick and choose which events we care about. If we do not want to handle the event when the parser starts reading the document, we can choose to ignore it by not implementing it. We will only implement three methods which is called when the parser encounters the start of an element, end of an element or value of an element.
Let’s look at parser:didStartElement:namespaceURI:qualifiedName:attributes method which is called when the parser encounters the start of an element.
From the above code we first initialize the array when it encounters the “Books” element, which can also be done in parserDidStartDocument method. If the element is “Book” then we initialize the local book object and read the attribute of the present XML book element from the attribute dictionary object.
Parsing an element’s value
Now that we have a local book object representing the current book element in the XML tree, the next thing to do is to populate the local object with the XML data. The parser now moves to the title element and the same method is called again, but this time we do not do anything. Parser then moves to the element value and it sends parser:foundCharactersevent to the delegate, let’s see how the code look like
Now that we have a local book object representing the current book element in the XML tree, the next thing to do is to populate the local object with the XML data. The parser now moves to the title element and the same method is called again, but this time we do not do anything. Parser then moves to the element value and it sends parser:foundCharactersevent to the delegate, let’s see how the code look like
The code is very easy to read, if the mutable string is nil then we initialize it with the string parameter. If the currentElementValue is not nil then we simply append the data to the existing string value.
Parsing the end of an element
The parser now moves to the end of the element and henceparser:didEndElement:namespaceURI:qualifiedName is sent to the delegate. This is where we set the currentElementValue to the correct property of the local book object and set the currentElementValue to nil. This is how the code looks like
The parser now moves to the end of the element and henceparser:didEndElement:namespaceURI:qualifiedName is sent to the delegate. This is where we set the currentElementValue to the correct property of the local book object and set the currentElementValue to nil. This is how the code looks like
If the element it encounters is “Books” then there is nothing to do as we are almost done reading the file. If the element name is “Book” then we add the book object to the array and set the local book object to nil and release its memory, so it can be used again. If the end element is not “Books” or “Book” then it must be one of the sub element of “book” and we set the currentElementValue to the current book property using setValue:forKey. We can do this, because the properties declared in the book is the same as the XML element names.
The cycle starts again by initializing the book object and reading the attribute, reading the children elements and setting its value to the local object and finally adding the object to the array. The parser calls the three functions again and again as long as it does not encounters eof.
Complete listing of XMLParser.m file
This is how the data looks like in the table view and the detail view controller.
The data is then shown in a UITableView with a detail view, the complete code is not shown here but you can download the source code and to get a better understanding UITableView, you can follow my suggested readings below.
Summary
Reading XML files is very easy and it can be done with only three methods as seen above. I hope this tutorial has got you started in reading XML files.
Reading XML files is very easy and it can be done with only three methods as seen above. I hope this tutorial has got you started in reading XML files.
No comments:
Post a Comment