【问题标题】:How to Save Parsed Data From Different URLs to Different Arrays in NSXMLParser?如何在 NSXMLParser 中将不同 URL 的解析数据保存到不同的数组中?
【发布时间】:2013-12-02 09:16:09
【问题描述】:

我搜索了很多类似的问题,但无法弄清楚我的问题。

我有一个嵌入了 RSS 提要文件的应用程序。我所做的是在我的根视图控制器中加载该本地文件并对其进行解析,并在table view 中显示数据。我还将每个项目的GUID 保存在一个数组中。

如果用户可以访问互联网,我想从服务器获取 RSS 提要链接并对其进行解析,然后将该文件中项目的GUIDs 保存到另一个数组中,然后比较两个数组,然后将新项目添加到我的表格视图中的当前列表中。

我有NIKFeedEntry 作为我解析数据的NSObject 模型和NSXMLParser。我用两个 URLs 的两个不同的解析器对象来实例化它,但它们都写在同一个对象中。因此第一组解析的数据显示了很短的时间,然后表格视图用新的解析数据重新加载数据,我不知道如何解决这个问题,以便在解析第二个 URL 后,将两者进行比较GUID 的数组,如果有任何新的,将这些项目(XML 数据)附加到我的本地 XML 文件中,并显示新旧数据的组合。

这是我的NIKFeedEntry.m

#import "NIKFeedEntry.h"

@implementation NIKFeedEntry

@synthesize lastBuildDate;
@synthesize radioTitle;
@synthesize podcastTitle;
@synthesize podcastDate;
@synthesize podcastURL;

@synthesize podcastAuthor;
@synthesize podcastContent;
@synthesize podcastGUID;
@synthesize podcastDownloadURL;
@synthesize podcastLinkURL;
@synthesize podcastSummary;
@synthesize categories;

- (id)initWithRadioTitle:(NSString*)radioTitle lastBuildDate:(NSDate*)lastBuildDate podcastTitle:(NSString*)podcastTitle podcastFile:(NSString*)podcastFile podcastDate:(NSDate*)podcastDate podcastDownloadURL:(NSString*)podcastDownloadURL
{
    return self;
}

@end

还有我的NIKFeedParser.m

//  NIKFeedParser.m

#import "NIKFeedParser.h"
#import "NIKMasterViewController.h"

@class NIKMasterViewController;

NIKMasterViewController *masterVC;


@interface NIKFeedParser (Private)

- (NSString *)trimString:(NSString *)originalString;

@end

@implementation NIKFeedParser

@synthesize currentItem;
@synthesize currentItemValue;
@synthesize feedItems;
@synthesize delegate;
@synthesize retrieverQueue;
@synthesize parsingFeedsWithNumbers;
@synthesize queue;
@synthesize selectedCategory;
@synthesize feedURL;
@synthesize downloadURL;
@synthesize lastModified;
@synthesize RSSURL;
@synthesize updatedGUIDs;

- (id)initWithRSSURL:(NSURL *)rssURL{
    self = [super init];
    if (self) {
        feedItems = [[NSMutableArray alloc]init];
        RSSURL = rssURL;
    }
    return self;
}


- (NSOperationQueue *)retrieverQueue
{
    if (nil == retrieverQueue)
    {
        retrieverQueue = [[NSOperationQueue alloc] init];
        retrieverQueue.maxConcurrentOperationCount = 1;
    }

    return retrieverQueue;
}

- (void) startDownloading
{
//  ?? [feedItems removeAllObjects];
    NSString *file = [[NSBundle  mainBundle] pathForResource:@"Feed"
                                                      ofType:@"plist"];
    NSDictionary *item = [[NSDictionary alloc]initWithContentsOfFile:file];
    NSArray *array = [item objectForKey:@"Root"];
    NSString *theURL = [[array objectAtIndex:selectedCategory.intValue] objectForKey:@"URL"];
    NSLog(@"url:%@",theURL);
    NSURL * url = [NSURL URLWithString:theURL];
    NSURLRequest * urlRequest = [NSURLRequest requestWithURL:url];

    NSURLConnection * download = [[NSURLConnection alloc] initWithRequest:urlRequest delegate:self];
    [download start];
}

