NSXMLParser停止,当它发现第一个实例

问题描述:

我想解析这个XML使用NSXMLParser。我有“咖啡”的多个实例的XML文件中,就像这样:NSXMLParser停止,当它发现第一个实例

… More XML 
<Coffee> 
     <Type Name="Type">Minimum Drinking Amount</Type> 
      </Coffee> 
<Coffee> 
     <Type Name="Type">Maximum Drinking Amount</Type> 
      </Coffee> 
… More XML 

现在,一旦发现的NSXMLParser“咖啡”的第一个实例,完成并移动到XML的其余部分。哪个...好吧,不是我想要做的。我需要它来读取“Coffee”的每个实例这就是我在Objective-C中处理它的方式。

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { 
    NSLog(@"Fired Stick1"); 

    _xmlString = elementName; 

    if ([_xmlString isEqualToString:@"Coffee"]) { 
     NSLog(@"Stick1 Coffee:"); 
    } 

    if ([_xmlString isEqualToString:@"Tea"]) { 
     NSLog(@"Stick1 Tea:"); 
} 

然后foundCharacters代表:

-(void) parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 

    if ([_xmlString isEqualToString:@"Coffee"] || [_xmlString isEqualToString:@"Tea"]) { 
     [email protected]"%@ Called", _xmlString); 
    } 
    if (!_coffeeString) { 
     _coffeeString = [[NSMutableString alloc] initWithString:string]; 
    } 
    else { 
     _coffeeString = string; 
    } 

    if (coffeeArray == NULL) { 
     NSLog(@"Stick1 the coffeeArray was null"); 
     coffeeArray = [[NSMutableArray alloc] init]; 
    } 

    //add the returned string into an array 
    [coffeeArray addObject:_coffeeString]; 
    NSLog(@"Stick1 array %@", coffeeArray); 

    // parse the returned data in array 
    NSString *seperate = [coffeeArray componentsJoinedByString:@"\n"]; 
    NSLog(@"Stick1 seperate is %@", seperate); 

    // another parsing 
    NSArray* words = [seperate componentsSeparatedByCharactersInSet :[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
                          //or use newLineCharecterSet 
    // Take out all of the whitespace like tabs and spaces and new lines 
    _singleName = [words componentsJoinedByString:@""]; 

    NSLog(@"Stick1 final result %@", _singleName); 
} 

基本上,它被称为两次,但并没有显示这两组数据。一旦找到咖啡,它会显示咖啡的第一部分(最小值),但不显示咖啡的第二个实例(最大值)。

+0

哪里是你的'解析器:didEndElement:'方法? – mbm29414 2015-01-26 18:15:52

+0

@ mbm29414我的didEndElement是空的。 – John 2015-01-26 18:18:50

+0

你想要输出什么数据? – mbm29414 2015-01-26 18:30:48

我认为你有几个问题正在进行。一个是(至少使用提供的XML),<Coffee>...</Coffee>定义了一个完整的XML文档,所以你可能会得到一个未处理的解析错误。你应该执行下面的代码在你的NSXMLParserDelegate,看报道有什么问题:

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { 
    NSLog(@"error: %@", parseError); 
} 
- (void)parser:(NSXMLParser *)parser validationErrorOccurred:(NSError *)validationError { 
    NSLog(@"error: %@", validationError); 
} 

你还必须在那里你试图关闭基于标签的名字在你的代码来设置一个触发/标志问题(elementName)的节点,但实际上您关心的是包含在子节点中的数据。

此外,parser:foundCharacters:保证返回标签的所有内容在一个字符串,所以你最好处理parser:didStartElement:...parser:didEndElement:...了很多。然后,在parser:foundCharacters:中,您可以确保您位于适当的节点并且附加已找到的字符。

下面是一些示例代码,您开始基于数据您提供获得:

注:我只是采取了一枪你真正想要的,因为你的数据是有点模糊。另外,我在全新的单视图应用程序的应用程序代表中完成了此操作。这是不是真正实现的方法!

// AppDelegate.m 
#import "AppDelegate.h" 
@interface AppDelegate() <NSXMLParserDelegate> { 

} 
@property (assign, nonatomic) BOOL    inNode; 
@property (strong, nonatomic) NSMutableArray *coffeeArray; 
@property (strong, nonatomic) NSMutableString *coffeeString; 
@property (copy , nonatomic) NSString   *singleName; 
@property (copy , nonatomic) NSString   *xmlString; 
@end 
@implementation AppDelegate 
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { 
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:[[self xml] dataUsingEncoding:NSUTF8StringEncoding]]; 
    parser.delegate  = self; 
    [parser parse]; 
    return YES; 
} 
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { 
    NSLog(@"Fired Stick1"); 

    self.xmlString = elementName; 

    if ([self.xmlString isEqualToString:@"Coffee"]) { 
     NSLog(@"Stick1 Coffee:"); 
     self.coffeeString = [[NSMutableString alloc] init]; 
     self.inNode   = YES; 
    } else if ([self.xmlString isEqualToString:@"Tea"]) { 
     NSLog(@"Stick1 Tea:"); 
     self.coffeeString = [[NSMutableString alloc] init]; 
     self.inNode   = YES; 
    } else { 
     self.inNode   = NO; 
    } 
} 
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 
    if (self.inNode == YES) { 
     if ([self.xmlString isEqualToString:@"Coffee"] || [self.xmlString isEqualToString:@"Tea"]) { 
      NSLog(@"%@ Called", self.xmlString); 
     } 
     [self.coffeeString appendString:string]; 
    } 
} 
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { 
    if ([elementName isEqualToString:@"Coffee"] || [elementName isEqualToString:@"Tea"]) { 
     if (self.coffeeArray == nil) { 
      NSLog(@"Stick1 the coffeeArray was null"); 
      self.coffeeArray = [[NSMutableArray alloc] init]; 
     } 

     //add the returned string into an array 
     [self.coffeeArray addObject:self.coffeeString]; 
     NSLog(@"Stick1 array %@", self.coffeeArray); 

     // parse the returned data in array 
     NSString *seperate = [self.coffeeArray componentsJoinedByString:@"\n"]; 
     NSLog(@"Stick1 seperate is %@", seperate); 

     // another parsing 
     NSArray* words = [seperate componentsSeparatedByCharactersInSet :[NSCharacterSet whitespaceAndNewlineCharacterSet]]; 
     //or use newLineCharecterSet 
     // Take out all of the whitespace like tabs and spaces and new lines 
     _singleName = [words componentsJoinedByString:@""]; 

     NSLog(@"Stick1 final result %@", _singleName); 

    } 
} 
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { 
    NSLog(@"error: %@", parseError); 
} 
- (void)parser:(NSXMLParser *)parser validationErrorOccurred:(NSError *)validationError { 
    NSLog(@"error: %@", validationError); 
} 
- (NSString *)xml { 
    NSMutableString *xml = [[NSMutableString alloc] init]; 
    [xml appendString:@"<Document>"]; 
    [xml appendString:@"" 
    @"<Coffee>" 
    @" <Type Name=\"Type\">" 
    @" Minimum Drinking Amount" 
    @" </Type>" 
    @"</Coffee>" 
    @"<Coffee>" 
    @" <Type Name=\"Type\">" 
    @" Maximum Drinking Amount" 
    @" </Type>" 
    @"</Coffee>\n"]; 
    [xml appendString:@"" 
    @"<Coffee>" 
    @" <Type Name=\"Type\">" 
    @" Minimum Drinking Amount" 
    @" </Type>" 
    @"</Coffee>" 
    @"<Coffee>" 
    @" <Type Name=\"Type\">" 
    @" Maximum Drinking Amount" 
    @" </Type>" 
    @"</Coffee>\n"]; 
    [xml appendString:@"" 
    @"<Coffee>" 
    @" <Type Name=\"Type\">" 
    @" Minimum Drinking Amount" 
    @" </Type>" 
    @"</Coffee>" 
    @"<Coffee>" 
    @" <Type Name=\"Type\">" 
    @" Maximum Drinking Amount" 
    @" </Type>" 
    @"</Coffee>\n"]; 
    [xml appendString:@"" 
    @"<Coffee>" 
    @" <Type Name=\"Type\">" 
    @" Minimum Drinking Amount" 
    @" </Type>" 
    @"</Coffee>" 
    @"<Coffee>" 
    @" <Type Name=\"Type\">" 
    @" Maximum Drinking Amount" 
    @" </Type>" 
    @"</Coffee>\n"]; 
    [xml appendString:@"" 
    @"<Coffee>" 
    @" <Type Name=\"Type\">" 
    @" Minimum Drinking Amount" 
    @" </Type>" 
    @"</Coffee>" 
    @"<Coffee>" 
    @" <Type Name=\"Type\">" 
    @" Maximum Drinking Amount" 
    @" </Type>" 
    @"</Coffee>\n"]; 
    [xml appendString:@"" 
    @"<Coffee>" 
    @" <Type Name=\"Type\">" 
    @" Minimum Drinking Amount" 
    @" </Type>" 
    @"</Coffee>" 
    @"<Coffee>" 
    @" <Type Name=\"Type\">" 
    @" Maximum Drinking Amount" 
    @" </Type>" 
    @"</Coffee>\n"]; 
    [xml appendString:@"</Document>"]; 
    return [xml copy]; 
} 
@end