如何解析XML文件并将其计入数组并将其显示在tableview中?

时间:2011-07-07 05:00:30

标签: iphone objective-c xml

我有一个应用程序,我使用NSXMLParser来解析XML file.xml。解析用于读取天气API并在tableview的自定义单元格中显示值。我的问题是值没有添加到数组中。

这是我的XML文件:

<?xml version="1.0" ?> 
- <xml_api_reply version="1">
  - <weather module_id="0" tab_id="0" mobile_row="0" mobile_zipped="1" row="0" section="0">
    - <forecast_information>
        <city data="" /> 
        <postal_code data="" /> 
        <latitude_e6 data="50500000" /> 
        <longitude_e6 data="30500000" /> 
        <forecast_date data="2011-07-07" /> 
        <current_date_time data="2011-07-07 04:00:00 +0000" /> 
        <unit_system data="US" /> 
     </forecast_information>
   </weather>
<xml_api_reply>

我已经获取了forecast_information的元素city和current_date_time的值。

这是我的解析器类:

#import <Foundation/Foundation.h>
@class journeyxmlAppDelegate, forecast_information;


@interface XMLParser : NSObject<NSXMLParserDelegate> 
{
    NSMutableString *currentElementValue;

    journeyxmlAppDelegate *appDelegate;

    forecast_information *f;

}



-(XMLParser*) initXMLParser;

@end

这是解析器.m文件:

#import "XMLParser.h"
#import "journeyxmlAppDelegate.h"
#import "forecast_information.h"

@implementation XMLParser

-(XMLParser *)initXMLParser
{
    [super init];

    appDelegate = (journeyxmlAppDelegate *)[[UIApplication sharedApplication]delegate];

    return self;
}


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

    if([elementName isEqualToString:@"weather"]) {
        //Initialize the array.
        appDelegate = (journeyxmlAppDelegate *)[[UIApplication sharedApplication]delegate];

        appDelegate.xmlapireply = [[NSMutableArray alloc] init];
    }
    else if([elementName isEqualToString:@"forecast_information"]) {

        f = [[forecast_information alloc] init];

        //Extract the attribute here.
        f.city = [attributeDict valueForKey:@"data"];
        f.postal_code = [attributeDict objectForKey:@"data"];
        f.latitude_e6 = [attributeDict objectForKey:@"data"];
        f.longitude_e6 = [attributeDict objectForKey:@"data"];
        f.forecast_date = [attributeDict objectForKey:@"data"];
        f.current_date_time = [attributeDict objectForKey:@"data"];
        f.unit_system = [attributeDict objectForKey:@"data"];

        NSLog(@"%@Reading id value", f.city);
        NSLog(@"%@Reading id value", f.postal_code);
        NSLog(@"%@Reading id value", f.latitude_e6);
        NSLog(@"%@Reading id value", f.longitude_e6);
        NSLog(@"%@Reading id value", f.forecast_date);
        NSLog(@"%@Reading id value", f.current_date_time);
        NSLog(@"%@Reading id value", f.unit_system);
    }



    NSLog(@"Processing Element: %@", elementName);
}


- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { 

    if(!currentElementValue) 
        currentElementValue = [[NSMutableString alloc] initWithString:string];
    else
        [currentElementValue appendString:string];

    NSLog(@"Processing Value: %@", currentElementValue);

}


- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName 
  namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

    if([elementName isEqualToString:@"weather"])
        return;

    if([elementName isEqualToString:@"forecast_information"]) {
        [appDelegate.xmlapireply addObject:f];

        [f release];
        f = nil;
    }
    else {


    [f setValue:currentElementValue forKey:elementName];
    [currentElementValue release];
    currentElementValue = nil;
    }

}


- (void) dealloc {

    [f release];
    [currentElementValue release];
    [super dealloc];
}


@end

这是我的元素预测信息类

#import <UIKit/UIKit.h>


