views:

274

answers:

3

I am currently working on a software to control aMule status of my server through the iPhone, i created a socket that spits out xml which should be parsed out, but because NSXMLParser is event-drive, i'm having problems in understanding how this could work... I thought of this type of XML structure, if you have ideas of a better way to structure it please tell me!! :D

<root type="donwloads">   <-- specifies downloads or search results
<file name="Ubuntu_9_10.iso" status="[11,6%]" />
<file name="Fedora 12.iso" status="[56,2%]" />
</root>

What i was thinking is, as i want to put this in a tableview, most probably i will need a NSMutableArray with lots of NSDictionaries based on the results, every dict should be a file.. what do you guys propose?? how should i handle this situation?

Thanks

+1  A: 

Write a parser class that turns nodes into Core Data managed objects and saves them to the managed object context, when a parser callback event is fired.

Use an NSFetchedResultsController to access the Core Data store. As the managed objects come in and are saved, the results controller updates the table view with whatever results it fetches.

Alex Reynolds
+1  A: 

An NSMutableArray of NSDictionary seems like a reasonable approach for your in-memory data structure.

You'll basically have a series of callbacks that build up that array as NSXMLParser runs through your XML file:

- (void) parseXML:(NSString *) filename {
    NSURL *xmlURL = [NSURL fileURLWithPath:filename];

    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithContentsOfURL:xmlURL];

    [xmlParser setDelegate:self];

    [xmlParser parse];

    // Check for errors.
    NSError *errorCode = [xmlParser parserError];
    if (errorCode) {
        // handle error here
        NSLog(@"%@", [errorCode localizedDescription]);
    }

    [xmlParser release];
}

And your main delegate:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
    // If certain elements are found initialize the object
    if ([elementName isEqualToString:"@file"]) {
       NSMutableDictionary *currentFile = [[NSMutableDictionary alloc] init];
       // Look through the attributes add stuff to your dictionary
       // Add it to your array.
    }
}

Since all of your data is returned in attributes you can do it this way. Otherwise you'd need to store the file and build it up (the foundCharacters delegate) finally adding it to your array when the file's tag occurs in the didEndElement delegate.

Epsilon Prime
You'll also want to call `reloadData` on your `UITableView` after you finish the parse.
Epsilon Prime
Thanks for your suggestion
PirosB3
A: 

Thanks a lot for your answers :D fortunately i resolved the problem 10 minutes after :D ill post what i did:

XML:

<root>
  <downloads>
<file type="text" name="fdsdf" />
<file type="text" name="sdfsdfssds" />
  </downloads>
</root>

NSXMLParser delegates:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName       namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict{
if([elementName isEqualToString:@"downloads"] || [elementName isEqualToString:@"results"]){
    NSLog(@"starting or downloads or results");
    if(xmlArray){
        xmlArray= nil;
    }
    self.xmlArray= [[NSMutableArray alloc] init];
}
else if([elementName isEqualToString:@"file"]){
    NSLog(@"found file...");
    [self.xmlArray addObject:attributeDict];
   }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
if([elementName isEqualToString:@"downloads"] || [elementName isEqualToString:@"results"]){
    if([elementName isEqualToString:@"downloads"]){
        NSLog(@"downloads found: %@...  reloading table", xmlArray);
    }
  }
}

I hope this can possibly help someone which has my same problem :D

PirosB3