iPhone 编程 XML 解析器 NSMutableArray

发布于 2024-12-27 17:07:08 字数 5950 浏览 0 评论 0原文

我目前在将 XML 中的信息解析为 NSMutableArray 时遇到问题,我粘贴了下面的代码,该代码用于解析器从互联网上检索文档并构造数组。然后,我尝试将 xml 解析器中的项目复制到 NSMutableArray 中进行搜索,但每次我尝试复制数组时,它都会返回一个结构错误,因此我暂时删除了更改。

这是解析器的代码和主视图控制器中 viewdidload 的当前代码,如果有人可以提供帮助,我将非常感激。

#import "BlogRssParser.h"
#import "BlogRss.h"

@implementation BlogRssParser

@synthesize currentItem = _currentItem;
@synthesize currentItemValue = _currentItemValue;
@synthesize rssItems = _rssItems;
@synthesize delegate = _delegate;
@synthesize retrieverQueue = _retrieverQueue;


- (id)init{
if(![super init]){
    return nil;
}
_rssItems = [[NSMutableArray alloc]init];
return self;
}

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

- (void)startProcess{
SEL method = @selector(fetchAndParseRss);
[[self rssItems] removeAllObjects];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self 
                                                                 selector:method 
                                                                   object:nil];
[self.retrieverQueue addOperation:op];
[op release];
}

-(BOOL)fetchAndParseRss{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

//To suppress the leak in NSXMLParser
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];

NSURL *url = [NSURL URLWithString:@"http://xxxxxxxxx.co.uk/rssparser/Data.xml"];
BOOL success = NO;
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:YES];
[parser setShouldReportNamespacePrefixes:YES];
[parser setShouldResolveExternalEntities:NO];
success = [parser parse];
[parser release];
[pool drain];
return success;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI 
 qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict{
if(nil != qualifiedName){
    elementName = qualifiedName;
}
if ([elementName isEqualToString:@"item"]) {
    self.currentItem = [[[BlogRss alloc]init]autorelease];
} else if([elementName isEqualToString:@"title"] || 
          [elementName isEqualToString:@"description"] ||
          [elementName isEqualToString:@"mediaUrl"] ||
          [elementName isEqualToString:@"link"] ||
          [elementName isEqualToString:@"guid"] ||
          [elementName isEqualToString:@"pubDate"]) {
    self.currentItemValue = [NSMutableString string];
} else {
    self.currentItemValue = nil;
}   
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if(nil != qName){
    elementName = qName;
}
if([elementName isEqualToString:@"title"]){
    self.currentItem.title = self.currentItemValue;
}else if([elementName isEqualToString:@"description"]){
    self.currentItem.description = self.currentItemValue;
}else if([elementName isEqualToString:@"link"]){
    self.currentItem.linkUrl = self.currentItemValue;
}else if([elementName isEqualToString:@"mediaUrl"]){
    self.currentItem.mediaUrl = self.currentItemValue;
}else if([elementName isEqualToString:@"guid"]){
    self.currentItem.guidUrl = self.currentItemValue;
}else if([elementName isEqualToString:@"pubDate"]){
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
    self.currentItem.pubDate = [formatter dateFromString:self.currentItemValue];
    [formatter release];
}else if([elementName isEqualToString:@"item"]){
    [[self rssItems] addObject:self.currentItem];
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(nil != self.currentItemValue){
    [self.currentItemValue appendString:string];
}
}

- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock{
//Not needed for now
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
if(parseError.code != NSXMLParserDelegateAbortedParseError) {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [(id)[self delegate] performSelectorOnMainThread:@selector(processHasErrors)
     withObject:nil
     waitUntilDone:NO];
}
}



- (void)parserDidEndDocument:(NSXMLParser *)parser {
[(id)[self delegate] performSelectorOnMainThread:@selector(processCompleted)
 withObject:nil
 waitUntilDone:NO];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}


-(void)dealloc{
self.currentItem = nil;
self.currentItemValue = nil;
self.delegate = nil;

[_rssItems release];
[super dealloc];
}

@end

BlogRSSParser.h

#import <Foundation/Foundation.h>

@class BlogRss;
@protocol BlogRssParserDelegate;
@interface BlogRssParser : NSObject <NSXMLParserDelegate>{
BlogRss * _currentItem;
NSMutableString * _currentItemValue;
NSMutableArray * _rssItems;
id<BlogRssParserDelegate> _delegate;
NSOperationQueue *_retrieverQueue;
}


@property(nonatomic, retain) BlogRss * currentItem;
@property(nonatomic, retain) NSMutableString * currentItemValue;
@property(readonly) NSMutableArray * rssItems;

@property(nonatomic, assign) id<BlogRssParserDelegate> delegate;
@property(nonatomic, retain) NSOperationQueue *retrieverQueue;

- (void)startProcess;


@end

@protocol BlogRssParserDelegate <NSObject>

-(void)processCompleted;
-(void)processHasErrors;

@end

ViewDidLoad

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
[self toolbarInit];
_rssParser = [[BlogRssParser alloc]init];
self.rssParser.delegate = self;
[[self rssParser]startProcess]; 
}

I am currently having a problem with parsing information from an XML into an NSMutableArray, i have pasted the code below which is for the parser this retrieves the document off the internet and constructs the array. I am then trying to copy the items from the xml parser into an NSMutableArray for searching, but every time i try to copy the array it returns a struct error so i have removed the changes for now.

Here is the code for the parser and the current code for the viewdidload in the main view controller, if anyone can help i would really appreciate it.

#import "BlogRssParser.h"
#import "BlogRss.h"

@implementation BlogRssParser

