views:

286

answers:

2

Hi Stackoverflow friends,

I am parsing an XML file of the network using NSXMLParser after I got the Data from NSURLConnection. The XML has many "items" and each item contains 1 category. In the CoreData module i have an Item entity with a relationship to one Category.

While parsing the XML file and hitting the message parser:didStartElement:... with "Item" element I create a NSEntityDescription for Item. Then the parser arrives the Category item again in message parser:didStartElement:... and I create an NSEntityDescription for Category.

the XML:

<item>

<title>Plates</title>

<category>Kitchen</category>

<price>14</price>

<picture></picture>

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


//Started reading an Item Element, init currentItemObject
if ([elementName isEqualToString:@"Item"]) {
    [self.currStringFound setString:@""];
    currentItemObject  = (Item *)[NSEntityDescription insertNewObjectForEntityForName:@"Item" inManagedObjectContext:[self managedObjectContext]];
    return;
}

//Started Title element
if ([elementName isEqualToString:kTitleElementName]) {
    [self.currStringFound setString:@""];
}

//Started Category element
if ([elementName isEqualToString:kCategoryElementName]) {
    currentCategory  = (Category *)[NSEntityDescription insertNewObjectForEntityForName:@"Category" inManagedObjectContext:[self managedObjectContext]];
    [self.currStringFound setString:@""];
}
}



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

if ([elementName isEqualToString:kItemElementName]) {
    //save the item to CoreData
    NSManagedObjectContext *context = [self managedObjectContext];
    NSError *error;
    if (![context save:&error]) {
        NSLog(@"could not save Item");
        exit(1);
    }
    return;
}

//Started Category element
if ([elementName isEqualToString:kCategoryElementName]) {
    currentCategory.title = self.currStringFound;
    NSLog(@"Category = %@",self.currStringFound);
    NSManagedObjectContext *context = [self managedObjectContext];
    NSError *error;
    if (![context save:&error]) {
        NSLog(@"could not save Item");
        exit(1);
    }
    return;
}}

So what happens is that the context save: call is being called for the currentCategory first while the CurrentItem was not finished creating.

+2  A: 

You don't need to save the context until you've parsed the entire XML file and inserted all the objects that you need to insert. Remove the -save: calls in your parsing routine and just call it when the parsing operation completes.

Rob Keniger
Thats a good idea, i will save only at at the end of each item loop this will give me a complete cycle of the data.Thanks for your reply
Cocoa student
+3  A: 

You appear to be saving too frequently. While waiting until the end of the XML file to save is probably not a great idea, you probably do want to wait until you are finished with one "entity".

However, I would recommend looking into a different parser as well. TouchXML may be more useful for you as it is not as low level as this and can make conceptualizing the import processes much easier.

Marcus S. Zarra
This is a good tip, i will save after each entity. I didnt know that i could save every thing in the end but this seems much safer.about TouchXML i will take a look i already downloaded it, but I am only reading from the XML so it seems like NSXMLParser is enough for the task.Thanks
Cocoa student