Проблемы с анализом XML и извлечением данных

Мне нужно проанализировать следующий XML из webservicex.net, для и iPhone App. Мне нужно хранить стих Verse а также BibleWords в некоторый NSArray/NSDictionary или что-то.

<string xmlns="http://www.webserviceX.NET">
<NewDataSet>
  <Table>
    <Book>1</Book>
    <BookTitle>Genesis</BookTitle>
    <Chapter>1</Chapter>
    <Verse>1</Verse>
    <BibleWords>In the beginning God created the heaven and the earth.</BibleWords>
  </Table>
  <Table>
    <Book>1</Book>
    <BookTitle>Genesis</BookTitle>
    <Chapter>1</Chapter>
    <Verse>2</Verse>
    <BibleWords>And the earth was without form, and void; and darkness was upon the face of the deep. And the Spirit of God moved upon the face of the waters.</BibleWords>
  </Table>
  <Table>
    <Book>1</Book>
    <BookTitle>Genesis</BookTitle>
    <Chapter>1</Chapter>
    <Verse>3</Verse>
    <BibleWords>And God said, Let there be light: and there was light.</BibleWords>
  </Table>
  <Table>
    <Book>1</Book>
    <BookTitle>Genesis</BookTitle>
    <Chapter>1</Chapter>
    <Verse>4</Verse>
    <BibleWords>And God saw the light, that it was good: and God divided the light from the darkness.</BibleWords>
  </Table>
</NewDataSet>
</string>

Я написал следующий код для анализа данных.

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    if ([elementName isEqualToString:@"string"]) {
        model = [[Model alloc]init];        
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if(!currentElementValue) {
        currentElementValue = [[NSMutableString alloc]initWithString:string];
    }

    else {
        [currentElementValue appendString:string];
    }

    NSLog(@"%@", currentElementValue);
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if ([elementName isEqualToString:@"NewDataSet"]) {
        return;
    }

    if ([elementName isEqualToString:@"Table"]) {
        [verses addObject:model];
        model = nil;
    }
    else {
        [model setValue:currentElementValue forKey:elementName]; //The exception break point hits here
    }    

    currentElementValue = nil;
}

currentElementValue отображается правильно. model это и объект класса с именем Model, currentElementValue это NSMutableString объект verses является NSMutableArray, Я новичок в цели C и раньше не занимался разбором. Проблема в том, что метод:

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

не работает, как ожидалось. Приложение сломалось после нажатия на точку останова исключения, которую я прокомментировал в коде. Как я могу получить значение Verse а также BibleWords и сохранить его для некоторых NSArray/NSMutableArray/NSDictionary/NSMutableDictionary, Пожалуйста, спросите, есть ли что-то еще, что я должен упомянуть, чтобы увидеть, где проблема на самом деле лежит.

РЕДАКТИРОВАТЬ:

Пробовал с этим:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    captureCharacters = NO;
    [currentElementValue setString : @""];
    if ([elementName isEqualToString:@"Table"]) { //set a break point here as well. The elementName is string and hence is not entering any of the conditions in this delegate method. Hence captureCharacters is always set to NO and nothing is working.
        model = [[Model alloc]init];        
    }
    else if ([elementName isEqualToString:@"Verse"]) {
       capturingCharacters = yes;
    }

    else if ([elementName isEqualToString:@"BibleWords"]) {
       capturingCharacters = yes;
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if(capturingCharacters) {
        [currentElementValue appendString:string];
    }
 }

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if ([elementName isEqualToString:@"Table"]) {
        [array addObject : model];
        model = nil;        
    }
    else if ([elementName isEqualToString:@"Verse"]) { //set a break point here
       model.Verse = currentElementValue; //not entering this condition
    }

    else if ([elementName isEqualToString:@"BibleWords"]) {
       model.BibleWords = currentElementValue; //not entering this condition
    }          
}

Это не работает, и я получаю нулевые значения для model.Verse а также model.BibleWords, Как работают эти методы?

РЕДАКТИРОВАТЬ-2
Интерфейс модели:

//model.h
@protocol HttpRequestHandler <NSObject>

- (void)returnFromSiteParsedData:(NSMutableArray *)parsedData;

@end

@interface Model : NSObject <NSURLConnectionDelegate, NSXMLParserDelegate>
{
    NSString *urlToLoad;
    NSMutableURLRequest *requestSiteToSendData;
    NSURLConnection *connectionToSiteToSendData;

    NSString *verseText;
    int verseNumber;

}
@property(nonatomic, retain) NSString *verseText;
@property(nonatomic, assign) int verseNumber;

- (void)loadSiteToSendDataWithChapterNumber:(int)chapterNumber AndBookNumber:(int)bookNumber;

@property(nonatomic, retain)id<HttpRequestHandler>httpRequestHandlerDelegate;

@end

Реализация модели

//model.m
@implementation Model

@synthesize verseNumber;
@synthesize verseText;

- (void)loadSiteToSendDataWithChapterNumber:(int)chapterNumber AndBookNumber:(int)bookNumber {

    urlToLoad = [[NSString alloc]initWithFormat:@"http://www.webservicex.net/BibleWebservice.asmx/GetBibleWordsByBookTitleAndChapter?BookTitle=Genesis&chapter=1"];
    requestSiteToSendData = [NSMutableURLRequest requestWithURL:[[NSURL alloc]initWithString:urlToLoad] cachePolicy:NSURLRequestReloadIgnoringCacheData  timeoutInterval:30];
    connectionToSiteToSendData = [[NSURLConnection alloc]initWithRequest:requestSiteToSendData delegate:self];    

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {

    // Parse the XML into a dictionary
    NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data];
    VBSParser *vbsParser = [[VBSParser alloc]initVBSParser];
    [parser setDelegate:vbsParser];
    BOOL success = [parser parse];

    if (success) {
        NSMutableArray *verses = [vbsParser verses];
        NSLog(@"%@", verses);
        NSLog(@"Number: %d\n Text: %@", verseNumber,verseText);
        [self.httpRequestHandlerDelegate returnFromSiteParsedData:verses];
    }
    // Print the dictionary

}

@end

Делегат используется для возврата проанализированных данных в контроллер представления.

1 ответ

Сделать BOOL захватив персонажей;

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
    captureCharacters = NO;
    [currentElementValue setString : @""];
    if ([elementName isEqualToString:@"Table"]) {
        model = [[Model alloc]init];        
    }
    else if ([elementName isEqualToString:@"Verse"]) {
       capturingCharacters = yes;
    }

    else if ([elementName isEqualToString:@"BibleWords"]) {
       capturingCharacters = yes;
    }
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    if(capturingCharacters) {
        [currentElementValue appendString:string];
    }
 }

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if ([elementName isEqualToString:@"Table"]) {
        [array addObject : model];
        model = nil;        
    }
    else if ([elementName isEqualToString:@"Verse"]) {
       model.Verse = currentElementValue;
    }

    else if ([elementName isEqualToString:@"BibleWords"]) {
       model.BibleWords = currentElementValue;
    }          
}
Другие вопросы по тегам