Choosing the Right iOS Xml Parser

Choosing the right IOS XML parser

Best comparison I've seen on the subject:

http://www.raywenderlich.com/553/how-to-chose-the-best-xml-parser-for-your-iphone-project

The difference between the slowest and fastest parsers in his case was a factor of 2. Depending on your feature requirements, there are definitely parsers that can cut your parsing time in half.

iOS XML Parser - Which one?

I would recommend to use TBXML as it takes lowest time comparatively to parse a document. To implement this surely you need multi-threading(GCD). You can implement this like lazy-loading concept, adding more rows as scroll reach to last.

XML Parsing in iPhone

You should use the following methods:

- (void)parseXMLFileAtURL:(NSString *)URL { //own method from me, URL could be local file or internet website 
itemsOfFeed = [[NSMutableArray alloc] init];
NSURL *xmlURL = [NSURL URLWithString:URL];
feedParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];
[feedParser setDelegate:self];
[feedParser setShouldProcessNamespaces:NO];
[feedParser setShouldReportNamespacePrefixes:NO];
[feedParser setShouldResolveExternalEntities:NO];
[feedParser parse];
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
//in case of an error
}

- (void)parserDidStartDocument:(NSXMLParser *)parser {
// start to parse xml
}

-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
feedElement = [elementName copy];
if([elementName isEqualToString:@"item"]) { //main xml tag
item = [[NSMutableDictionary alloc] init];
feedTitle = [[NSMutableString alloc] init];
feedDate = [[NSMutableString alloc] init];
feedText = [[NSMutableString alloc] init];
feedLink = [[NSMutableString alloc] init];
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if([feedElement isEqualToString:@"title"]) {
[feedTitle appendString:string];
} else if([feedElement isEqualToString:@"link"]) { // some examples of tags
[feedLink appendString:string];
} else if([feedElement isEqualToString:@"content:encoded"]) {
[feedText appendString:string];
} else if([feedElement isEqualToString:@"pubDate"]) {
[feedDate appendString:string];
}
}

- (void) parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if([elementName isEqualToString:@"item"]) {
[item setObject:feedTitle forKey:@"title"];
[item setObject:feedDate forKey:@"date"];
[item setObject:feedText forKey:@"text"];
[item setObject:feedLink forKey:@"link"];
[itemsOfFeed addObject:item];
}
}

- (void)parserDidEndDocument:(NSXMLParser *)parser {
[self.myTableView reloadData]; // for example reload table view
[self writeArrayToFile]; //or write to a local property list
}

in your header file:

NSMutableArray *itemsOfFeed;
NSXMLParser *feedParser;
NSMutableDictionary *item;
NSMutableString *feedElement;
NSMutableString *feedTitle, feedDate, feedText, feedLink; //strings of your tags

Then you have:

  • NSArray
    • NSDictionary
      • object a
      • object b
      • object c

Just access 'object a' and put it in your text field

hopefully this code example helps you

How can I improve the XML parsing performance of my iOS code?

Your parsing logic is quite inefficient - you are doing the same test over and over again by saying

if (string and x) do this
if (string and y) do this
if (string and z) do this

Instead of

if (string)
if (x) do this
if (y) do this
if (z) do this

All those unnecessary string comparisons are probably why your parsing is so slow. Same goes for all the object lookups. If you need a value multiple times, get it once and then store it in a variable.

Objective C method calls are relatively slow and can't be optimised away by the compiler, so if the value doesn't change you should call the method once and then store it.

So for example, this:

if([elementName isEqualToString:@"string"] && [[attributeDict objectForKey:@"name"] isEqualToString:@"id"]){
if(categoryFound){
categoryIdFound = YES;
}
else{
subscriptionIdFound = YES;
}
}
if([elementName isEqualToString:@"string"] && [[attributeDict objectForKey:@"name"] isEqualToString:@"title"]){
subscriptionTitleFound = YES;
}
if([elementName isEqualToString:@"string"] && [[attributeDict objectForKey:@"name"] isEqualToString:@"label"]){
categoryLabelFound = YES;
}
if([elementName isEqualToString:@"string"] && [[attributeDict objectForKey:@"name"] isEqualToString:@"htmlUrl"]){
subscriptionHtmlURLFound = YES;
}

