views:

1324

answers:

1

Hi Everyone:

Today I am looking into how to make a simple XML parser in Cocoa (for the desktop). I am thinking of using NSXMLParser to parse the data, but am not quite sure where to start. The XML file on the web doesn't have the much data in it, just a simple listing with a few things that I need to save into a variable. Does anyone have any suggestions on how to do this, as the online documentation about this isn't making too much sense.

Thanks for any help!

EDIT The reason why I am wanting to create an XML parser is to get information from a MYSQL database on a server to the client application. If there is some better way to do this besides a XML parser, please let me know!

+15  A: 

Here's how it works:

There's a class called NSXMLParser. It's used to parse XML files. However, NSXMLParser is stupid. All it knows how to do is parse XML, but it doesn't know what it's supposed to do with the information it finds.

Enter a delegate. A delegate is like a nanny. Since the XMLParser doesn't have a clue what to do with the information it finds, it goes and asks its delegate about each and every thing: "Hey! I started parsing a document! Am I supposed to do anything?" "Hey! I found some CDATA! What am I supposed to do with it!" "Hey! I found another tag!" "Hey! I found a closing tag!", and so on. All of these "Hey!" statements are delegate methods, or in other words, they are optional methods that a delegate object may choose to implement. Usually (but not always), the object that creates the NSXMLParser is also the delegate, but that doesn't have to be the case.

So you might have something like this:

NSXMLParser * parser = [[NSXMLParser alloc] initWithContentsOfURL:someURLToAnXMLFile];
[parser setDelegate:self];
[parser parse];
[parser release];

Then in that same object (self), you might have some of these methods:

- (void)parserDidStartDocument:(NSXMLParser *)parser {
  //the parser started this document. what are you going to do?
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
  //the parser found an XML tag and is giving you some information about it
  //what are you going to do?
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
  //the parser found some characters inbetween an opening and closing tag
  //what are you going to do?
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {
  //the parser finished. what are you going to do?
}

There are a whole bunch of these methods listed in the documentation. Simply go to the NSXMLParser class reference, and they're all listed under the "Delegate Methods" section. Once you get the hang of it, NSXMLParser is pretty easy to use. It is a SAX Parser, which means it's event-driven parser. It finds stuff, and it tells you about it.

Dave DeLong
Thanks Dave: Really helpful! And, for the future, would you recommend using XML or MYSQL for database/client communications?
PF1
I'd probably use both. If I needed a client-server connection, and I controlled both ends, I'd probably keep the data in a MySQL database, then access it with some PHP scripts that spit out the appropriate data that's formatted as XML (Plist XML specifically, so I could do things like NSArray * myArray = [NSArray arrayWithContentsOfURL:urlToMyPHPScript];)
Dave DeLong
@Dave How would I format XML as a PLIST, and would that mean that I could just make a NSDictionary and sort through like that?I have also been trying some stuff with NSXMLParser, and am wondering how you would suggest using the commands that you posted above to associate the element and the found characters. For instance, you know that "Some description" is in the element "Description".Thanks for all your help.
PF1
@PF1 to get the idea of the plist format, open up a .plist file in ~/Library/Preferences. Then just have a PHP script that pulls stuff out of your DB and echos text that looks like a plist. If you want a specific example, you can contact me directly. =)
Dave DeLong
@Dave Just looked at some PLIST files - Doesn't seem to have too much of a difference to regular XML. And as far the PHP part, seems pretty simple (I knew PHP before I learned Cocoa). :) If I have any other questions/want examples, I'll either post here or drop you an email.
PF1
@Dave I was just playing around with NSXMLParser. But unfortunately, I still can't figure out how to associate the element and the found string with the contents of the elements. For instance, you know that "Some description" is in the element "Description". Thanks again for all your help!
PF1
Dave DeLong
@Dave Totally fine, no pressure. I just also wanted to post here in case some spam filter blocked my email. Believe me, it happens.
PF1
Also Dave, if it isn't possible to do what I was saying, is there some way to change the names of the methods (ex. parserDidEndDocument1 and parserDidEndDocument2) and call these depending on what XML document you are calling?
PF1
Great description of delegates. I was wondering why you `[parser autorelease]` instead of `[parser release]`?
nevan
@nevan - i was under the impression that `NSXMLParser` would spawn a thread for parsing, but a quick test shows that to be incorrect.
Dave DeLong