RSS解析新浪新闻IOS


CategoryViewController.h

#import <UIKit/UIKit.h>

#import "QFHttpDownloadDelegate.h"

@interface CategoryViewController : UITableViewController <QFHttpDownloadDelegate>
{
    //保存所有分类信息
    NSMutableArray * dataArray;
    QFHttpDownload * httpDownload;
}

@end


CategoryViewController.m

#import "CategoryViewController.h"
#import "CategoryItem.h"
#import "RssItem.h"
#import "QFHttpDownload.h"
#import "NewsListViewController.h"
#import "GDataXMLNode.h"

@interface CategoryViewController ()

@end

@implementation CategoryViewController

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
    }
    return self;
}

- (void)viewDidLoad
{
    [super viewDidLoad];

    dataArray = [[NSMutableArray alloc] init];
    httpDownload = [[QFHttpDownload alloc] init];
    httpDownload.delegate = self;
    [httpDownload downloadFromUrl:@"http://rss.sina.com.cn/sina_all_opml.xml"];
}

-(NSString *)elementAttr:(GDataXMLElement *)element name:(NSString *)name
{
    //从当前节点中根据属性名获得属性值
    GDataXMLNode * node = [element attributeForName:name];
    return [node stringValue];
}

-(void)downloadComplete:(QFHttpDownload *)hd
{
    GDataXMLDocument * doc = [[[GDataXMLDocument alloc] initWithData:hd.downloadData options:0 error:nil] autorelease];
    if(doc){
        //获得所有外层outline节点
        NSArray * array = [doc nodesForXPath:@"/opml/body/outline" error:nil];
        for(GDataXMLElement * element in array){
            CategoryItem * citem = [[[CategoryItem alloc] init] autorelease];
            citem.title = [self elementAttr:element name:@"title"];
            NSMutableArray * subArray = [NSMutableArray array];
            //遍历当前节点的所有子节点(内层outline)
            for(GDataXMLElement * subElement in [element children]){
                RssItem * ritem = [[[RssItem alloc] init] autorelease];
                ritem.title = [self elementAttr:subElement name:@"title"];
                ritem.url = [self elementAttr:subElement name:@"xmlUrl"];
                [subArray addObject:ritem];
            }
            citem.subArray = subArray;
            [dataArray addObject:citem];
        }
        [self.tableView reloadData];
    }
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return [dataArray count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    CategoryItem * item = [dataArray objectAtIndex:section];
    return [item.subArray count];
}

-(NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
    CategoryItem * item = [dataArray objectAtIndex:section];
    return item.title;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    if(cell == nil){
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
    }
    CategoryItem * cItem = [dataArray objectAtIndex:indexPath.section];
    RssItem * rItem = [cItem.subArray objectAtIndex:indexPath.row];
    cell.textLabel.text = rItem.title;
    cell.detailTextLabel.text = rItem.url;
    
    return cell;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    return 60.0f;
}

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    NewsListViewController * nlvc = [[NewsListViewController alloc] initWithStyle:UITableViewStylePlain];
    CategoryItem * cItem = [dataArray objectAtIndex:indexPath.section];
    RssItem * rItem = [cItem.subArray objectAtIndex:indexPath.row];
    nlvc.url = rItem.url;
    [self.navigationController pushViewController:nlvc animated:YES];
    [nlvc release];
}

@end

NewsListViewController.h

#import <UIKit/UIKit.h>
#import "QFHttpDownloadDelegate.h"
#import "EGORefreshTableHeaderView.h"

@interface NewsListViewController : UITableViewController <QFHttpDownloadDelegate, EGORefreshTableHeaderDelegate>
{
    NSMutableArray * dataArray;
    QFHttpDownload * httpDownload;
    NSUInteger curPage; //当前页码
    NSUInteger pageCount; //总页数
    NSUInteger perPageCount;//每页的数据条数
    
    BOOL isLoading; //是否正在请求数据
    
    //下拉刷新视图
    EGORefreshTableHeaderView * refreshView;
}

//当前分类源地址
@property (nonatomic, copy) NSString * url;
@property (nonatomic, retain) NSMutableArray * curPageArray;//当前页码的数据

@end


NewsListViewController.m

#import "NewsListViewController.h"
#import "NewsItem.h"
#import "QFHttpDownload.h"
#import "GDataXMLNode.h"
#import "NewsCell.h"

@interface NewsListViewController ()

@end


@implementation NewsListViewController

@synthesize url = _url;
@synthesize curPageArray = _curPageArray;

