Processing XML on the iPhone
For Tutorial 6 I needed to process an XML document produced by a tilemap editor. I was most disappointed to find that the iPhone SDK does not come with very much in the way of classes to process XML.
The one class it does have NSXMLParser is not bad but its VERY VERY slow and uses loads of memory.
So, based on this I started to look around at what else I could use. There is plenty of chatter on forums about the lack of a good XML API on the iPhone SDK and I soon found TouchXML.
This is an Objective-C wrapper for the libxml2 library which it appears Apple themselves use. What I liked about it was that it followed the NSXML structure of the XML APIs Apple provides within Cocoa on the Mac, so the Apple docs pretty much can be used to work out how TouchXML works.
I followed the minimal instructions and managed to get it working in my project and it all seemed great, very quick and just what I needed. Then I came across a problem with xPath. For some reason I could not get my xPath expressions to work with TouchXML. I am not sure if this was a namespace issues, as my file was not using namespaces, but I could not get past this issue so I decided to keep looking.
The next API I came across was KissXML. This was created based on TouchXML although it goes further. TouchXML allows you to read XML whilst KissXML allows you to both read and write XML. KissXML was again very easy to get working in my project and again follows the NSXML API closely.
It again was quick, although it did not seem as quick as TouchXML. This time it was also able to handle my simple xPath without any problems and so this is the API I have stuck with.
I’ve not had a chance to check out many of the features yet, but it seems like a great solution to the lack of a good XML API from Apple in the SDK.
Mike
18 Comments
uprise78 on May 6th, 2009
Xpath is grossly slow and uses a ton of memory on the iPhone which is probably why Apple didn’t include it in the framework. If you like straight C there is no faster way to parse XML with less memory than SAX. Personally, I started with TouchXML and the memory footprint got me using xpath so I moved over to NSXMLParser. I’m not sure how you got NSXMLParser to be slower than TouchXML….my tests where quite the opposite. NSXMLParser was faster by a decent margin…
mike on May 6th, 2009
Hi uprise78
I was also surprised at how slow NSXMLParser was running. The only thing I can think of is that I was parsing an XML file which contained around 20k rows. With NXSMLParser it could take 15-20 seconds to process the file. With KissXML its taking 5 seconds. When processing elements I just had a number of if statements checking which element had been found and then reacted to those.
Apart from populating some arrays with objects I was creating there should have been nothing in there to really slow it down. Its basically the same kind of code I’m using now with KissXML. I read on the internet as well that others were suffering with performance problems with NSXMLParser which is what made me swtich.
You are more than Likely right about why Apple did not include it. I’m sure they didn’t want to include anything which could hammer the phone and is included in their own SDK.
I’ve not tried native SAX using C. I’ve come from a Java background recently so I’m trying to stick with Objective-C where I can unless I really need performance and then using small bits of C when necessary :O)
Thanks for the comment.
Mike
uprise78 on May 7th, 2009
If you are interested in seeing the SAX way (which is insanely fast with very low memory footprint) there is a pretty good example on Apple’s dev site.
mike on May 7th, 2009
Thanks uprise78, I’m going to check that out as fast is good.
Thanks for the info.
Mike
XML Parsing Frameworks for iPhone Development | i3U on May 16th, 2009
[...] excellent article by Mike on various XML frameworks available for iPhone SDK, particularly, TouchXML, KissXML. The article [...]
XML Parsing Frameworks for iPhone Development | i3U on May 16th, 2009
[...] excellent article by Mike on various XML frameworks available for iPhone SDK, particularly, TouchXML, KissXML. The article [...]
HarryiPhony on May 23rd, 2009
HI,
NOW I am using NSXMLParser and i am getting lots of memory leaks, actually i have to do lots of parsing, my application is like facebook. I have created one class which holds all the values coming from xml parser and this class’s object store in one array. Class holds many strings and arrays and i m getting that those are leaks..what to do? have you faced this problem?
Thanks.
mike on May 23rd, 2009
Hi HarryiPhony. I’ve not done a great deal of XML parsing on the iPhone, just what I needed to do to process the tilemap data I need.
I didn’t spot any memory leaks from NSXMLParser itself, and it sounds from your description like the memory leaks are from within a class holding an array and your string data.
If you look for leaks in intruments, when you spot one where in the code does it take you?
I have found sometimes that using [NSString stringWithFormat:@"blah"] has produced leaks. It should not as memory management is handled by NSString, but by adding another autorelease pool and emptying it myself has removed the leak problem.
That is about as much as I’ve done.
Mike
HarryiPhony on May 23rd, 2009
Hi,
Thanks for your instant reply. Actually i tried to use libxml and i got work but my xml format is some thing like,
mike
71squared
mike
71squared
mike
71squared
and libxml work based on XMLDoc and we have to pass constant char right?…if my xml format would be sinlge like then no problem but i tried to give is not working…
do u know how can i pass this element like …
i am asking for this method…and here kName_Item, i have to give key_0, key_1..but its constant char…i can’t change after key_0…
static void startElementSAX(void *ctx, const xmlChar *localname, const xmlChar *prefix, const xmlChar *URI,
int nb_namespaces, const xmlChar **namespaces, int nb_attributes, int nb_defaulted, const xmlChar **attributes)
{
XMLParser *parser = (XMLParser *)ctx;
// The second parameter to strncmp is the name of the element, which we known from the XML schema of the feed.
// The third parameter to strncmp is the number of characters in the element name, plus 1 for the null terminator.
if (prefix == NULL && !strncmp((const char *)localname, kName_Item, kLength_Item)) {
Taste *newTaste = [[Taste alloc] init];
parser.currentTaste = newTaste;
[newTaste release];
parser.parsingASong = YES;
} else if (parser.parsingASong && ( (prefix == NULL && (!strncmp((const char *)localname, kName_Title, kLength_Title) || !strncmp((const char *)localname, kName_Category, kLength_Category))) || ((prefix != NULL && !strncmp((const char *)prefix, kName_Itms, kLength_Itms)) && (!strncmp((const char *)localname, kName_Artist, kLength_Artist) || !strncmp((const char *)localname, kName_Album, kLength_Album) || !strncmp((const char *)localname, kName_ReleaseDate, kLength_ReleaseDate))) )) {
parser.storingCharacters = YES;
}
}
Thanks.
anon_anon on August 17th, 2009
xpath doesn’t have to be slow, you may want to look at vtd-xml
http://vtd-xml.sf.net
Aram on February 5th, 2010
I get a compilation error when trying to compile KissXML and Cocos2d in the same project, have anyone else experienced this problem?
It’s sad because it seems as a very clean and decent XML-library :(
mike on February 5th, 2010
Hi Aram
I’ve not tried to use KissXML with Cocod2d so can’t comment on the problem you are having.
What is it you are using KissXML for. If you just want a very quick way to read and parse XML with a nice simple API you should try TBXML (http://www.tbxml.co.uk)
This is what I am now using for parsing all my XML for tilemaps, particle emitters etc.
Mike
avanadra on June 11th, 2010
Hi!I Would love to know how to add a thumbnail image from a RSS feed to a table view– Can somebody please point me in the right direction?
mike on June 11th, 2010
If you can identify the image data inside the XML you are receiving then you should be able to use +(UIImage *)imageWithData:(NSData *)data
If the data is encoded with base64 then you could use the NSDataAdditions category that is used within TBXML to unzip the data before passing it to UIImage.
Hope that helps.
Mike
mike on June 11th, 2010
…of course, with the UIImage create you could then create your own custom UITableViewCell to display that image as you wish.
Mike
DangerWillRobinson on August 5th, 2010
@MIke:
I’m parsing data from a URL into a tableview, and pushing to a detailview. All that works fine but I can’t get the images to load in the table cell.
Is there a code snippet you can share to point me in the right directions?
Thanks!
CAC




XML Parsing Frameworks for iPhone Development | iPhone Development | iPhone Programming | iPhone Application Development | iPhone Game Development on May 6th, 2009
[...] excellent article by Mike on various XML frameworks available for iPhone SDK, particularly, TouchXML, KissXML. The article [...]