Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7408549
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 29, 20262026-05-29T05:56:12+00:00 2026-05-29T05:56:12+00:00

This may have been asked a lot but I’m still lost. I need to

  • 0

This may have been asked a lot but I’m still lost. I need to parse an XML file that I retrieve from Google Reader’s API. Basically, it contains objects such as below :

<object>
    <string name="id">feed/http://developer.apple.com/news/rss/news.rss</string>
    <string name="title">Apple Developer News</string>
    <list name="categories">
        <object>
            <string name="id">user/17999068807557229152/label/Apple</string>
            <string name="label">Apple</string>
        </object>
    </list>
    <string name="sortid">DB67AFC7</string>
    <number name="firstitemmsec">1317836072018</number>
    <string name="htmlUrl">http://developer.apple.com/news/</string>
</object>

I have tried with NSXMLParser and it works but it is really slow. Maybe my code is not the most efficient but still, it can take more than 10 second to parse and save an object into Core Data. I also have taken a look a several other libraries but their use seem a bit complicated and heavy for such a small XML file.

What do you think I should use ?

Thank you.

EDIT

Here the parser code:

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

    if([elementName isEqualToString:@"list"] && [[attributeDict objectForKey:@"name"] isEqualToString:@"subscriptions"]){
        subscriptionListFound = YES;
    }

    if(subscriptionListFound){
        if([elementName isEqualToString:@"list"] && [[attributeDict objectForKey:@"name"] isEqualToString:@"categories"]){
            categoryFound = YES;
            currentCategoryId = [[[NSMutableString alloc] init] autorelease];
            currentCategoryLabel = [[[NSMutableString alloc] init] autorelease];
        }
        if([elementName isEqualToString:@"object"] && !subscriptionFound && !categoryFound){
            subscriptionFound = YES;
            currentSubscriptionTitle = [[[NSMutableString alloc] init] autorelease];
            currentSubscriptionId = [[[NSMutableString alloc] init] autorelease];
            currentSubscriptionHtmlURL = [[[NSMutableString alloc] init] autorelease];
        }
        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;
        }
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {   

    if([elementName isEqualToString:@"list"] && !categoryFound){
        subscriptionListFound = NO;
    }

    if([elementName isEqualToString:@"list"] && categoryFound){
        categoryFound = NO;
    }

    if([elementName isEqualToString:@"object"] && !categoryFound && subscriptionFound){        
        [self saveSubscription];
        [[NSNotificationCenter defaultCenter] postNotificationName:@"currentSubscriptionNotification" object:currentSubscriptionTitle];
        subscriptionFound = NO;
    }

    if([elementName isEqualToString:@"string"]){
        if(subscriptionIdFound == YES) {
            [currentSubscriptionId appendString:self.currentParsedCharacterData];
            subscriptionIdFound = NO;
        }
        if(subscriptionTitleFound == YES) {
            [currentSubscriptionTitle appendString:self.currentParsedCharacterData];
            subscriptionTitleFound = NO;
        }
        if(subscriptionHtmlURLFound == YES) {
            [currentSubscriptionHtmlURL appendString:self.currentParsedCharacterData];
            subscriptionHtmlURLFound = NO;
        }
        if(categoryIdFound == YES) {
            [currentCategoryId appendString:self.currentParsedCharacterData];
            categoryIdFound = NO;
        }
        if(categoryLabelFound == YES) {
            [currentCategoryLabel appendString:self.currentParsedCharacterData];
            categoryLabelFound = NO;
        }
    }

    [self.currentParsedCharacterData setString:@""];
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    [self.currentParsedCharacterData appendString:string];
}

Here the code to save by means of CoreData:

- (void) saveSubscription {

    NSFetchRequest *fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
    [fetchRequest setEntity:
     [NSEntityDescription entityForName:@"Group" inManagedObjectContext:context]];
    [fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"(id == %@)",self.currentCategoryId]];
    [fetchRequest setSortDescriptors: [NSArray arrayWithObject:
                                        [[[NSSortDescriptor alloc] initWithKey: @"id"
                                        ascending:YES] autorelease]]];

    NSError *error2 = nil;
    NSArray *foundGroups = [context executeFetchRequest:fetchRequest error:&error2];

    if ([foundGroups count] > 0) {
        self.currentGroupObject = [foundGroups objectAtIndex:0];
    }
    else {
        self.currentGroupObject = [NSEntityDescription insertNewObjectForEntityForName:@"Group" inManagedObjectContext:context];
        [self.currentGroupObject setId:self.currentCategoryId];
        [self.currentGroupObject setLabel:self.currentCategoryLabel];
    }

    fetchRequest = [[[NSFetchRequest alloc] init] autorelease];
    [fetchRequest setEntity:
     [NSEntityDescription entityForName:@"Subscription" inManagedObjectContext:context]];
    [fetchRequest setPredicate: [NSPredicate predicateWithFormat: @"(id == %@)", self.currentSubscriptionId]];
    [fetchRequest setSortDescriptors: [NSArray arrayWithObject:
                                       [[[NSSortDescriptor alloc] initWithKey: @"id"
                                                                    ascending:YES] autorelease]]];

    error2 = nil;
    NSArray *foundSubscriptions = [context executeFetchRequest:fetchRequest error:&error2];

    if ([foundSubscriptions count] > 0) {
        self.currentSubscriptionObject = [foundSubscriptions objectAtIndex:0];
    }
    else {
        self.currentSubscriptionObject = [NSEntityDescription insertNewObjectForEntityForName:@"Subscription" inManagedObjectContext:context];
        [self.currentSubscriptionObject setId:self.currentSubscriptionId];
        [self.currentSubscriptionObject setTitle:self.currentSubscriptionTitle];
        [self.currentSubscriptionObject setHtmlURL:self.currentSubscriptionHtmlURL];
        NSString *faviconURL = [self favIconUrlStringFromURL:self.currentSubscriptionHtmlURL];
        NSString *faviconPath = [self saveFavicon:self.currentSubscriptionTitle url:faviconURL];
        [self.currentSubscriptionObject setFaviconPath:faviconPath];
        [self.currentSubscriptionObject setGroup:self.currentGroupObject];
        [self.currentGroupObject addSubscriptionObject:self.currentSubscriptionObject];
    }

    NSError *error;
    if (![context save:&error]) {
        NSLog(@"Whoops, couldn't save: %@", [error localizedDescription]);
    }
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-29T05:56:13+00:00Added an answer on May 29, 2026 at 5:56 am

    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.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I'm aware that this question may have been asked before, but I still haven't
This question may have been asked before, but I had trouble finding an answer,
This has / may have been asked before, but, as far as I remember,
This may have been asked before, but I could not find the answer. I
this question may have been asked many times, but could not find any suitable
This question may have been asked already - but unfortunately, I could not find
This question may have been asked before, but I'm starting to get into game
This may have been asked already, but I can't find it, so here goes.
This may have been asked in the past but I couldnt find a suitable
I realize that this question may have been asked several times in the past,

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.