Karl Kivi
Karl Kivi

Reputation: 145

NSXMLParser not reading all elements

I need to parse a xml file which content can be found on this site: http://jpg.tartu.ee/tunniplaan/xml/arvestus1.xml ( In order to see this file you must look at the page source code! (The file is too big to post in here)

I first download this file and then my application reads the data in.

I am using NSXMLParser. From that file above I need element TimeTableSchedule attributes, but NSXMLParser does not find that element in the file, but it does exist.

I checked if it finds element named TimeTableSchedule with below code, but it does not! It prints out all the other elements except "TimeTableSchedule"

func parser(parser: NSXMLParser, didStartElement elementName: String, namespaceURI: String?, qualifiedName qName: String?, attributes attributeDict: [String : String]) {
        print(elementName)
    }

My questions is: Why it does not find the element TimeTableSchedule? Is it something to do with that TimeTableSchedule element has two attributes called Period? Is there any way I can access TimeTableSchedule elements attributes using NSXMLParser

Upvotes: 1

Views: 209

Answers (1)

Rob
Rob

Reputation: 437622

Yes, the problem is that the XML is not well formed. It includes something like:

<TimeTableSchedule DayID="" Period="" Period="-1" SchoolRoomID="" SubjectGradeID="*28" ClassID="*11" OptionalClassID="" TeacherID=""/>

The attribute Period appears twice in that element. In fact, if you implemented NSXMLParserDelegate method parseErrorOccurred you would have seen an error to that effect. Or you can use the command line program xmllint to check the XML.


Given that you cannot fix the XML on the web service, you could theoretically fix it yourself in the client:

let url = NSURL(string: "http://jpg.tartu.ee/tunniplaan/xml/arvestus1.xml")!
let task = NSURLSession.sharedSession().dataTaskWithURL(url) { data, response, error in
    guard let data = data where error == nil else {
        print(error)
        return
    }

    // replace occurrences of `Period="" Period` with `Period`

    let mutableData = data.mutableCopy() as! NSMutableData
    let searchData = "Period=\"\" Period".dataUsingEncoding(NSUTF8StringEncoding)!
    let replacementData = "Period".dataUsingEncoding(NSUTF8StringEncoding)!

    var range = mutableData.rangeOfData(searchData, options: [], range: NSRange(location: 0, length: mutableData.length))
    while range.location != NSNotFound {
        mutableData.replaceBytesInRange(range, withBytes: replacementData.bytes, length: replacementData.length)
        range = mutableData.rangeOfData(searchData, options: [], range: NSRange(location: range.location, length: mutableData.length - range.location))
    }

    // now parse

    let parser = NSXMLParser(data: mutableData)
    parser.delegate = self
    parser.parse()

    // do whatever you want with the parsed data here
}
task.resume()

Upvotes: 1

Related Questions