-(void)dealloc
{
    httpDownload.delegate = nil;
    [httpDownload release];
    [super dealloc];
}

- (id)initWithStyle:(UITableViewStyle)style
{
    self = [super initWithStyle:style];
    if (self) {
        // Custom initialization
        UIBarButtonItem * leftitem = [[UIBarButtonItem alloc] initWithTitle:@"前一页" style:UIBarButtonItemStyleDone target:self action:@selector(perClicked:)];
        self.navigationItem.leftBarButtonItem = leftitem;
        [leftitem release];
        
        UIBarButtonItem * rightitem = [[UIBarButtonItem alloc] initWithTitle:@"后一页" style:UIBarButtonItemStyleDone target:self action:@selector(nextClicked:)];
        self.navigationItem.rightBarButtonItem = rightitem;
        [rightitem release];
    }
    return self;
}

-(void)perClicked:(UIBarButtonItem *)item
{
    if(isLoading){
        return;
    }
    if([item.title isEqualToString:@"Back"]){
        [self.navigationController popToRootViewControllerAnimated:YES];
    }
    curPage--;
    if(curPage < 1){
        curPage = 1;
        [item setTitle:@"第一页"];
    }
}

-(void)nextClicked:(UIBarButtonItem *)item
{
    if(isLoading){
        return;
    }
    curPage++;
    if(curPage > pageCount){
        curPage = pageCount;
    }
//    [self loadData:curPage count:perPageCount];
}


- (void)viewDidLoad
{
    [super viewDidLoad];

    dataArray = [[NSMutableArray alloc] initWithCapacity:0];
    httpDownload = [[QFHttpDownload alloc] init];
    httpDownload.delegate = self;
    
    [httpDownload downloadFromUrl:self.url];
    isLoading = YES;
    
    CGRect frame = self.tableView.frame;
    frame.origin.y -= (frame.size.height + 24);
    refreshView = [[EGORefreshTableHeaderView alloc] initWithFrame:frame];
    refreshView.delegate = self;
    [self.tableView addSubview:refreshView];
    //最新刷新时间
    [refreshView refreshLastUpdatedDate];
    
    curPage = 1;
    perPageCount = 10;
    pageCount = 888888;
}

//滚动视图发生滚动
-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
    [refreshView egoRefreshScrollViewDidScroll:scrollView];
}

//停止拖拽
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    [refreshView egoRefreshScrollViewDidEndDragging:scrollView];
}

//当前是否正在刷新
-(BOOL)egoRefreshTableHeaderDataSourceIsLoading:(EGORefreshTableHeaderView *)view
{
    return isLoading;
}

//最后刷新时间
-(NSDate *)egoRefreshTableHeaderDataSourceLastUpdated:(EGORefreshTableHeaderView *)view
{
    return [NSDate date];
}

//在此方法中重新加载数据(触发了刷新)
-(void)egoRefreshTableHeaderDidTriggerRefresh:(EGORefreshTableHeaderView *)view
{
    [self nextClicked:nil];
}

-(void)viewDidDisappear:(BOOL)animated
{
    httpDownload.delegate = nil;
    [super viewDidDisappear:animated];
}

//获得节点element的指定的子节点(name)的值(文本信息)
-(NSString *)element:(GDataXMLElement *)element name:(NSString *)name
{
    NSArray * array = [element elementsForName:name];
    GDataXMLElement * subElement = [array lastObject];
    return [subElement stringValue];
}

-(void)downloadComplete:(QFHttpDownload *)hd
{
    GDataXMLDocument * doc = [[GDataXMLDocument alloc] initWithData:hd.downloadData options:0 error:nil];
    if(doc){
        NSArray * array = [doc nodesForXPath:@"//item" error:nil];
        for(GDataXMLElement * itemElement in array){
            NewsItem * item = [[[NewsItem alloc] init] autorelease];
            item.title = [self element:itemElement name:@"title"];
            item.summary = [self element:itemElement name:@"description"];
            item.link = [self element:itemElement name:@"link"];
            item.pubdate = [self element:itemElement name:@"pubDate"];
            [dataArray addObject:item];
        }
        [self.tableView reloadData];
    }else{
        NSLog(@"没有数据");
    }
    //通知下拉刷新视图结束
    [refreshView egoRefreshScrollViewDataSourceDidFinishedLoading:self.tableView];
    isLoading = NO;
}