@interface forecast_information : NSObject 
{
    NSString *city;
    NSString *postal_code;
    NSString *latitude_e6; 
    NSString *longitude_e6; 
    NSString *forecast_date;  
    NSString *current_date_time;  
    NSString *unit_system; 
}
@property (nonatomic,retain) NSString *city;
@property (nonatomic,retain) NSString *postal_code;
@property (nonatomic,retain) NSString *latitude_e6;
@property (nonatomic,retain) NSString *longitude_e6; 
@property (nonatomic,retain) NSString *forecast_date;
@property (nonatomic,retain) NSString *current_date_time;
@property (nonatomic,retain) NSString *unit_system; 

@end

这是.m文件

#import "forecast_information.h"


@implementation forecast_information
@synthesize city;
@synthesize postal_code;
@synthesize latitude_e6;
@synthesize longitude_e6;
@synthesize forecast_date;
@synthesize current_date_time;
@synthesize unit_system;


- (void) dealloc 
{
    [super dealloc];
    [city release];
    [postal_code release];
    [latitude_e6 release];
    [longitude_e6 release];
    [forecast_date release];
    [current_date_time release];
    [unit_system release];

}

@end

这是我的控制器类,我在tableview中显示值。

#import <UIKit/UIKit.h>
@class journeyxmlAppDelegate;

@interface RootViewController : UITableViewController
{
    journeyxmlAppDelegate *appDelegate;

}

@end

RootViewController.m

#import "RootViewController.h"
#import "journeyxmlAppDelegate.h"
#import "forecast_information.h"
#import "current_conditions.h"
#import "forecast_conditions.h"
#import "TWeatherCell.h"

@implementation RootViewController


#pragma mark -
#pragma mark View lifecycle


- (void)viewDidLoad {
    [super viewDidLoad];

    // Uncomment the following line to display an Edit button in the navigation bar for this view controller.
    // self.navigationItem.rightBarButtonItem = self.editButtonItem;
    appDelegate = (journeyxmlAppDelegate *)[[UIApplication sharedApplication] delegate];
}


#pragma mark -
#pragma mark Table view data source

// Customize the number of sections in the table view.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    return 1;
}


// Customize the number of rows in the table view.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return [appDelegate.xmlapireply count];
}


// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {

    static NSString *CellIdentifier = @"Cell";

    TWeatherCell *cell =(TWeatherCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
       cell = [[[TWeatherCell alloc] initWithStyle:UITableViewStyleGrouped reuseIdentifier:CellIdentifier] autorelease];
    }

    forecast_information *f = [appDelegate.xmlapireply objectAtIndex:indexPath.row];
    NSLog(@"Value of f:%@",f);
    switch (indexPath.row) {
        case 0:
            cell.reportdate.text = f.city;
            break;
        case 1:
            cell.conditionname.text = f.postal_code;
            break;
        case 2:
            cell.twotemp.text = f.current_date_time;
            cell.humidity.text = f.unit_system;
            break;
    }

    return cell;
}

问题是我的tableview单元格中没有显示任何值。可能是什么问题?

2 个答案:

答案 0 :(得分:0)

可能您可能忘记分配数组。

修改

如果这是xml,那么你可能只得到一个计数。

 - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath

这将只执行一次,因为您的数组计数为1.

        case 1:
            cell.conditionname.text = f.postal_code;
            break;
        case 2:
            cell.twotemp.text = f.current_date_time;
            cell.humidity.text = f.unit_system;
            break;

这不会被执行,只会执行大小写0.明白地理解cellForRowAtIndexPath的使用。

答案 1 :(得分:0)

您需要实现- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;委托方法并将字符串的字符累积到在init或begin parse中分配的NSMutableString *实例变量中。此实例变量将包含endTag...委托方法中每个标记的值。

此外,您可能希望实现- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict;委托方法,以便它可以清空当前(新)标记的NSMutableString实例变量。

参见“事件驱动的XML编程指南”http://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/XMLParsing/Articles/HandlingElements.html%23//apple_ref/doc/uid/20002265-BCIJFGJI清单3引用“currentStringValue”