NSXMLParser seems highly inefficient

Discussion in 'iOS Programming' started by CaptSaltyJack, Jul 2, 2009.

  1. CaptSaltyJack macrumors 6502

    Joined:
    Jun 28, 2007
    #1
    ..or I just don't understand it.

    Why have all these crazy delegate methods like didStartElement, foundCharacters, foundComment... I mean, let's say foundCharacters gets called. It has NO idea what element the string belongs to, right?

    I don't understand why there's not just a method for NSXMLParser that parses everything and returns a single data object like an NSDictionary or NSSet, etc. I just want to grab XML data via the web and have all of that data very easily accessible in some sort of data structure.

    Could someone explain the methodology behind NSXMLParser and how to use the delegates to assemble data?
     
  2. dejo Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #2
    See the XML Performance sample app which explorers two different approaches to parsing XML. NSXMLParser uses an event-driven approach which allows you to handle things differently "on-the-fly", if needed.
     
  3. Luke Redpath macrumors 6502a

    Joined:
    Nov 9, 2007
    Location:
    Colchester, UK
    #3
    NSXMLParser is far from inefficient, in fact it, and other streaming XML parsers are about as efficient as it gets which is why its the only XML parser available in the SDK due to the iPhone's limited resources.

    Of course, it requires more work to use than a DOM parser. A DOM parser loads the entire XML into memory in order to parse it. A streaming parser is event driven - the delegate methods represent events that occur as the document is parsed from beginning to end and it is up to you to respond to them.

    Well no, not in isolation, but before it calls that it must have sent a 'didStartElement' message; you need to create your own context and record the current element so the subsequent calls to foundCharacters know which element it belongs to.

    I suggest you have a good read of Apple's own Introduction to Event-Driven XML Programming.
     
  4. Peter Maurer macrumors member

    Joined:
    Oct 9, 2008
    #4
    That's precisely what the delegate is for. You could, for instance, create your own NSObject subclass that has properties for those things in the XML code you're interested in.

    I'm far from being an XML expert, but XML just doesn't always map directly to Cocoa data types. Think of element attributes, for instance -- Cocoa's collection types don't have those. So you'll have to decide how to handle these things. You may actually have your own data types for some elements, so you'll obviously have to do the mapping yourself. And that's what you do in your delegate. (Another way Apple could have chosen to deal with this would have been subclassing NSXMLParser all the time. Personally, I'm glad they didn't, though, because delegates tend to be much more flexible.)

    Anyway, NSXMLParser only deals with the formal XML code for you and gives you the series of elements it sees. Converting those elements into a Cocoa data structure would mean interpreting the XML code semantically, and NSXMLParser just can't do that for you. After all, that XML it's parsing could mean anything.
     
  5. CaptSaltyJack thread starter macrumors 6502

    Joined:
    Jun 28, 2007
    #5
    Hmm, makes sense...though I'll admit it's quite a bit foreign to me. Guess I've been spoiled with PHP calls like $data = json_decode($jsonData). ;)

    I'll check out the links and start putting together some practice apps. Thanks!
     
  6. Troglodyte macrumors member

    Joined:
    Jul 2, 2009
    #6
    If you really really need to load the whole XML in to memory and parse it then there are third party libraries that do it (usually as a wrapper around libxml). I've used Google's and it works well as a drop in replacement of the important bits of NSXMLDocument (which is missing on the iPhone).

    http://code.google.com/p/gdata-objectivec-client/

    You need the GDataXMLNode class and the GDataDefines.

    If you're writing something from scratch then use NSXMLParser as it's much more lightweight. If you're porting something (as I was) and can get away with it then the Google stuff is there as an alternative.
     

Share This Page