Could be rewritten as this:

NSString *name = [attributeDict objectForKey:@"name"];
if([elementName isEqualToString:@"string"])
{
if ([name isEqualToString:@"id"])
{
if(categoryFound){
categoryIdFound = YES;
}
else{
subscriptionIdFound = YES;
}
}
else if ([name isEqualToString:@"title"])
{
subscriptionTitleFound = YES;
}
else if ([name isEqualToString:@"label"])
{
categoryLabelFound = YES;
}
else if ([name isEqualToString:@"htmlUrl"])
{
subscriptionHtmlURLFound = YES;
}
}

Which is way more efficient.

Ipad XML parsing doubts

There is a built in XML parsing class in iOS called NSXMLParser. As an init parameter it takes an NSData that is usually the data you get back from a web service. Assign yourself as its delegate and call [parser parse] and it will call your delegate when it encounters an element, when it finishes an element, etc. See documentation for the parser and its delegate protocol.

If you have control over the structure of your XML, I've found it easier when it's structured like this:

<Element attr1='value1' attr2='value2' />

instead of:

<Element>
<attr1>value1</attr1>
<attr2>value2</attr2>
</Element>

The reason is that the callback for when it finds an element is:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI
qualifiedName:(NSString *)qualifiedName
attributes:(NSDictionary *)attributeDict

where attributes is a dictionary of the values, so in the above example, [attributes objectForKey:@"attr1"] would give you "value1" if it was structured in the first way. If it's the second way, you end up doing lots of state management that's a bit of a pain, especially if you've got elements within elements, etc.

In addition to NSXMLParser thare are open-source parsers that either do everything themselves or wrap the built-in parser. I've written my own wrapper for it before. See here for a post on the subject (thanks to this question for the link).

Parsing data in an iOS app using XML or JSON parser

Just to add onto what others have already said in the comments:

Ideally you'll want to always connect asynchronously, using NSURLConnection's Delegate which will not block the main thread. If you're not already aware, iOS will force quit applications that block the main thread for too long a time. Synchronous connections can be ok in certain instances, but I'd say over 90% of the time you'll want asynchronous.

That said, asynchronous connections cause their own set of headaches. If you need to have data before allowing your users access to the application interface, you'll need to throw up loading screens and then remove them. You'll need to manage canceling requests if the user moves to a different part of the application that starts a new request. You'll also want to determine if any ongoing requests need to be registered for background completion in the event the user backgrounds the app.

On the JSON parsing side of things, it's always recommended to use NSData when you can, as converting JSON from NSString adds a lot of overhead from NSString itself. I personally do NOT use Apple's provided JSON parser, but the excellent JSONKit as it's faster than even Apple's binary plist parser. It does however require that your JSON adhere very strictly to the JSON RFC, and that it be UTF-8/16/32 encoded, not ASCII. This is fairly standard amongst the faster JSON parsers available.

Avoid XML all together when possible. The built-in iPhone parser is a SAX-style parser only, which is obnoxious to implement. If you must use XML, take a look at Ray Wenderlich's XML parser comparison and choose an appropriate one. If you have a large XML document to parse though, SAX is probably your only option given the limited processing capabilities of iDevices.

--EDIT--

One of the commenters mention SBJSON. I'd recommend against that entirely. It's slower than Apple's JSON parser (which has been available since iOS 5), and is much slower then JSONKit and several others by an order of magnitude. I specifically moved my current enterprise-level iOS Application off of SBJSON because of errors I was receiving in the JSON parsing as well.

Xml parsing in iOS tutorial

Use TBXml parser..That is the easiest way and also less time taken to parse a value..U can download TBXMLDemo project on github and to print that instead of label u can use table view cell and make it selection as null.So that it looks simillarly like label.If u need more details comment me,..i'll be helping it..

How To Parse XML in Cocoa?

You can access the value enclosed within tags by intelligently using this delegate method ;):

 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string

This link can prove to be useful - Handling XML Elements and Attributes



Related Topics



Leave a reply



Submit