网络之XML解析-原生
2024-09-12 07:42:52
Json和XML都属于字符串,用于跨平台,前面总结了下Json,下面看下XML。
XML定义这些百度比我说的清,不再啰嗦,直接代码,我喜欢把东西都放进注释。
一、首先看下要解析的XML内容
<?xml version="1.0" encoding="utf-8"?> <Users> <User id="1"> <name>Tom</name> <age>20</age> </User> <User id="2"> <name id = "222">John</name> <age>33</age> </User> <User> <name id = "333">Eric</name> <age>43</age> </User> <User> <name id = "444">Tony</name> <age>54</age> </User> </Users>
二、在项目中添加Person类为其添加属性
// // Person.h // XmlDemo // // Created by City--Online on 15/4/29. // Copyright (c) 2015年 CYW. All rights reserved. // #import <Foundation/Foundation.h> @interface Person : NSObject @property(nonatomic,strong)NSString *Pid; @property(nonatomic,strong)NSString *Name; @property(nonatomic,assign)int Age; @end
三、用IOS原生框架来解析XML,注意实现代理
// // ViewController.m // XmlDemo // // Created by City--Online on 15/4/29. // Copyright (c) 2015年 CYW. All rights reserved. // #import "ViewController.h" #import "Person.h" @interface ViewController () <NSXMLParserDelegate> @property (nonatomic, strong) NSMutableArray *personArray; @property (nonatomic, strong) NSMutableString *element; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // XML的解析方式有2种 // DOM:一次性将整个XML文档加载进内存,比较适合解析小文件 文档驱动 // SAX:从根元素开始,按顺序一个元素一个元素往下解析,比较适合解析大文件 事件驱动 //IOS自带的属于SAX事件驱动的解析方式 // 就是一个事物模型解析,从头开始读取文档然后根据读取到的头标签,读完头标签后,理论上是读取标签值,然后读取后遇到结束标签等 NSString *path=[[NSBundle mainBundle]pathForResource:@"user" ofType:@"xml"]; NSURL *url=[[NSURL alloc]initFileURLWithPath:path]; //实例化 NSXMLParser *parser=[[NSXMLParser alloc]initWithContentsOfURL:url]; //设置代理 parser.delegate=self; //开始解析 [parser parse]; } // step1 开始解析 -(void)parserDidStartDocument:(NSXMLParser *)parser { self.personArray = [[NSMutableArray alloc] initWithCapacity:0]; self.element = [[NSMutableString alloc] init]; } //step2 开始解析元素 获取头标签的信息<>里面的属性、名字 -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { if ([elementName isEqualToString:@"Users"]) { NSLog(@"进入<Users>"); } if ([elementName isEqualToString:@"User"]) { NSLog(@"进入<User>"); Person *user = [[Person alloc] init]; [_personArray addObject:user]; } if ([elementName isEqualToString:@"name"]) { NSLog(@"进入<name>"); Person *user = [_personArray objectAtIndex:[_personArray count] -1]; user.Pid = [attributeDict objectForKey:@"id"]; } if ([elementName isEqualToString:@"age"]) { NSLog(@"进入<age>"); } } //step3 获得首尾标签间 > < 的内容 //此处分几种情况: //1.当标签间内容为“”,如果</></>(如图</age></User></Users>)则进入step4,否则进入step2 //2.当标签间内容不为“”,则进入step4 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { NSLog(@"%@", string); //获取文本节点中的数据,因为下面的方法要保存这里获取的数据,所以要定义一个全局变量(可修改的字符串) //这里要赋值为空,目的是为了清空上一次的赋值 [_element setString:@""]; [_element appendString:string];//string是获取到的文本节点的值,只要是文本节点都会获取(包括换行),然后到下个方法中进行判断区分 } //step4 标签解析结束</> - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { // NSLog(@"%@", elementName); NSString *str=[[NSString alloc] initWithString:_element]; if ([elementName isEqualToString:@"Users"]) { NSLog(@"</Users>= %@",str); } if ([elementName isEqualToString:@"name"]) { NSLog(@"</name>=%@",str); Person *user = [_personArray objectAtIndex:[_personArray count] -1]; user.Name = str; } if ([elementName isEqualToString:@"age"]) { NSLog(@"</age>=%@",str); Person *user = [_personArray objectAtIndex:[_personArray count] -1]; user.age = (int)[str integerValue]; } if ([elementName isEqualToString:@"User"]) { NSLog(@"</User>=%@ ",str); } } //step5 解析结束 -(void)parserDidEndDocument:(NSXMLParser *)parser { for (Person *p in self.personArray) { NSLog(@"%@ %d %@",p.Name,p.Age,p.Pid); } } //解析报错 -(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { NSLog(@"解析有误 Error:%@",parseError); } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end
四、运行结果(显示的内容过长,减少了两个User)
在这里要感谢陈高oliver和袁伟(伟哥)
最新文章
- Hibernate映射一对多双向关联关系及部门关联属性
- Myeclipse+maven时Tomcat部署时maven的依赖文件不能部署到Tomcat上
- HotSwap和JRebel原理
- Html学习_简易个人网页制作
- PHP 中xampp不能启动服务器的问题
- Java+7入门经典 - 6 扩展类与继承 Part 2/2
- 世界gis相关的资源网站分类整理
- Ubuntu下安装Intel Fortran编译器(ifort)
- 12-7jquery选择器学习
- 使用jenkins进行前端项目自动部署
- springboot之单元测试
- 洛谷T31039 九尾狐吃棉花糖
- Java charAt() 方法
- 【Java】-NO.16.EBook.4.Java.1.003-【疯狂Java讲义第3版 李刚】- oop
- html 基本布局介绍
- [转]C#使用 Salt + Hash 来为密码加密
- MySQL数据库之存储过程与存储函数
- python 多线程示例
- 转:PHP关于反斜杠处理函数addslashes()和stripslashes()的用法
- 李洪强iOS开发之iOS工具收集
热门文章
- UNIGUI换版本注意事项
- Scott-Knott test 配置与使用
- .net图表之ECharts随笔02-字符云
- 记录一次BUG修复-Entity Framwork SaveChanges()失效
- 背水一战 Windows 10 (44) - 控件(日期类): CalendarView, DatePicker, TimePicker
- 【js】关于正则表达式
- Python 库,资源
- 前端基础-html 字体标签,排版标签,超链接,图片标签
- linux 服务器脚本采集数据中文无法执行错误
- Vue.js 60 分钟快速入门