object c解析(包含本地和远程)xml文件

来源:互联网 发布:数字低通滤波算法 编辑:程序博客网 时间:2024/06/06 18:13

0、理论基础:

NSXML是iOS SDK自带的,也是苹果默认解析框架,采用SAX模式解析。NSXML框架中的核心是NSXMLParser和它的委托协议NSXMLParserDelegate。主要的解析工作是在委托协议NSXMLParserDelegate的实现类中完成的,委托中定义了很多回掉方法,在SAX解析器从上到下遍历XML文档的过程中,遇到开始标签、结束标签、文档开始、文档结束和字符串就会触发这些方法。这些方法有很多,比如下面的:

 

1、parserDidStartDocument,在文档开始的时候触发;

2、parser:didStartElement:namespaceURI:qualifiedName:attributes,遇到一个开始标签时触发,其中namespaceURI部分是命名空间,qualifiedName是限定名,attributes是字典类型的属性集合;

3、parser:foundCharacters,遇到字符串时触发;

4、parser:didEndElement:namespaceURI:qualifiedName,遇到结束标签时触发;

5、parserDidEndDocument,遇到文档结束时触发。


1、一个例子,从xml读取数据并显示到tableview上:

先来看我们的测试xml文件内容(这个是远程的,本地的需要再创建项目的时候,再拷贝一份):



首先我们创建一个测试工程ParserXML,把自带的storyboard、ViewController删掉,创建MainViewController(集成自UITableViewController),创建对应的group,这是处理处理过后的工程内容:



下面对其进行修改,在AppDelegate.m的(主要是初始化Main视图)

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions{    // Override point for customization after application launch.    self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];    self.window.backgroundColor = [UIColor grayColor];        [self.window makeKeyAndVisible];            MainViewController *mainController = [[MainViewController alloc] init];    self.window.rootViewController = mainController;        return YES;}

并且在工程中删掉下边的这个(其实无所谓,删不删除都不会导致错误):



因为需要在tableView中显示数据,因此我们给tableView中加入一个动态数组:



在对应的viewDid中对其进行初始化(包括对dataArray和对表格的):


并且设置一个tableview的行数




好,下面补上从xml中读取数据的内容

 

新建一个XmlDataParser的一个类,他继承自NSobject,并且实现协议NSXMLParserDelegate



commond+NSXMLParserDelegate找到NSXMLParserDelegate.h的内容,取出最上边理论时候讲到的四个方法:



实现这四个方法的,达到解析xml的目的

 

因为,上一个类tableView中需要的数据源是NSMutableArray的,所以这里我们也新建一个NSMutableArray的dataArray对象,保存读取到的数据,当然我们需要一个NSMutableDictionary保存我们读取每一个xml子项的内容,还需要一个从xml读取出字符串的NSMutableString:


 

按照一开始理论的,我们在parserDidStartDocument中对成员变量进行初始化:



因为,我们不打算把数据清空,所以在parserDidEndDocument中,我们什么都不做,如果你打算清空数据,那么在这里完成是最好的时机(这里对两个临时变量清空,其实也没太大必要)


我们先来填foundCharacters,他是发现字符串的时候触发,所以这里:


 

按照逻辑,在一开始碰到xml的开始标签的时候,比如遇到Note,这是每一子项的开始标签,我们需要清空一下NSMutableDictionary以便我们存放一个子项;在比如遇到CDate的时候,只需要清空一个临时字符串就行了(因为他只是子项的一个数据项,所以这是我们的didStartElement):


可以看到这里有一个参数是attributeDict的,他的含义是,当你的每一个xml标签有属性值的时候,比如这里的<Note id = "1">,那么你可以继续进行匹配,进而取出后面的id的值

didEndElement是把对应的内容,填进Array中,这里也和上面是一样,同样要区别开每一个子项和数据项的操作



因为,我们是对xml的操作进行封装的,所以对外需要有一个接口;上面一开始我们提到,xml文件可能是本地的数据,也可能是web的数据,所以我们还得需要一个bool的标记:



下面我们来实现它,这个很简单,判断一个是本地读取文件,还是从web中获得数据:


看看这里的代码,因为从文件中读取,我们只需要在xml文件名前面跟上路径信息就行(用NSBundle mainBundle就很容易办到)

 

网络路径的文件,那么我们就需要先从NSData中取到数据,再去解析了

 

 

最后部分我们要对tableView的每一项进行设置,这个就不说了,查看代码:

这里提一下,也是我第一次创建cell的时候抛出未初始化错误的问题

if (cell == nil)    {        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];// 填充对应的数据,从NSMutableArray中取出}

因为自带的两行代码中,cell是没有alloc的,所以我们必须要在判断cell等于nil的时候,用alloc对其初始化;而且原有的一行代码是通过forIndexPath来加载的,所以我们去掉后面的forIndexPath只要前面的:



最后,我们来补上一开始获取xml内容的部分(分别对网络和本地的xml文件做测试):




2、演示效果:


3、最后说明:

本文第0章节和xml文件内容引用自:《iOS网络编程与云端应用最佳实践》,其余部分与代码属于原创内容

本文工程下载地址:http://download.csdn.net/detail/zengraoli/6510441
原创粉丝点击