#pragma mark -
#pragma mark Private Methods


- (NSString *)trimString:(NSString *)originalString
{
    NSString * trimmedString;
    trimmedString  = [originalString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    return trimmedString;
}

#pragma mark -
#pragma mark NSURLConnectionDelegate

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response
{
    //This method is called when the download begins.
    //You can get all the response headers

    /* create the NSMutableData instance that will hold the received data */

    long long contentLength = [response expectedContentLength];
    if (contentLength == NSURLResponseUnknownLength) {
        contentLength = 500000;
    }


    if (downloadedData!=nil)
    {
        downloadedData = nil;
    }
    downloadedData = [NSMutableData dataWithCapacity:(NSUInteger)contentLength];

}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    //This method is called whenever there is downloaded data available
    //It will be called multiple times and each time you will get part of downloaded data
    [downloadedData appendData:data];
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    //This method is called once the download is complete


    //The next step is parse the downloaded xml feed
    [feedItems removeAllObjects];
    NSXMLParser * xmlParser = [[NSXMLParser alloc] initWithData:downloadedData];
    [self startParsingWithParser:xmlParser];

    updatedGUIDs = [[NSMutableArray alloc] init];

    for (int i = 0; i < feedItems.count; i++) {
        [updatedGUIDs insertObject: [[feedItems objectAtIndex:i]podcastGUID]  atIndex:i];
    }

}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error
{

    [error localizedDescription];
    NSLog(@"%@", [error localizedDescription]);
    [self.delegate parserHasError:error];

}

#pragma mark -
#pragma mark NSXMLParserDelegate
- (void) startParsingWithParser: (NSXMLParser *)parser
{

    [parser setDelegate:self];
    [parser setShouldProcessNamespaces:YES];
    [parser setShouldReportNamespacePrefixes:YES];
    [parser setShouldResolveExternalEntities:NO];
    [parser parse];
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict
{
    if(nil != qualifiedName)
    {
        elementName = qualifiedName;
    }
    parseElement = NO;
    if ([elementName isEqualToString:@"lastBuildDate"])
    {
        lbd = [[NSString alloc] init];
    }

    if ([elementName isEqualToString:@"item"])
    {
        currentItem = [[NIKFeedEntry alloc] init];
    } else if([elementName isEqualToString:@"title"] ||
              [elementName isEqualToString:@"guid"] ||
              [elementName isEqualToString:@"description"] ||
              [elementName isEqualToString:@"content:encoded"] ||
              [elementName isEqualToString:@"link"] ||
              [elementName isEqualToString:@"category"] ||
              [elementName isEqualToString:@"dc:creator"] ||
              [elementName isEqualToString:@"pubDate"] ||
              [elementName isEqualToString:@"enclosure"] ||
              [elementName isEqualToString:@"lastBuildDate"])
    {
        NSString *urlValue=[attributeDict valueForKey:@"url"];
        NSString *urlType=[attributeDict valueForKey:@"type"];
        parseElement = YES;
        if ([urlType  isEqualToString:@"audio/ogg"] && ([urlValue rangeOfString:@"jadi.net"].length != 0))
        {
            downloadURL = [urlValue stringByReplacingOccurrencesOfString:@"jadi.net" withString:@"192.168.2.1"];
            downloadURL = [downloadURL stringByReplacingOccurrencesOfString:@"ogg" withString:@"mp3"];
            [currentItem setPodcastDownloadURL:downloadURL];
        }
    }

}


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
    if(nil != qName)
    {
        elementName = qName;
    }

    NSString * parsedElementContent = nil;

    if (parsedElementData != nil) {
        parsedElementContent = [[NSString alloc] initWithData:parsedElementData encoding:NSUTF8StringEncoding];
    } else if (parsedElementString != nil) {
        parsedElementContent = [[NSString alloc] initWithString:parsedElementString];
    }
    if ([elementName isEqualToString:@"lastBuildDate"]) {
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss Z"];
        NSDate *lastSavedBuildDate = [formatter dateFromString:[self trimString:parsedElementContent]];
        [[NSUserDefaults standardUserDefaults] setObject:lastSavedBuildDate forKey:@"Date"];

    }
    if([elementName isEqualToString:@"title"])
    {
        [currentItem setPodcastTitle:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"guid"])
    {
        [currentItem setPodcastGUID:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"description"])
    {
        [currentItem setPodcastSummary:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"content:encoded"])
    {
        [currentItem setPodcastContent:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"link"])
    {
        [currentItem setPodcastLinkURL:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"category"])
    {
        [currentItem addPodcastCategory:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"dc:creator"])
    {
        [currentItem setPodcastAuthor:[self trimString:parsedElementContent]];
    }
    else if([elementName isEqualToString:@"pubDate"])
    {
        NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
        [formatter setDateFormat:@"EEE, d MMM yyyy HH:mm:ss Z"];
        [currentItem setPodcastDate:[formatter dateFromString:[self trimString:parsedElementContent]]];
    }
    else if([elementName isEqualToString:@"item"])
    {
        [feedItems addObject:currentItem];
        currentItem = nil;
    }

    if (parsedElementContent!=nil)
    {
        parsedElementContent = nil;
    }

    if (parsedElementString!=nil)
    {
        parsedElementString = nil;
    }

    if (parsedElementData!=nil)
    {
        parsedElementData = nil;
    }

}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
    if (!parseElement)
    {
        return;
    }
    if (parsedElementString==nil)
    {
        parsedElementString = [[NSMutableString alloc] init];
    }
    [parsedElementString appendString:string];
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
{
    NSLog(@"parseErrorOccured: %@",[parseError localizedDescription]);

}

