ios-XML文档解析之SAX解析
首先SAX解析xml
*xml文档的格式特点是节点,大体思路是把每个最小的子节点作为对象的属性,每个最小子节点的'父'节点作为对象,将节点转化为对象,输出.

每个节点都是成对存在的,有开始有结束.有始有终
搭建本地服务器,并创建异步请求访问本地服务器中的数据video.xml
#import "ViewController.h"
#import "Video.h"
@interface ViewController () <NSXMLParserDelegate>
//vidios用来保存video对象的数组
@property (nonatomic, strong) NSMutableArray *videos;
//当前创建的video对象
@property (nonatomic, strong) Video *currentVideo;
//存储当前节点的内容
@property (nonatomic, copy) NSMutableString *mString;
@end
- currentVideo每次寻找到节点名字为video的时候创建一个video对象,并添加到数组videos中.
- mString是开始与结束节点之间的内容用mString来存储.在找到结束节点之后把mString通过setvalue...forkey...的方式(kvc)赋值给video对应的属性.
- 通过SAX(NSXMLParser)方式解析xml文件要遵守协议NSXMLParserDelegate,设置代理.=self
@implementation ViewController
//懒加载--->初始化videos
- (NSMutableArray *)videos {
if (_videos == nil) {
_videos = [NSMutableArray arrayWithCapacity:10];
}
return _videos;
}
//初始化mString
- (NSMutableString *)mString {
if (_mString == nil) {
_mString = [NSMutableString string];
}
return _mString;
}
- (void)viewDidLoad {
[super viewDidLoad];
[self loadXML];
}
//异步请求xml
- (void)loadXML {
//异步请求服务器的xml文件
NSURL *url = [NSURL URLWithString:@"http://127.0.0.1/videos.xml"];
NSURLRequest *request = [NSURLRequest requestWithURL:url];
[NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) {
if (connectionError) {
NSLog(@"连接错误 %@",connectionError);
return;
}
NSHTTPURLResponse *httpResponse = (NSHTTPURLResponse *)response;
if (httpResponse.statusCode == 200 || httpResponse.statusCode == 304) {
//解析数据
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
//设置代理
parser.delegate = self;
//开始执行代理的方法,代理的方法中开始解析的
[parser parse];
}else{
NSLog(@"服务器内部错误");
}
}];
}
- 创建video分类
#import <Foundation/Foundation.h>
@interface Video : NSObject
@property (nonatomic, copy) NSNumber *videoId;
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSNumber *length;
@property (nonatomic, copy) NSString *videoURL;
@property (nonatomic, copy) NSString *imageURL;
@property (nonatomic, copy) NSString *desc;
@property (nonatomic, copy) NSString *teacher;
@property (nonatomic, readonly) NSString *time;
- (instancetype)initWithDict:(NSDictionary *)dict;
+ (instancetype)videoWithDict:(NSDictionary *)dict;
@end
- .m文件
#import "Video.h"
@implementation Video
- (instancetype)initWithDict:(NSDictionary *)dict {
self = [super init];
if (self) {
[self setValuesForKeysWithDictionary:dict];
}
return self;
}
+ (instancetype)videoWithDict:(NSDictionary *)dict {
return [[self alloc] initWithDict:dict];
}
- (NSString *)time {
int len = self.length.intValue;
return [NSString stringWithFormat:@"%02d:%02d:%02d", len / 3600, (len % 3600) / 60, (len % 60)];
}
- (NSString *)description {
return [NSString stringWithFormat:@"<%@ : %p> { videoId : %@, name : %@, length : %@, videoURL : %@, imageURL : %@, desc : %@, teacher : %@}", [self class], self, self.videoId, self.name, self.length, self.videoURL, self.imageURL, self.desc, self.teacher];
}
@end
重写- (NSString *)description 为了在解析结束后打印出来看结果是否正确
开始写代理方法
//1 开始解析文档
- (void)parserDidStartDocument:(NSXMLParser *)parser {
NSLog(@"1 开始解析文档 %@",[NSThread currentThread]);
}
//2 找开始节点
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict {
//elementName 节点的名称
//attributeDict 标签的属性
NSLog(@"2 找开始节点 %@--%@",elementName,attributeDict);
//如果是video标签,创建video对象
if ([elementName isEqualToString:@"video"]) {
self.currentVideo = [[Video alloc] init];
self.currentVideo.videoId = @([attributeDict[@"videoId"] intValue]);
//添加到数组中
[self.videos addObject:self.currentVideo];
}
}
- 开始查找节点,如果节点名称==video则创建对象self.currentVideo = [[Video alloc] init];并且加入可变数组videos中.
//3 找节点之间的内容
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
//
NSLog(@"3 找节点之间的内容 %@",string);
//拼接字符串
[self.mString appendString:string];
}
- 将开始于结束节点之间的内容用可变字符串mString保存起来.当找到结束节点名字后,利用结束节点名通过setvalue...forkey...方式把mString的内容赋值给对应的video(或者说self.currentVideo)的属性.
//4 找结束节点
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
//elementName 节点名称
NSLog(@"4 找结束节点 %@",elementName);
//判断标签是否是对应的属性
if (![elementName isEqualToString:@"video"] && ![elementName isEqualToString:@"videos"]) {
//kvc 赋值的过程就是地址指向的过程,不会做类型转换
[self.currentVideo setValue:self.mString forKey:elementName];
}
//清空可变字符串
[self.mString setString:@""];
}
- 每次用完mString都要清空,不然前面的节点内容都会拼接到正在解析的节点的内容上.
//5 结束解析文档
- (void)parserDidEndDocument:(NSXMLParser *)parser {
NSLog(@"5 结束解析文档");
NSLog(@"%@",self.videos);
}
//6 解析出错
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSLog(@"出错");
}
- 文档解析完成.思路--->找最小子节点--->把最小子节点的父节点作为一个对象,最小子节点作为属性.通过读取到节点的名称,用kvc方式对对象的属性进行赋值.
文档输出由于汉字编码是Unicode方式需要对其转换.
下面演示不管是数组还是字典只要整体输出都会有编码问题


