麻烦解析XML并获取数据

时间:2013-08-16 06:29:16

标签: objective-c nsxmlparser nsxmlparserdelegate

我需要从webservicex.net解析以下xml和iPhone App。我需要将诗句VerseBibleWords存储到某些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;
}

正确显示currentElementValuemodel是名为Model的类的对象,currentElementValueNSMutableString对象versesNSMutableArray。我是目标C的初学者,之前没有做过解析。问题是方法:

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

未按预期工作。在点击我在代码中注释的异常断点后,应用程序崩溃了。如何获取VerseBibleWords的值并将其存储到某些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.Versemodel.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 个答案:

答案 0 :(得分:1)

制作BOOL captureCharacters;

- (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;
    }          
}