- (void)didReceiveMemoryWarning
{
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

#pragma mark - Table view data source

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
    return [dataArray count];
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *CellIdentifier = @"Cell";
//    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
//    
//    if(nil == cell){
//        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
//    }
//    NewsItem * item = [dataArray objectAtIndex:indexPath.row];
//    cell.textLabel.text = item.title;
//    cell.textLabel.numberOfLines = 0;
//    cell.detailTextLabel.text = [NSString stringWithFormat:@"%@\n%@", item.summary, item.link];
//    cell.detailTextLabel.numberOfLines = 5;
    
    NewsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    
    if(nil == cell){
        cell = [[[NSBundle mainBundle] loadNibNamed:@"NewsCell" owner:self options:nil] lastObject];
    }
    NewsItem * item = [dataArray objectAtIndex:indexPath.row];
    cell.titleLabel.numberOfLines = 0;

    cell.titleLabel.text = item.title;
    //设置计算高度时的参数
    cell.summaryLabel.font = [UIFont systemFontOfSize:14];
    cell.summaryLabel.lineBreakMode = NSLineBreakByCharWrapping;
    //设置行数为0,有多少显示多少
    cell.summaryLabel.numberOfLines = 0;
    //得新设置标签的高度
    CGRect frame = cell.summaryLabel.frame;
    frame.size.height = item.height;
    cell.summaryLabel.frame = frame;
    
    cell.summaryLabel.text = item.summary;
    cell.linkLabel.text = item.link;
    cell.pubDateLabel.text = [NSString stringWithFormat:@"北京发布时间: %@", item.pubdate];
    cell.pubDateLabel.font = [UIFont systemFontOfSize:13];

    
    return cell;
}

-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NewsItem * item = [dataArray objectAtIndex:indexPath.row];
    if([item.summary isEqualToString:@""]){
        return 49 + [item height] + 10;
    }
    return 100 + [item height] + 49;
}

-(void)tableView:(UITableView *)tableView willDisplayCell:(UITableViewCell *)cell forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if(indexPath.row % 4 == 0){
        cell.backgroundColor = [UIColor greenColor];
    }else if(indexPath.row % 4 == 1){
        cell.backgroundColor = [UIColor purpleColor];
    }else if(indexPath.row % 4 == 2){
        cell.backgroundColor = [UIColor yellowColor];
    }else{
        cell.backgroundColor = [UIColor orangeColor];
    }
}


/*
// Override to support conditional editing of the table view.
- (BOOL)tableView:(UITableView *)tableView canEditRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the specified item to be editable.
    return YES;
}
*/

/*
// Override to support editing the table view.
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (editingStyle == UITableViewCellEditingStyleDelete) {
        // Delete the row from the data source
        [tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationFade];
    }   
    else if (editingStyle == UITableViewCellEditingStyleInsert) {
        // Create a new instance of the appropriate class, insert it into the array, and add a new row to the table view
    }   
}
*/

/*
// Override to support rearranging the table view.
- (void)tableView:(UITableView *)tableView moveRowAtIndexPath:(NSIndexPath *)fromIndexPath toIndexPath:(NSIndexPath *)toIndexPath
{
}
*/

/*
// Override to support conditional rearranging of the table view.
- (BOOL)tableView:(UITableView *)tableView canMoveRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Return NO if you do not want the item to be re-orderable.
    return YES;
}
*/

#pragma mark - Table view delegate

- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
    // Navigation logic may go here. Create and push another view controller.
    /*
     <#DetailViewController#> *detailViewController = [[<#DetailViewController#> alloc] initWithNibName:@"<#Nib name#>" bundle:nil];
     // ...
     // Pass the selected object to the new view controller.
     [self.navigationController pushViewController:detailViewController animated:YES];
     [detailViewController release];
     */
}

@end

CategoryItem.h

#import <Foundation/Foundation.h>

@interface CategoryItem : NSObject
//一级分类名
@property (nonatomic, copy) NSString * title;
//子分类的信息数组
@property (nonatomic, retain) NSArray * subArray;

@end


CategoryItem.m

#import "CategoryItem.h"

@implementation CategoryItem

@synthesize title = _title;
@synthesize subArray = _subArray;

-(void)dealloc
{
    self.title = nil;
    self.subArray = nil;
    [super dealloc];
}

@end

RssItem.h

#import <Foundation/Foundation.h>

@interface RssItem : NSObject

//子分类标题
@property (nonatomic, copy) NSString * title;
//子分类的地址
@property (nonatomic, copy) NSString * url;

@end

RssItem.m

#import "RssItem.h"

@implementation RssItem

@synthesize title = _title;
@synthesize url = _url;

-(void)dealloc
{
    self.title = nil;
    self.url = nil;
    [super dealloc];
}

@end


NewsItem.h

#import <Foundation/Foundation.h>