- (void)parserDidEndDocument:(NSXMLParser *)parser
{
    if (downloadedData!=nil)
    {
        downloadedData = nil;
    }
    [self.delegate parserDidCompleteParsing];
}

@end

【问题讨论】:

    标签: ios objective-c arrays nsxmlparser


    【解决方案1】:

    在下载后使用 GDataXMLNode Hear i attach its .h and .m 而不是使用这个过程很混乱,请按照以下步骤操作:-

    • 下载并解压 zip 并将这两个类添加到您的项目 GDataXMLNode.hGDataXMLNode.m

    • #import "GDataXMLNode.h" 到你想调用你的 xmp URL 的类中。

    • 使用此波纹管方法解析数据:-


    -(void)ActionCountAlikes
    {
    NSString *urlParsingStr =@"http://youryoue.php"
    
    
    
        NSData *xmlData = [[NSMutableData alloc] initWithContentsOfURL:[NSURL URLWithString:urlParsingStr]];
    
        NSError *error;
        GDataXMLDocument *xmlDocument = [[GDataXMLDocument alloc] initWithData:xmlData
                                                                       options:0 error:&error];
        NSArray *getData = [[xmlDocument rootElement]elementsForName:@"Record"];
    
            for(GDataXMLElement *e in getData)
            {
                 NSMutableDictionary *d = [[NSMutableDictionary alloc] init];
                [d setValue:[[[e elementsForName:@"Message"]objectAtIndex:0]stringValue] forKey:@"Message"];
    
    
            }
    
    
        }
    

    【讨论】:

    • 谢谢尼廷。目前我没有使用这个类,因为我想用 NSXMLParser 修复我自己的代码,但我将来会尝试这个。附:我试过了,但是导入 libXML 框架,并没有阻止 #import libxml/tree.h; 的错误。
    【解决方案2】:

    NSXMLParserDelegate 的所有方法都返回对调用者parser:(NSXMLParser *)parser 的引用。您可以将其用于单独的数据。在属性中保留对解析器实例的引用并与它们进行比较。

    【讨论】:

      猜你喜欢
      • 2022-11-25
      • 2018-07-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多