1
votes

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

2 Answers

3
votes

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.

2
votes

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.