2

I'm trying to learn XMLMapper, So I thought of using my W3 Schools XML example about books to try and map them my self.

So I'm trying to print title, author from an array of Books.

Books.XML

<?xml version="1.0" encoding="utf-8"?>
<bookstore>
    <book>
        <title>Everyday Italian</title>
        <author>Giada De Laurentiis</author>
        <year>2005</year>
        <price>30.00</price>
    </book>
    <book>
        <title>Harry Potter</title>
        <author>J K. Rowling</author>
        <year>2005</year>
        <price>29.99</price>
    </book>
    <book>
        <title>XQuery Kick Start</title>
        <author>James McGovern</author>
        <author>Per Bothner</author>
        <author>Kurt Cagle</author>
        <author>James Linn</author>
        <author>Vaidyanathan Nagarajan</author>
        <year>2003</year>
        <price>49.99</price>
    </book>
    <book>
        <title>Learning XML</title>
        <author>Erik T. Ray</author>
        <year>2003</year>
        <price>39.95</price>
    </book>
</bookstore>

BooksXMLMappable.swift file:

import Foundation
import XMLMapper

class BookStore: XMLMappable {
    required init?(map: XMLMap) {
        //Empty
    }

    var nodeName: String!

    var books: [Book]?

    func mapping(map: XMLMap) {
        books <- map["book"]

    }

}

class Book: XMLMappable {
    required init?(map: XMLMap) {
        //Empty
    }

    var nodeName: String!

    var title: String!
    var author: String?
    var year: Int?
    var price: Double?


    func mapping(map: XMLMap) {
        //category <- map.attributes["category"]
        title <- map["title"]
        author <- map["author"]
        year <- map["year"]
        price <- map["price"]
    }

}

Now I tried to run this in my ViewController's ViewDidLoad:

let storeObject = XMLMapper<BookStore>().map(XMLfile: "books.xml")
        print(storeObject?.books?.first?.author ?? "nil")

And I have successfully printed author for the first book, but I can't find a way to print author's of all the books without getting nil.

And if a book has multiple authors which one will be printed and how to print them all ?

Sorry if my question is too easy to solve, or a very basic one, but I'm trying to learn.

Thanks in advance.

Hussein
  • 487
  • 6
  • 22

2 Answers2

2

You are getting a nil in author value, in the third book, because there are more than one authors.

Since version 1.4.4 of XMLMapper you can map those cases using an Array.

In your case, specifically, you can map the author tag using an Array of String like:

class Book: XMLMappable {
    required init?(map: XMLMap) {
        //Empty
    }

    var nodeName: String!

    var title: String!
    var authors: [String]?
    var year: Int?
    var price: Double?


    func mapping(map: XMLMap) {
        //category <- map.attributes["category"]
        title <- map["title"]
        authors <- map["author"]
        year <- map["year"]
        price <- map["price"]
    }
}

Then you can access all the authors, looping the authors Array.

Hope this helps.

gcharita
  • 7,729
  • 3
  • 20
  • 37
1

used for in loop for print author like this

let storeObject = XMLMapper<BookStore>().map(XMLfile: "books.xml")
for book in storeObject.books {
      print(book.author)
}
Sabbir Ahmed
  • 351
  • 1
  • 13
  • Worked thanks, any idea how to remove "Optional" word in console ? isn't adding explanation mark to (storeObject?.books)! should removes Optional ? – Hussein Nov 01 '18 at 21:47