解决方法:重写数组与字典的- (NSString *)descriptionWithLocale:(id)locale,写完不用导入头文件.
创建NSObject 分类Log

用block循环逐个输出解决汉字问题

小结:XML和json解析的区别
XML:
* 优点:1>所有的语言中格式统一,数据共享比较方便
* 缺点: 1>XML格式文件庞大,格式复杂,解析起来比较麻烦!压缩比例小。
JOSN:
* 优点:
* 1>数据结构简单,易于读写,易于解析,压缩比例大。
* 2>支持多种语言,java,ios,javascript,php等语言。
* 3>前端和后台维护简单方便。
* 缺点:1>JSON出现的时间比XML晚。移动端开发推荐使用json!!!
ios-XML文档解析之SAX解析的更多相关文章
- JavaEE实战——XML文档DOM、SAX、STAX解析方式详解
原 JavaEE实战--XML文档DOM.SAX.STAX解析方式详解 2016年06月22日 23:10:35 李春春_ 阅读数:3445 标签: DOMSAXSTAXJAXPXML Pull 更多 ...
- Java解析XML文档(简单实例)——dom解析xml
一.前言 用Java解析XML文档,最常用的有两种方法:使用基于事件的XML简单API(Simple API for XML)称为SAX和基于树和节点的文档对象模型(Document Object ...
- [Swift通天遁地]七、数据与安全-(1)XML文档的创建和解析
★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★➤微信公众号:山青咏芝(shanqingyongzhi)➤博客园地址:山青咏芝(https://www.cnblogs. ...
- XML文档的生成和解析操作方法
XML文档和JSon文档同为网络传输中的数据格式,JSon的解析和创建已经在新浪微博的使用中相当熟悉,故仅仅记载XML文档的相关方法. 关于XML文档: 1.一种便于编辑和传输的数据文件格式 2.xm ...
- 程序员带你学习安卓开发-XML文档的创建与解析
这是程序员带你学习安卓开发系列教程.本文章致力于面向对象程序员可以快速学习开发安卓技术. 上篇文章:程序员带你学习安卓开发系列-Android文件存储 因知识连贯性推荐关注头条号:做全栈攻城狮.从头开 ...
- Android XML文档解析(一)——SAX解析
---------------------------------------------------------------------------------------------------- ...
- Java高级特性 第14节 解析XML文档(2) - SAX 技术
一.SAX解析XML文档 SAX的全称是Simple APIs for XML,也即XML简单应用程序接口.与DOM不同,SAX提供的访问模式是一种顺序模式,这是一种快速读写XML数据的方式.当使用S ...
- 四种生成和解析XML文档的方法详解(介绍+优缺点比较+示例)
众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J 下面首先给出这四种方法的jar包下载地址 DOM:在现在的Java JDK里都自带了,在xml- ...
- 四种生成和解析XML文档的方法详解
众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J 下面首先给出这四种方法的jar包下载地址 DOM:在现在的Java JDK里都自带了,在xml- ...
- 大杂烩 -- 四种生成和解析XML文档的方法详解
基础大杂烩 -- 目录 众所周知,现在解析XML的方法越来越多,但主流的方法也就四种,即:DOM.SAX.JDOM和DOM4J DOM:在现在的Java JDK里都自带了,在xml-apis.jar包 ...
随机推荐
- Apache Spark技术实战之2 -- PackratParsers实例
欢迎转载,转载请注明出处,徽沪一郎 概要 通过一个简明的Demo程序来说明如何使用scala中的PackratParsers DemoApp import scala.util.parsing.com ...
- Apache Storm 衍生项目之2 -- Trident-ML
欢迎转载,转载请注明出处,徽沪一郎,谢谢. 楔子 或许谈起storm是大数据实时计算框架已经让你不明觉厉,如果说storm还可以跟机器学习算法(ml)有机的结合在一起,是不是更加觉着高大尚呢.trid ...
- PHP 使用 GET 传递数组变量
PHP 代码: <?php print_r($_GET['tag_name']); URL: http://127.0.0.16/get.php?tag_name[]=送货快&tag_n ...
- linux python版本升级
升级python版本的时候千万不能卸载python 2.6,再安装python2.7,这样会有无穷无尽的麻烦,保守的方式 是直接安装python2.7的源码包,也就是python两个版本共存.(因为C ...
- UE4.7的IOS发布和调试的相关问题
UE4.7以后正式源码免费了,正好最近工作也在做这部分,ue4的官方文档虽然有一部分ios平台的资料,那也只是通过编辑器来发布或预览一类,但手游程序员都知道,一些cpu和gpu性能上的调试是在所难免的 ...
- 页面静态化2 --- 使用PHP缓存机制来完成页面静态化(上)(ob_flush和flush函数区别用法)
我们可以使用PHP自带的缓存机制来完成页面静态化,但在这里,需要说明一点,仅靠PHP缓存机制并不能完美的解决页面静态化,往往需要和其他页面静态技术(通常是伪静态技术)结合使用 例子: 当访问一个页面时 ...
- Decomposing and Redistributing the Statement Method
Refactoring: Improving the Design of Existing Code Decomposing and Redistributing the Statement Meth ...
- 我的第一个chrome扩展(1)——读样例,实现时钟
学习chrome扩展开发: 与网页类似,需要的知识:html,javascript chrome扩展程序的构成: manifest.json:对扩展程序的整体描述文件 { "manifest ...
- Strom简介,以及安装,和官方案例测试
一:简介 1.strom的两种形式 2.strom的特性 3.使用场景 4.集群架构 5.集群架构进程 6.组件 Nimbus 7.从节点Supervisor 8.组件worker 9.组件Execu ...
- ZooKeeper Recipes and Solutions 翻译
ZooKeeper 秘诀 与解决方案 A Guide to Creating Higher-level Constructs with ZooKeeper Out of the Box Applica ...