Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/ios/109.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Ios NSXMLParser将两个元素添加到一个TableView单元格_Ios_Objective C_Uitableview_Rss_Nsxmlparser - Fatal编程技术网

Ios NSXMLParser将两个元素添加到一个TableView单元格

Ios NSXMLParser将两个元素添加到一个TableView单元格,ios,objective-c,uitableview,rss,nsxmlparser,Ios,Objective C,Uitableview,Rss,Nsxmlparser,我正在尝试使用NSXMLParser填充一个UITableView,其中包含来自几个单独RSS提要的文章标题: for (NSString* feedString in [[NSUserDefaults standardUserDefaults] objectForKey:@"RSSFeeds"]) { NSURL *url = [NSURL URLWithString:feedString]; parser = [[NSXMLParser alloc] initWithCont

我正在尝试使用
NSXMLParser
填充一个
UITableView
,其中包含来自几个单独RSS提要的文章标题:

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源,第二个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];
}

当使用
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;
    }
}


这里有几个类变量和一个
XMLNode
类。
您必须根据自己的需要定制这些产品,因此我不会详细解释这些产品是什么。
很可能在你的情况下,你可以完全移除它们

将该代码通读几遍,您应该能够了解
NSXMLParser
为您做了什么以及它对您的期望


祝你好运。

当使用
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;
    }
}


这里有几个类变量和一个
XMLNode
类。
您必须根据自己的需要定制这些产品,因此我不会详细解释这些产品是什么。
很可能在你的情况下,你可以完全移除它们

将该代码通读几遍,您应该能够了解
NSXMLParser
为您做了什么以及它对您的期望


祝你好运。

看来你从未重置过
标题
链接

试试这个(不确定,因为你的逻辑有点与众不同)


似乎您从未重置过
标题
链接

试试这个(不确定,因为你的逻辑有点与众不同)

注意:不是最优化的解决方案,但应该可以工作(稍后我将编辑此内容)




注意:不是最优化的解决方案,但应该可以工作(稍后我将编辑此内容)






请发布您的
didEnd
代码。这是您应该处理关闭最后一个对象的地方。如果你不关闭最后一个对象并创建一个新对象,那么你只是在创建一个大对象,所有数据都混在一起。谢谢,我已经附加了它。你能发布你试图解析的实际XML吗?请发布你的
didEnd
代码。这是您应该处理关闭最后一个对象的地方。如果你不关闭最后一个对象并创建一个新对象,那么你只是在创建一个大对象,所有数据都混在一起。谢谢,我已经附加了它。你能发布你试图解析的实际XML吗?这给了我一个表,每个单元格中都有空字符串。谢谢,但还是空单元格。@Robert:hm。。让我们稍后再看你的具体案例,现在,我将发布另一个答案,用一种许多人普遍认为的方式follow@Robert:发布了一个新的答案(我身边没有我的mac电脑,但我认为它应该可以工作)。我将在稍后编辑这两个答案,以使其正确(也许明天),但希望你应该正确track@Robert:我也更新了这个答案。(如果你坚持你原来的逻辑,那么这个答案在技术上应该是有效的……多亏了@Putz1103)这给了我一个表格,每个单元格都有空字符串。谢谢,但还是空单元格。@Robert:hm。。让我们稍后再看你的具体案例,现在,我将发布另一个答案,用一种许多人普遍认为的方式follow@Robert:发布了一个新的答案(我身边没有我的mac电脑,但我认为它应该可以工作)。我将在稍后编辑这两个答案,以使其正确(也许明天),但希望你应该正确track@Robert:我也更新了这个答案。(如果你坚持你原来的逻辑,那么这个答案在技术上应该是有效的…感谢@Putz1103)谢谢,但是与
[\uu NSArrayM insertObject:atIndex:]:object不能是nil
Mea culpa,我只需要添加
element=elementName到didStartElement的顶部
。非常感谢,先生。@罗伯特:噢。。。嘘。这表明现代IDE如何帮助我们忽略这些无关紧要的细节。事实上。。。更新答案。不需要
element=elementName谢谢,但是崩溃了
[\uu NSArrayM insertObject:atIndex:]:对象不能为零
Mea culpa,我只需要添加
element=elementName到didStartElement的顶部
。非常感谢,先生。@罗伯特:噢。。。嘘。这表明现代IDE如何帮助我们忽略这些无关紧要的细节。事实上。。。更新答案。不需要
元素
- (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;
}
- (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 = @"";
    }
}
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]];
    }
}