@synthesize currentItem = _currentItem;
@synthesize currentItemValue = _currentItemValue;
@synthesize rssItems = _rssItems;
@synthesize delegate = _delegate;
@synthesize retrieverQueue = _retrieverQueue;


- (id)init{
if(![super init]){
    return nil;
}
_rssItems = [[NSMutableArray alloc]init];
return self;
}

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

- (void)startProcess{
SEL method = @selector(fetchAndParseRss);
[[self rssItems] removeAllObjects];
NSInvocationOperation *op = [[NSInvocationOperation alloc] initWithTarget:self 
                                                                 selector:method 
                                                                   object:nil];
[self.retrieverQueue addOperation:op];
[op release];
}

-(BOOL)fetchAndParseRss{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];

[UIApplication sharedApplication].networkActivityIndicatorVisible = YES;

//To suppress the leak in NSXMLParser
[[NSURLCache sharedURLCache] setMemoryCapacity:0];
[[NSURLCache sharedURLCache] setDiskCapacity:0];

NSURL *url = [NSURL URLWithString:@"http://xxxxxxxxx.co.uk/rssparser/Data.xml"];
BOOL success = NO;
NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];
[parser setDelegate:self];
[parser setShouldProcessNamespaces:YES];
[parser setShouldReportNamespacePrefixes:YES];
[parser setShouldResolveExternalEntities:NO];
success = [parser parse];
[parser release];
[pool drain];
return success;
}

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI 
 qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict{
if(nil != qualifiedName){
    elementName = qualifiedName;
}
if ([elementName isEqualToString:@"item"]) {
    self.currentItem = [[[BlogRss alloc]init]autorelease];
} else if([elementName isEqualToString:@"title"] || 
          [elementName isEqualToString:@"description"] ||
          [elementName isEqualToString:@"mediaUrl"] ||
          [elementName isEqualToString:@"link"] ||
          [elementName isEqualToString:@"guid"] ||
          [elementName isEqualToString:@"pubDate"]) {
    self.currentItemValue = [NSMutableString string];
} else {
    self.currentItemValue = nil;
}   
}

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if(nil != qName){
    elementName = qName;
}
if([elementName isEqualToString:@"title"]){
    self.currentItem.title = self.currentItemValue;
}else if([elementName isEqualToString:@"description"]){
    self.currentItem.description = self.currentItemValue;
}else if([elementName isEqualToString:@"link"]){
    self.currentItem.linkUrl = self.currentItemValue;
}else if([elementName isEqualToString:@"mediaUrl"]){
    self.currentItem.mediaUrl = self.currentItemValue;
}else if([elementName isEqualToString:@"guid"]){
    self.currentItem.guidUrl = self.currentItemValue;
}else if([elementName isEqualToString:@"pubDate"]){
    NSDateFormatter *formatter = [[NSDateFormatter alloc] init];
    [formatter setDateFormat:@"yyyy-MM-dd'T'HH:mm:ss'Z'"];
    self.currentItem.pubDate = [formatter dateFromString:self.currentItemValue];
    [formatter release];
}else if([elementName isEqualToString:@"item"]){
    [[self rssItems] addObject:self.currentItem];
}
}

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
if(nil != self.currentItemValue){
    [self.currentItemValue appendString:string];
}
}

- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock{
//Not needed for now
}

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
if(parseError.code != NSXMLParserDelegateAbortedParseError) {
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
    [(id)[self delegate] performSelectorOnMainThread:@selector(processHasErrors)
     withObject:nil
     waitUntilDone:NO];
}
}



- (void)parserDidEndDocument:(NSXMLParser *)parser {
[(id)[self delegate] performSelectorOnMainThread:@selector(processCompleted)
 withObject:nil
 waitUntilDone:NO];
[UIApplication sharedApplication].networkActivityIndicatorVisible = NO;
}


-(void)dealloc{
self.currentItem = nil;
self.currentItemValue = nil;
self.delegate = nil;

[_rssItems release];
[super dealloc];
}

@end

BlogRSSParser.h

#import <Foundation/Foundation.h>

@class BlogRss;
@protocol BlogRssParserDelegate;
@interface BlogRssParser : NSObject <NSXMLParserDelegate>{
BlogRss * _currentItem;
NSMutableString * _currentItemValue;
NSMutableArray * _rssItems;
id<BlogRssParserDelegate> _delegate;
NSOperationQueue *_retrieverQueue;
}


@property(nonatomic, retain) BlogRss * currentItem;
@property(nonatomic, retain) NSMutableString * currentItemValue;
@property(readonly) NSMutableArray * rssItems;

@property(nonatomic, assign) id<BlogRssParserDelegate> delegate;
@property(nonatomic, retain) NSOperationQueue *retrieverQueue;

- (void)startProcess;


@end

@protocol BlogRssParserDelegate <NSObject>

-(void)processCompleted;
-(void)processHasErrors;

@end

ViewDidLoad

// Implement viewDidLoad to do additional setup after loading the view, typically from a nib.
- (void)viewDidLoad {
[super viewDidLoad];
[self toolbarInit];
_rssParser = [[BlogRssParser alloc]init];
self.rssParser.delegate = self;
[[self rssParser]startProcess]; 
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

潦草背影 2025-01-03 17:07:08

您的 rssItems 数组被标记为“只读”。

更改:

 @property(readonly) NSMutableArray * rssItems;

 @property(nonatomic, retain) NSMutableArray * rssItems;

You rssItems array is marked "readonly".

Change:

 @property(readonly) NSMutableArray * rssItems;

to

 @property(nonatomic, retain) NSMutableArray * rssItems;
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文