Parse XML iOS Tutorial

In this tutorial a xml file will be parsed using a XMLParser object. The results of the parsing will be displayed in  a Table View. This tutorial is made with Xcode 10 and built for iOS 12.

Open Xcode and create a new Single View App.

For product name, use IOSParseXMLTutorial and then fill out the Organization Name and Organization Identifier with your customary values. Enter Swift as Language and choose Next.

Remove the View Controller from the Storyboard and drag a Navigation Controller to the empty canvas. The Navigation Controller will automatically put a Table View Controller onto the storyboard. When the initial View Controller is deleted there isn't a starting point defined. Select the Navigation Controller and go to the Attribute Inspector. In the View Controller Section select the "Is Initial View Controller" checkbox.

Double-click the Title Bar of the Table View Controller and set the title to "Books". Select the Table View Cell and go to the Attributes Inspector. In the Table View Cell section set the Style Attribute to Subtitle. Also set the Cell identifier to “Cell”.

The Storyboard should look like this

Since we have deleted the View Controller from the Storyboard we can also delete the ViewController.swift file. Add a new file to the project, select iOS->Source->Cocoa Touch Class. Name it TableViewController and make it a subclass of UITableViewController.

Go to the Storyboard and select the Table View Controller. go to the Identity inspector and in the Custom Class section change the class to TableViewController. 

Add a new file to the project, select iOS->Other->Empty File. Give the fille a filename of Books.xml

Open the Books.xml file and add the following contents.

<?xml version="1.0"?>
<catalog>
    <book id="1">
        <title>To Kill a Mockingbird</title>
        <author>Harper Lee</author>
    </book>
    <book id="2">
        <title>1984</title>
        <author>George Orwell</author>
    </book>
    <book id="3">
        <title>The Lord of the Rings</title>
        <author>J.R.R Tolkien</author>
    </book>
    <book id="4">
        <title>The Catcher in the Rye</title>
        <author>J.D. Salinger</author>
    </book>
    <book id="5">
        <title>The Great Gatsby</title>
        <author>F. Scott Fitzgerald</author>
    </book>
</catalog>

Go to the TableViewController.swift file and add a new struct above the TableViewController class.

struct Book {
    var bookTitle: String
    var bookAuthor: String
}

Change the TableViewController class declaration to

class TableViewController: UITableViewController, XMLParserDelegate {

Add the following properties inside the TableViewController class

var books: [Book] = []
var elementName: String = String()
var bookTitle = String()
var bookAuthor = String()

Change the viewDidLoad method to

override func viewDidLoad() {
    super.viewDidLoad()

    if let path = Bundle.main.url(forResource: "Books", withExtension: "xml") {
        if let parser = XMLParser(contentsOf: path) {
            parser.delegate = self
            parser.parse()
        }
    }
}

The XMLParser object parses the Books.xml file inside the bundle. Add the following TableViewController delegate methods

override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
    return 1
}

override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return books.count
}
    
override func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCellWithIdentifier("Cell", forIndexPath: indexPath)
        
    let book = books[indexPath.row]
        
    cell.textLabel?.text = book.bookTitle
    cell.detailTextLabel?.text = book.bookAuthor

    return cell
}

The title and author of the books will be displayed into the Table View with the contents of the books array. Next, implement the XMLParser delegate methods.

// 1
func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {

    if elementName == "book" {
        bookTitle = String()
        bookAuthor = String()
    }

    self.elementName = elementName
}

// 2
func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?) {
    if elementName == "book" {
        let book = Book(bookTitle: bookTitle, bookAuthor: bookAuthor)
        books.append(book)
    }
}

// 3
func parser(_ parser: XMLParser, foundCharacters string: String) {
    let data = string.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)

    if (!data.isEmpty) {
        if self.elementName == "title" {
            bookTitle += data
        } else if self.elementName == "author" {
            bookAuthor += data
        }
    }
}
  1. This method is sent by the parser object when the start tag of "<book>" is encountered.

  2. This method is sent by the parser object when the end tag of "</book>" is encountered.

  3. Here the actual parsing is executed. The title and author tags will be parsed and the corresponding properties will be initialized.

Build and Run the project. Inside the TableViewController the book tiles and authors will be displayed.

You can download the source code of the IOSParseXMLTutorial at the ioscreator repository on Github.