2010-11-07 7 views
2

Je suis en train d'analyser un fichier XML et de remplir une vue tabulaire. Le XML a un format comme celui-ci:Comment analyser plusieurs balises XML à l'aide de NSXMLParser

<article> 
    <title>Title 1</title> 
    <last-modified>MM/DD/YYY</last-modified> 
</article> 
... 

J'ai actuellement ce travail à l'aide d'un NSMutableString pour recueillir tous les titres de l'article et les chaînes dans annexant la méthode - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string. Puis, au moment opportun, j'ajoute le articleTitle à un NSMutableArray qui contient tous les titres d'articles, et remplit la table à partir du tableau, comme vous vous en doutez.

Cependant, maintenant je veux passer à l'aide d'une cellule de vue de table qui a un sous-titre (je veux mettre la date de dernière modification comme detailTextLabel et le titre comme textLabel). Avec la façon dont l'analyse est divisée en plusieurs méthodes (c'est-à-dire 2 parser méthodes et la méthode foundCharacters), je ne suis pas sûr de la façon dont je devrais aller "recueillir" les données, et remplir la table à partir de ces données.

Quelle est la meilleure approche pour cela? Puis-je en quelque sorte juste remplir un NSDictionary ou quelque chose, et juste récupérer les éléments par clé lors de la construction des cellules du tableau?

Je n'arrive pas à trouver la meilleure façon de gérer cela.

Merci d'avance!

+0

événement l'analyse XML -drive est un battement, s'il y a un analyseur de style DOM disponible, commencez là. –

Répondre

5

Vous pouvez utiliser un parseur DOM si vous le souhaitez, et cela pourrait vous faciliter la vie, mais si pour une raison quelconque vous voulez rester avec NSXMLParser, continuez à lire.

Vous voulez que l'objet que vous donnez à l'analyseur en tant que votre délégué (la chose qui implémente NSXMLParserDelegate) accumule essentiellement les données lors de la transmission des données.

IMPORTANT DÉTAIL SOUVENT SOUVENT: Pour le 'contenu' des différentes étiquettes, vous pouvez réellement recevoir plusieurs appels à parser:foundCharacters:. Il n'y a absolument aucune exigence que l'analyseur vous remette tout à la fois. S'il le voulait, il pourrait vous envoyer un personnage à la fois et vous devriez le gérer correctement.

Ce qui suit assume les Ivars suivantes:

NSMutableArray articles_; 
NSMutableString currentCharacters_; 
Article currentArticle_; // Article has title and lastModified properties. 

Et voici un exemple de la façon dont le délégué pourrait mettre en œuvre quelques messages pertinents (le code suivant a évidemment pas de traitement d'erreur):

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { 
    if ([elementName isEqualToString:@"article"]) { 
     NSAssert(currentArticle_ == nil, @"Uh oh! Bad XML!"); 
     currentArticle_ = [[Article alloc] init]; 
     return; 
    } 
    if ([elementName isEqualToString:@"title"]) { 
     NSAssert(currentCharacters_ == nil, @"Uh oh! Bad XML!"); 
     currentCharacters_ = [[NSMutableString alloc] init]; 
     return; 
    } 
    if ([elementName isEqualToString:@"last-modified"]) { 
     NSAssert(currentCharacters_ == nil, @"Uh oh! Bad XML!"); 
     currentCharacters_ = [[NSMutableString alloc] init]; 
     return; 
    } 
} 

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { 
    if ([elementName isEqualToString:@"article"]) { 
     [articles_ addObject:currentArticle_]; 
     [currentArticle_ release], currentArticle_ = nil; 
     return; 
    } 
    if ([elementName isEqualToString:@"title"]) { 
     currentArticle_.title = currentCharacters_; 
     [currentCharacters_ release], currentCharacters_ = nil; 
     return; 
    } 
    if ([elementName isEqualToString:@"last-modified"]) { 
     [currentArticle_ setLastModifiedWithString:currentCharacters_]; 
     [currentCharacters_ release], currentCharacters_ = nil; 
     return; 
    } 
} 

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
    [currentCharacters_ appendString:string]; 
} 
+0

Parfait, exactement ce dont j'avais besoin! Merci. – rpheath

+1

Si c'est exactement ce dont vous avez besoin, n'hésitez pas à accepter la réponse. ;) – imaginaryboy

0

I utilisateur DOM Parser, il est plus propre et plus facile si vous n'êtes pas analysez beaucoup de données .. recommande ici Google GDATA

est un StackOverflow Questio n sur elle

NSError *error; 
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options:0 error:&error]; 
if (doc == nil) { return nil; } 

// get number of hits 
GDataXMLElement * article = [[doc nodesForXPath:@"//article" error:nil] objectAtIndex:0]; 

// title 
NSLog([[[entry elementsForName:@"title"] objectAtIndex:0] stringValue]], nil); 

// last-modified 
NSLog([[[entry elementsForName:@"last-modified"] objectAtIndex:0] stringValue]], nil);