NSXMLParser向一个TableView单元格添加两个元素

时间:2014-01-10 15:23:06

标签: ios objective-c uitableview rss nsxmlparser

我正在尝试使用NSXMLParser使用来自多个单独RSS源的文章标题填充UITableView

for (NSString* feedString in [[NSUserDefaults standardUserDefaults] objectForKey:@"RSSFeeds"])
{
    NSURL *url = [NSURL URLWithString:feedString];
    parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
    [parser setDelegate:self];
    [parser setShouldResolveExternalEntities:NO];
    [parser parse];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{    
    element = elementName;

    if ([element isEqualToString:@"item"])
    {        
     item    = [[NSMutableDictionary alloc] init];
     title   = [[NSMutableString alloc] init];
     link    = [[NSMutableString alloc] init];
    }
}

如果只有一个RSS提要,这似乎运作良好但是只要有多个RSS提要,第二个提要的第一个标题将附加到第一个提要的最后一个标题,并且它们共享同一个单元格表格视图。

我认为这种方法是问题的核心,但我正在努力使其正常运作:

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if ([element isEqualToString:@"title"])
    {
        [title appendString:string];
    }

    else if ([element isEqualToString:@"link"])
    {
        [link appendString:string];
    }
}

我很欣赏我可能会忽略一些显而易见的东西,但任何指针都会受到赞赏。

我的didEnd代码:

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{    
  if ([elementName isEqualToString:@"item"])
  {
    [item setObject:title forKey:@"title"];
    [item setObject:link forKey:@"link"];
    [feeds addObject:[item copy]];
  }
}

- (void)parserDidEndDocument:(NSXMLParser *)parser
{    
    [self.tableView reloadData];
}

3 个答案:

答案 0 :(得分:2)

使用NSXMLParser时,完全取决于您创建对象结构,因为NSXMLParser是愚蠢的(,我并不是说它是无功能的,我的意思是它离开了所有聪明的东西都由你决定

NSXMLParser只是逐行读取文件,并告诉您它在当前解析的行上找到了什么(在-foundCharacters方法中)。 它没有告诉您前一行或即将到来的行。

我将为您提供最基本的代码,这些代码将根据解析的XML结构创建对象层次结构。

根据您当前的需求,您可以更轻松或更具辨识度。

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName 
                                        namespaceURI:(NSString *)namespaceURI
                                       qualifiedName:(NSString *)qName
                                          attributes:(NSDictionary *)attributeDict
{
    //NSLog(@"started element %@", elementName);

    if(resultString) {

        if(eliminateWhiteSpace)
            [[objects objectAtIndex:[objects count] - 1] setStringValue:[resultString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
        else
            [[objects objectAtIndex:[objects count] - 1] setStringValue:resultString];
        resultString = nil;
    }

    XMLNode* currentObject = [[XMLNode alloc] init];

    if(!objects) {
        objects = [[NSMutableArray alloc] init];
    }

    [objects addObject:currentObject];
    [currentObject setNodeName:elementName];

    if([[attributeDict allKeys] count] > 0) {
        currentObject.attributes = attributeDict;
    }
}

- (void)parser:(NSXMLParser*)parser foundCharacters:(NSString *)string
{
    NSLog(@"found characters %@", string);

    if(!resultString) {
        resultString = [[NSMutableString alloc] init];
    }

    [resultString appendString:string];
}

- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
{
    resultString = [[NSMutableString alloc] initWithData:CDATABlock 
                                                encoding:NSUTF8StringEncoding];
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
                                      namespaceURI:(NSString *)namespaceURI
                                     qualifiedName:(NSString *)qName
{
    //NSLog(@"ended element %@", elementName);

    if(resultString) {
        if(eliminateWhiteSpace)
            [[objects objectAtIndex:[objects count] - 1] setStringValue:[resultString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]];
        else
            [[objects objectAtIndex:[objects count] - 1] setStringValue:resultString];
    }

    if([objects count] > 1) {
        [[objects objectAtIndex:[objects count] - 2] addSubNode:[objects objectAtIndex:[objects count] - 1]];
        [objects removeObjectAtIndex:[objects count] - 1];
    }

    resultString = nil;
}

我在那里有一些类变量和一个XMLNode类 你必须根据自己的需要定制那些,所以我不会准确解释它们是什么 根据您的情况,您可以完全删除它们。

阅读该代码几次,您应该能够了解NSXMLParser为您做的事情及其对您的期望。

祝你好运。

答案 1 :(得分:1)

您好像没有重置titlelink

试试这个(不确定,因为你的逻辑有点不同寻常

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
                                      namespaceURI:(NSString *)namespaceURI
                                     qualifiedName:(NSString *)qName
{    
    if ([elementName isEqualToString:@"item"]) {
        [feeds addObject:[item copy]];
    }

    if ([elementName isEqualToString:@"title"]) {
        [item setObject:[title copy] forKey:@"title"];
        title = @"";
    }

    if ([elementName isEqualToString:@"link"]) {
        [item setObject:[link copy] forKey:@"link"];
        link = @"";
    }
}

答案 2 :(得分:1)

注意:不是最优化的解决方案,但应该可以使用(我稍后会对此进行编辑)

for (NSString* feedString in [[NSUserDefaults standardUserDefaults] objectForKey:@"RSSFeeds"])
{
    NSURL *url = [NSURL URLWithString:feedString];
    parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
    [parser setDelegate:self];
    [parser setShouldResolveExternalEntities:NO];
    [parser parse];

    //declare "NSMutableString *strCurrent;" in the .h of this class
    strCurrent = [NSMutableString alloc] init];
}

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

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

    if ([elementName isEqualToString:@"title"]) {        
        strCurrent = [[NSMutableString alloc] init];
    }

    if ([elementName isEqualToString:@"link"]) {        
        strCurrent = [[NSMutableString alloc] init];
    }
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
                                      namespaceURI:(NSString *)namespaceURI
                                     qualifiedName:(NSString *)qName
{    
    if ([elementName isEqualToString:@"title"]) {
        [item setObject:strCurrent forKey:@"title"];
    }

    if ([elementName isEqualToString:@"link"]) {
        [item setObject:strCurrent forKey:@"link"];
    }

    if ([elementName isEqualToString:@"item"]) {
        [feeds addObject:[item copy]];
    }
}