0

I am working on trying to parse some XML data to a tableView and I keep coming up with my string being empty, thus not allowing me to populate a tableView. I have checked all over online trying to find good example on how to achieve this but everything seems to be out of date due to swift changing all the time.

<?xml version="1.0" encoding="UTF-8"?>
<client region = "Midwest">
<person
name = "Pete Seeger"
profession = "Musician"
dob = "May 3, 1919">
<child
name = "Daniel">
</child>
<child
name = "Mika">
</child>
<child
name = "Tinya">
</child>
</person>
</client>

Next is my Client.swift file

class Client{
var clientName: String = String()
var clientProfession: String = String()
var clientDob: String = String()}

and in my ViewController I have declared these variables

var client: [Client] = []
var eName: String = String() //element Name
var cName: String = String()
var cProfession: String = String()
var cDOB: String = String()

Preceding is my didStart/didEnd/and foundCharacters

 func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
    //this finds the starting tag of <person>
    eName = (elementName as NSString) as String
    if eName == "person"{
        print("we found start tag of person")
        cName = String()
        cProfession = String()
        cDOB = String()
}

 func parser(_ parser: XMLParser, didEndElement elementName: String, namespaceURI: String?, qualifiedName qName: String?)
{
    //this looks for the end tag </person>
    if eName == "person"{
        print("we found End tag of person")
        let client = Client() //letting the client = to w.e
        print(client, "printing client in the didEndElement")
        client.clientName = cName
        print(cName, "This is the cName though nothing will show I bet...")
        client.clientProfession = cProfession
        client.clientDob = cDOB
    }
func parser(_ parser: XMLParser, foundCharacters string: String)
{

let foundChar = string.trimmingCharacters(in: NSCharacterSet.whitespacesAndNewlines)

    print(foundChar, "This is foundChar for foundCharacters")
    if(foundChar.isEmpty){
        print("its empty")
        }
        else{
            if eName == "name"{
                cName += foundChar
                cProfession += foundChar
                cDOB += foundChar
        }

    }

I am finding the beginning tags and closing tags for person, but once it gets to the foundCharacters it seems that it is returning empty. Am I overlooking something here?

Kolorbox
  • 1
  • 2
  • 1
    You might want to try this: https://github.com/tadija/AEXML – Daniel Nov 15 '17 at 07:31
  • Check this it might help in your scenario : https://stackoverflow.com/questions/29937456/swift-parsing-attribute-name-for-given-elementname – Amit Nov 15 '17 at 09:35
  • All of these examples online are using NSXML functions and calls, and I understand that some you should be able to remove the NS and it will function correctly but I am still left with examples that are identical to how I have mine set up with no progress. – Kolorbox Nov 16 '17 at 21:37

1 Answers1

0

You are looking for your data at the wrong place.

parser(_:foundCharacters:) function is getting called for text that is in between open and close tags.

For the following example XML:

<name>Pete Seeger</name>

parser(_:foundCharacters:) function will be called with foundCharacters = "Pete Seeger"

The data that you are looking for is in element's attributes. Just check the attributeDict parameter in parser(_:didStartElement:namespaceURI:qualifiedName:attributes:) function.

func parser(_ parser: XMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String] = [:]) {
    //this finds the starting tag of <person>
    eName = (elementName as NSString) as String
    if eName == "person"{
        print("we found start tag of person")
        cName = attributeDict["name"] ?? ""
        cProfession = attributeDict["profession"] ?? ""
        cDOB = attributeDict["dob"] ?? ""
    }
}

Also, if you are interesting in mapping the XML into swift objects consider XMLMapper. (uses the same technique as the ObjectMapper)

Hope this helps.

gcharita
  • 7,729
  • 3
  • 20
  • 37