@interface NewsItem : NSObject

@property (nonatomic, copy) NSString * title;
@property (nonatomic, copy) NSString * pubdate;
@property (nonatomic, copy) NSString * summary;
@property (nonatomic, copy) NSString * link;

//获得动态信息的高度
-(CGFloat)height;

@end

NewsItem.m

#import "NewsItem.h"

@implementation NewsItem

@synthesize title = _title;
@synthesize link = _link;
@synthesize summary = _summary;
@synthesize pubdate = _pubdate;

-(void)dealloc
{
    self.title = nil;
    self.link = nil;
    self.summary = nil;
    self.pubdate = nil;
    [super dealloc];
}

-(CGFloat)height
{
    //根据字体,显示的宽度,以及换行方式计算字符串高度
    CGSize size = [self.summary sizeWithFont:[UIFont systemFontOfSize:14] constrainedToSize:CGSizeMake(300, CGFLOAT_MAX) lineBreakMode:NSLineBreakByCharWrapping];
    return size.height;
}

@end

NewsCell.h


#import <UIKit/UIKit.h>

@interface NewsCell : UITableViewCell
@property (retain, nonatomic) IBOutlet UILabel *titleLabel;
@property (retain, nonatomic) IBOutlet UILabel *summaryLabel;
@property (retain, nonatomic) IBOutlet UILabel *linkLabel;
@property (retain, nonatomic) IBOutlet UILabel *pubDateLabel;

@end

NewsCell.m


#import "NewsCell.h"

@implementation NewsCell

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
    if (self) {
        // Initialization code
    }
    return self;
}

- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
    [super setSelected:selected animated:animated];

    // Configure the view for the selected state
}

- (void)dealloc {
    [_titleLabel release];
    [_summaryLabel release];
    [_linkLabel release];
    [_pubDateLabel release];
    [super dealloc];
}
@end







  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用SAX解析器实现RSS Feed文件的解析,可以按照以下步骤进行: 1. 创建SAXParserFactory和SAXParser对象:首先需要创建SAXParserFactory对象和SAXParser对象,使用它们来解析RSS Feed文件。 ```java SAXParserFactory factory = SAXParserFactory.newInstance(); SAXParser parser = factory.newSAXParser(); ``` 2. 创建RSSFeedHandler类:创建一个RSSFeedHandler类,继承自DefaultHandler类,用于处理SAX解析解析XML文件时的事件。 ```java public class RSSFeedHandler extends DefaultHandler { // 处理startElement事件 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { // ... } // 处理endElement事件 @Override public void endElement(String uri, String localName, String qName) throws SAXException { // ... } // 处理characters事件 @Override public void characters(char[] ch, int start, int length) throws SAXException { // ... } } ``` 3. 实现RSSFeedHandler类的方法:在RSSFeedHandler类中实现startElement、endElement和characters等方法,用于处理XML文件中的元素和内容。比如,在startElement方法中,可以判断当前元素是否是item元素,如果是,则创建一个RSSItem对象,并将其添加到RSS Feed中。 ```java public class RSSFeedHandler extends DefaultHandler { private RSSFeed feed; private RSSItem item; // 处理startElement事件 @Override public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException { if (qName.equalsIgnoreCase("item")) { item = new RSSItem(); feed.addItem(item); } else if (qName.equalsIgnoreCase("title") && item != null) { item.setTitle(true); } else if (qName.equalsIgnoreCase("link") && item != null) { item.setLink(true); } else if (qName.equalsIgnoreCase("description") && item != null) { item.setDescription(true); } } // 处理endElement事件 @Override public void endElement(String uri, String localName, String qName) throws SAXException { if (qName.equalsIgnoreCase("item")) { item = null; } } // 处理characters事件 @Override public void characters(char[] ch, int start, int length) throws SAXException { if (item != null) { item.addContent(new String(ch, start, length)); } } } ``` 4. 解析RSS Feed文件:使用SAXParser对象的parse方法,解析RSS Feed文件,并将RSS Feed对象返回。 ```java public RSSFeed parse(String url) throws Exception { RSSFeedHandler handler = new RSSFeedHandler(); parser.parse(url, handler); return handler.getFeed(); } ``` 总体来说,使用SAX解析器实现RSS Feed文件的解析,需要创建SAXParserFactory对象和SAXParser对象,实现RSSFeedHandler类的方法,并使用SAXParser对象的parse方法解析RSS Feed文件。SAX解析器是一种基于事件驱动的解析器,相比DOM解析器,它更加轻量级,适合处理大型XML文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值