督导系统iOS开发解析XML
先看效果图:
XML文件(**学院.xml):
<?xml version="1.0" encoding="UTF-8"?>
-<resources>
-<string-array name="语音室">
<item>语音室1</item>
<item>语音室2</item>
<item>语音室3</item>
<item>语音室4</item>
</string-array>
</resources>
item和string-array都是xml中的元素,其中元素string-array中的name=”***”,是元素的属性。
下面讲解下在iOS中解析xml的方法:
1、先创建一个类AppRecord不带任何窗口的class
//
// AppRecord.h
// ClassroomXML
//
// Created by apple on 12-10-11.
// Copyright 2012年 __MyCompanyName__. All rights reserved.
//
//定义一个保存xml解析数据类,该类使用了NSCoding协议
#import <Foundation/Foundation.h>
@interface AppRecord : NSObject <NSCoding>
{
NSString *appString_Array;
NSString *appItem;
}
@property (nonatomic, retain) NSString *appString_Array;
@property (nonatomic, retain) NSString *appItem;
@end
//
// AppRecord.m
// ClassroomXML
//
// Created by apple on 12-10-11.
// Copyright 2012年 __MyCompanyName__. All rights reserved.
//
#import "AppRecord.h"
@implementation AppRecord
@synthesize appString_Array;
@synthesize appItem;
-(void)dealloc
{
[appItem release];
[appString_Array release];
[super dealloc];
}
//编码,当对象需要保存自身时调用
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.appString_Array forKey:@"appString_Array"];
[aCoder encodeObject:self.appItem forKey:@"appItem"];
}
//解码并初始化,当对象需要加载自身时调用
- (id) initWithCoder:(NSCoder *)aDecoder
{
if (self == [super init])
{
self.appString_Array =[aDecoder decodeObjectForKey:@"appString_Array"];
self.appItem = [aDecoder decodeObjectForKey:@"appItem"];
}
return self;
}
@end
//
// AppRecord.m
// ClassroomXML
//
// Created by apple on 12-10-11.
// Copyright 2012年 __MyCompanyName__. All rights reserved.
//
#import "AppRecord.h"
@implementation AppRecord
@synthesize appString_Array;
@synthesize appItem;
-(void)dealloc
{
[appItem release];
[appString_Array release];
[super dealloc];
}
//编码,当对象需要保存自身时调用
- (void)encodeWithCoder:(NSCoder *)aCoder
{
[aCoder encodeObject:self.appString_Array forKey:@"appString_Array"];
[aCoder encodeObject:self.appItem forKey:@"appItem"];
}
//解码并初始化,当对象需要加载自身时调用
- (id) initWithCoder:(NSCoder *)aDecoder
{
if (self == [super init])
{
self.appString_Array =[aDecoder decodeObjectForKey:@"appString_Array"];
self.appItem = [aDecoder decodeObjectForKey:@"appItem"];
}
return self;
}
@end
2、该工程需要add进所用到的xml文件
//
// BaseCheckView.m
// SteeringSystem
//
// Created by apple on 12-10-14.
// Copyright 2012年 __MyCompanyName__. All rights reserved.
//
#import "BaseCheckView.h"
#import "ASIHTTPRequest.h"
#import "ASIFormDataRequest.h"
#import "JSONKit.h"
#import "ClassSituation.h"
@implementation BaseCheckView
//创建tableview
@synthesize SchoolDistrictTableView;
@synthesize ClassTypeTableView;
@synthesize LessonClassroomTableView;
@synthesize LessonSectionTableView;
@synthesize submitView;
@synthesize SchoolDistrictText;
@synthesize LessonDateText;
@synthesize ClassTypeText;
@synthesize LessonClassroomText;
@synthesize LessonSectionText;
@synthesize DistrictNumText;
@synthesize LessonDatePicker;
@synthesize LessonDateToolbar;
//先建窗口view,为tableview做准备
@synthesize SchoolDistrictView;
@synthesize ClassTypeView;
@synthesize LessonClassroomView;
@synthesize LessonSectionView;
@synthesize baseCheckView;
//创建数组
@synthesize schoolDistrictList,classTypeList,lessonSectionList,lessonClassroomList;
//xml
@synthesize xmlData;
@synthesize parserXML;
@synthesize dataToParse,workingArray,workingEntry,workingPropertyString,elementsToParse;
//定义需要从xml中解析的元素
//static NSString *kStringArray = @"string-array";
static NSString *kItem = @"item";
//xml
//取课室类别
@synthesize ClassTypeArray;
//取具体课室
@synthesize LessonClassroomArray;
//特定的课室
@synthesize OneClassType;
//解析过程变动的课室
@synthesize MovingClassType;
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
self.title = @"督导信息录入";
UIBarButtonItem *SearchButton = [[UIBarButtonItem alloc]initWithTitle:@"下一步" style:UIBarButtonItemStyleBordered target:self action:@selector(NextStep)];
UIBarButtonItem *BackButton = [[UIBarButtonItem alloc]initWithTitle:@"返回" style:UIBarButtonItemStyleBordered target:self action:@selector(ReturnToMain)];
self.navigationItem.rightBarButtonItem = SearchButton;
self.navigationItem.leftBarButtonItem = BackButton;
}
return self;
}
- (void)dealloc
{
[SchoolDistrictText release];
[LessonDateText release];
[ClassTypeText release];
[LessonClassroomText release];
[LessonSectionText release];
[DistrictNumText release];
[LessonDatePicker release];
[LessonDateToolbar release];
[submitView release];
[LessonDatePicker release];
//先建窗口view,为tableview做准备
[SchoolDistrictView release];
[ClassTypeView release];
[LessonClassroomView release];
[LessonSectionView release];
//创建tableview
[SchoolDistrictTableView release];
[ClassTypeTableView release];
[LessonClassroomTableView release];
[LessonSectionTableView release];
//xml
[xmlData release];
[parserXML release];
[dataToParse release];
[workingEntry release];
[workingArray release];
[workingPropertyString release];
[elementsToParse release];
//xml
[baseCheckView release];
//取课室类别
[ClassTypeArray release];
//取具体课室
[LessonClassroomArray release];
//特定的课室
[OneClassType release];
//解析过程变动的课室
[MovingClassType release];
[super dealloc];
}
- (void)didReceiveMemoryWarning
{
// Releases the view if it doesn't have a superview.
[super didReceiveMemoryWarning];
// Release any cached data, images, etc that aren't in use.
}
#pragma mark - View lifecycle
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view from its nib.
[self.view addSubview:self.baseCheckView];
//初始化数组
self.schoolDistrictList = [NSArray arrayWithObjects:@"大学城",@"龙洞",@"东风路",@"商学院", nil];
self.lessonSectionList = [NSArray arrayWithObjects:@"1,2",@"3,4",@"5",@"6,7",@"8,9",@"10,11,12" ,nil];
//显示校区和节次
//self.SchoolDistrictText.text = [self.schoolDistrictList objectAtIndex:0];
self.LessonSectionText.text = [self.lessonSectionList objectAtIndex:0];
//取课室类别
self.ClassTypeArray = [[NSMutableArray alloc] init];
//取有关的教室
self.LessonClassroomArray = [[NSMutableArray alloc] init];
//课室
self.OneClassType = [[NSString alloc] init];
self.MovingClassType = [[NSString alloc] init];
}
- (void)viewDidUnload
{
[self setSchoolDistrictText:nil];
[self setLessonDateText:nil];
[self setClassTypeText:nil];
[self setLessonClassroomText:nil];
[self setLessonSectionText:nil];
[self setDistrictNumText:nil];
[self setLessonDatePicker:nil];
[self setLessonDateToolbar:nil];
[self setLessonDatePicker:nil];
//先建窗口view,为tableview做准备
[self setSchoolDistrictView:nil];
[self setClassTypeView:nil];
[self setLessonClassroomView:nil];
[self setLessonSectionView:nil];
//创建tableview
[self setSchoolDistrictTableView:nil];
[self setClassTypeTableView:nil];
[self setLessonClassroomTableView:nil];
[self setLessonSectionTableView:nil];
//[self setbaseCheckView: nil];
//xml
self.xmlData = nil;
self.parserXML = nil;
self.dataToParse = nil;
self.workingArray = nil;
self.workingEntry = nil;
self.workingPropertyString = nil;
self.elementsToParse = nil;
//xml
//取课室类别
self.ClassTypeArray = nil;
//取具体课室
self.LessonClassroomArray = nil;
//特定的课室
self.OneClassType = nil;
//解析过程变动的课室
self.MovingClassType = nil;
[super viewDidUnload];
// Release any retained subviews of the main view.
// e.g. self.myOutlet = nil;
}
- (BOOL)shouldAutorotateToInterfaceOrientation:(UIInterfaceOrientation)interfaceOrientation
{
// Return YES for supported orientations
return (interfaceOrientation == UIInterfaceOrientationPortrait);
}
- (IBAction)schoolDistrictButton:(id)sender
{
// 设置选择框为空
NSString *nothing = @"";
self.ClassTypeText.text = nothing ;
self.LessonClassroomText.text = nothing;
[LessonDatePicker removeFromSuperview];
[LessonDateToolbar removeFromSuperview];
[self.ClassTypeTableView removeFromSuperview];
[self.LessonClassroomTableView removeFromSuperview];
[self.LessonSectionTableView removeFromSuperview];
[self.view addSubview:self.SchoolDistrictTableView];
}
- (IBAction)lessonDateButton:(id)sender {
[self.view addSubview:LessonDatePicker];
[self.view addSubview:LessonDateToolbar];
}
- (void) ReturnToMain
{
[self.navigationController popViewControllerAnimated:YES];
}
- (IBAction)classTypeButton:(id)sender
{
self.MovingClassType = nil;
self.OneClassType = nil;
// 设置选择框为空
NSString *nothing = @"";
self.LessonClassroomText.text = nothing;
[LessonDatePicker removeFromSuperview];
[LessonDateToolbar removeFromSuperview];
[self.SchoolDistrictTableView removeFromSuperview];
[self.LessonClassroomTableView removeFromSuperview];
[self.LessonSectionTableView removeFromSuperview];
[self.view addSubview:self.ClassTypeTableView];
}
- (IBAction)lessonClassButton:(id)sender
{
[LessonDatePicker removeFromSuperview];
[LessonDateToolbar removeFromSuperview];
[self.SchoolDistrictTableView removeFromSuperview];
[self.ClassTypeTableView removeFromSuperview];
[self.LessonSectionTableView removeFromSuperview];
[self.view addSubview:self.LessonClassroomTableView];
}
- (IBAction)lessonSectionButton:(id)sender
{
[LessonDatePicker removeFromSuperview];
[LessonDateToolbar removeFromSuperview];
[self.SchoolDistrictTableView removeFromSuperview];
[self.LessonClassroomTableView removeFromSuperview];
[self.ClassTypeTableView removeFromSuperview];
[self.view addSubview:self.LessonSectionTableView];
}
- (IBAction)lessonDatePickerDone:(id)sender {
NSDate *date = [LessonDatePicker date];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc]init];
[dateFormatter setDateFormat:@"yyyy-MM-dd"];
LessonDateText.text = [dateFormatter stringFromDate:date];
[self.LessonDatePicker removeFromSuperview];
[self.LessonDateToolbar removeFromSuperview];
}
-(IBAction) textFiledReturnEditing:(id)sender
{
[sender resignFirstResponder];
}
- (IBAction)backGroundTouch:(id)sender {
[SchoolDistrictText resignFirstResponder];
[ClassTypeText resignFirstResponder];
[LessonClassroomText resignFirstResponder];
[LessonSectionText resignFirstResponder];
[LessonDatePicker removeFromSuperview];
[LessonDateToolbar removeFromSuperview];
//移除tableview
[self.SchoolDistrictTableView removeFromSuperview];
[self.ClassTypeTableView removeFromSuperview];
[self.LessonClassroomTableView removeFromSuperview];
[self.LessonSectionTableView removeFromSuperview];
}
- (NSString*)GetDistrictNum
{
if (SchoolDistrictText.text == @"大学城")
return @"1";
else if (SchoolDistrictText.text == @"龙洞")
return @"2";
else if (SchoolDistrictText.text == @"东风路")
return @"3";
else if (SchoolDistrictText.text == @"商学院")
return @"4";
else
return NULL ;
}
//这里有关解析xml的三个方法:
//----------------------------------------
//遍历xml的节点
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
//判断elementName与string-array是否相等
if ([elementName isEqualToString:@"string-array"])
{
//相等的话,重新初始化workingEntry
self.workingEntry = [[[AppRecord alloc] init] autorelease];
self.workingEntry.appString_Array = [attributeDict objectForKey:@"name"];
//这步是将解析到的属性都存进数组ClassTypeArray 里面
[ClassTypeArray addObject:[attributeDict objectForKey:@"name"]];
self.MovingClassType = [attributeDict objectForKey:@"name"];
}
//查询指定对象是否存在,我们需要保存的那两个对象,开头定义的两个static
storingCharacterData = [elementsToParse containsObject:elementName];
//self.classTypeList = [NSArray arrayWithArray:ClassTypeArray];
}
//节点有值则调用此方法
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if (storingCharacterData)
{
//string添加到workingPropertyString中
[workingPropertyString appendString:string];
}
}
// 当遇到结束标记时,进入此句
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
//判断workingEntry是否为空
if (self.workingEntry)
{
if (storingCharacterData)
{
//NSString的方法,去掉字符串前后的空格
NSString *trimmedString = [workingPropertyString stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
//将字符串置空
[workingPropertyString setString:@""];
//根据元素名,进行相应的存储
//NSLog(@"%@",MovingClassType);
//NSLog(@"%@",OneClassType);
if ([elementName isEqualToString:@"item"])
{
self.workingEntry.appItem = trimmedString;
//两个都是NSString,MovingClassType存的是解析时不断变化的属性,OneClassType存的是在tableview选择后显示在 课室类别的textfield中的内容,当解析xml到某种课室类别时就将该类课室全部存进LessonClassroomArray 数组里
if ([MovingClassType isEqualToString: OneClassType])
{
[LessonClassroomArray addObject:trimmedString];
}
}
}
}
//遇到string-array时,将本次解析的数据workingArray中,AppRecord对象置空
if ([elementName isEqualToString:@"string-array"])
{
[self.workingArray addObject:self.workingEntry];
self.workingEntry = nil;
//用于检测数组中是否已保存,实际使用时可去掉,保存的是AppRecord的地址
//NSLog(@"%@",workingArray);
}
}
//清除cell的信息的其中一步
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
[self performSelectorOnMainThread:@selector(tableReload) withObject:nil waitUntilDone:NO];
}
-(void) tableReload
{
[self.ClassTypeTableView reloadData];
[self.LessonClassroomTableView reloadData];
}
//----------------------------------------
//---------------------------------------------
//这里在显示tableView的内容,并点击选择的内容,进行逐步解析xml文件
#pragma mark -
#pragma mark date Source
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
{
return 20;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
if (tableView == self.SchoolDistrictTableView)
{return [self.schoolDistrictList count];}
else if(tableView == self.ClassTypeTableView)
{
return [self.classTypeList count];
}
else if (tableView == self.LessonClassroomTableView)
{ return [self.lessonClassroomList count];}
else
return [self.lessonSectionList count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *TableIdentifier = @"theTableIdentifier";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:TableIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc]initWithStyle:UITableViewCellStyleDefault reuseIdentifier:TableIdentifier];
}
//删除cell.contentView中所有内容,避免以下建立新的重复
int i = [[cell.contentView subviews] count] -1;
for (; i >= 0; i -- )
{
[[[cell.contentView subviews] objectAtIndex:i] removeFromSuperview];
}
NSUInteger row = [indexPath row];
cell.textLabel.textAlignment = UITextAlignmentCenter;
if (tableView == self.SchoolDistrictTableView)
{
cell.textLabel.text = [self.schoolDistrictList objectAtIndex:row];
}
else if(tableView == self.ClassTypeTableView)
{
cell.textLabel.text = [self.classTypeList objectAtIndex:row];
}
else if (tableView == self.LessonClassroomTableView)
{
cell.textLabel.text = [self.lessonClassroomList objectAtIndex:row];
}
else
{
cell.textLabel.text =[self.lessonSectionList objectAtIndex:row];
}
return cell;
}
#pragma mark -
#pragma mark Table Delegate Methods
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath;
{
[tableView deselectRowAtIndexPath:indexPath animated:YES];
int row = [indexPath row];
if (tableView == self.SchoolDistrictTableView)
{
NSString *schoolDistrictlist = [self.schoolDistrictList objectAtIndex:row];
[self.SchoolDistrictTableView removeFromSuperview];
//[self.ClassTypeTableView reloadData];//去掉解析就会使教室类型的数组清零
SchoolDistrictText.text = schoolDistrictlist;
DistrictNumText.text = [self GetDistrictNum];
//尝试解析xml
//初始化用来临时存储从xml中读取的字符串
self.workingPropertyString = [NSMutableString string];
//初始化用来存储解析后的xml文件
self.workingArray = [NSMutableArray array];
//从资源文件中获取xml文件
NSString *strPathXml = [[NSBundle mainBundle] pathForResource:schoolDistrictlist ofType:@"xml"];
//将xml文件转换成data类型
self.xmlData = [[NSData alloc] initWithContentsOfFile:strPathXml];
//初始化待解析的xml
self.parserXML = [[NSXMLParser alloc] initWithData:xmlData];
//初始化需要从xml中解析的元素
self.elementsToParse = [NSArray arrayWithObjects:@"string-array",kItem, nil];
//设置xml解析代理为self
[parserXML setDelegate: self];
//开始解析之前清空数组
self.ClassTypeArray = [[NSMutableArray alloc] init];
self.classTypeList = [[NSArray alloc] init];
//开始解析
[parserXML parse];//调用解析的代理方法,那三个代理方法
self.classTypeList = [NSArray arrayWithArray:ClassTypeArray];
}
else if(tableView == self.ClassTypeTableView)
{
NSString *classTypelist = [self.classTypeList objectAtIndex:row];
[self.ClassTypeTableView removeFromSuperview];
//[self.LessonClassroomTableView reloadData];
ClassTypeText.text = classTypelist;
OneClassType = classTypelist;
//NSLog(@"%@",OneClassType);
//将xml文件转换成data类型
//self.xmlData = [[NSData alloc] initWithContentsOfFile:strPathXml];
//初始化待解析的xml
self.parserXML = [[NSXMLParser alloc] initWithData:xmlData];
//初始化需要从xml中解析的元素
self.elementsToParse = [NSArray arrayWithObjects:@"string-array",kItem, nil];
//设置xml解析代理为self
[parserXML setDelegate: self];
//解析前清空数组
self.LessonClassroomArray = [[NSMutableArray alloc] init];
self.lessonClassroomList = [[NSArray alloc] init];
//self.ClassTypeArray = [[NSMutableArray alloc] init];
//self.classTypeList = [[NSArray alloc] init];
//开始解析
[parserXML parse];//调用解析的代理方法
self.lessonClassroomList = [NSArray arrayWithArray:LessonClassroomArray];
}
else if(tableView == self.LessonClassroomTableView)
{
NSString *lessonclassroomlist = [self.lessonClassroomList objectAtIndex:row];
[self.LessonClassroomTableView removeFromSuperview];
[self.LessonSectionTableView reloadData];
LessonClassroomText.text = lessonclassroomlist;
LessonSectionText.text = [self.lessonSectionList objectAtIndex:0];
}
else
{
NSString *lessonSectionlist = [self.lessonSectionList objectAtIndex:row];
[self.LessonSectionTableView removeFromSuperview];
LessonSectionText.text = lessonSectionlist;
}
}
@end