XML文件解析方式
SAX方式解析XML 苹果官方提供的原生的解析XML文件的方式 在iOS上解析XML文件的方式. 速度快,内存占用小. 是只读的,只能读取XML文件数据不能做修改操作.
DOM方式解析XML 是在MAC使用的解析方式. 注意 : 内存消耗极大,不适用于手机. 可以读写XML文件. iPhone无法直接使用DOM方式解析XML. 如果要在iPhone上使用DOM方式解析XML文件,可以使用第三方框架.
解析XML过程
//发送请求 1.获取URL–>创建请求–>发送请求–>响应处理–>XML解析 //xml解析器 2>创建XML解析器–>设置解析器代理–>开启解析器 //代理方法 3>开启–>开始节点–>节点内容–>结束节点–>结束–>监听错误信息 //模型(开始节点–节点内容–结束节点) 4>判断开始节点–创建模型–标签属性赋值给模型–模型添加到数组 //可遍数组 5>保存节点内容的可变字符串 //可变字符串 6>每次取出属性数组的模型–判断对应节点–给模型属性赋值–可变字符串置为@”“
NSXMLParser–parse–DidStartDocument–didStartElement–foundCharacters–didEndElement–DidEndDocument–parseErrorOccurred
实例XML解析
#import "ViewController.h"
#import "VideoModel.h"
@interface ViewController () <NSXMLParserDelegate>
@property (
nonatomic,
strong)
NSMutableArray *videoM;
@property (
nonatomic, copy)
NSMutableString *stringM;
@property (
nonatomic,
strong) VideoModel *currentModel;
@end
@implementation ViewController
- (
void)viewDidLoad {
[
super viewDidLoad];
}
- (
void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
[
self loadXML];
}
- (
void)loadXML {
NSURL *URL= [
NSURL URLWithString:@
"http://localhost/videos.xml"];
NSURLRequest *request = [
NSURLRequest requestWithURL:URL];
[
NSURLConnection sendAsynchronousRequest:request queue:[[NSOperationQueue alloc] init] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data,
NSError * _Nullable connectionError) {
if (connectionError ==
nil && data !=
nil) {
NSXMLParser *XMLParser = [[NSXMLParser alloc] initWithData:data];
XMLParser
.delegate =
self;
[XMLParser parse];
}
else {
NSLog(@
"%@",connectionError);
}
}];
}
#pragma mark - NSXMLParserDelegate
- (
void)parserDidStartDocument:(NSXMLParser *)parser {
NSLog(@
"1.开始解析XML文档");
}
- (
void)parser:(NSXMLParser *)parser didStartElement:(
NSString *)elementName namespaceURI:(nullable
NSString *)namespaceURI qualifiedName:(nullable
NSString *)qName attributes:(
NSDictionary<
NSString *,
NSString *> *)attributeDict {
if ([elementName isEqualToString:@
"video"]) {
VideoModel *model = [[VideoModel alloc] init];
model
.videoId = attributeDict[@
"videoId"];
[
self.videoM addObject:model];
}
}
- (
void)parser:(NSXMLParser *)parser foundCharacters:(
NSString *)string {
[
self.stringM appendString:string];
}
- (
void)parser:(NSXMLParser *)parser didEndElement:(
NSString *)elementName namespaceURI:(nullable
NSString *)namespaceURI qualifiedName:(nullable
NSString *)qName {
VideoModel *model = [
self.videoM lastObject];
if ([elementName isEqualToString:@
"videos"] || [elementName isEqualToString:@
"video"]) {
return;
}
[model setValue:
self.stringM forKey:elementName];
[
self.stringM setString:@
""];
}
- (
void)parserDidEndDocument:(NSXMLParser *)parser {
NSLog(@
"5.结束解析文档");
NSLog(@
"%@",
self.videoM);
}
- (
void)parser:(NSXMLParser *)parser parseErrorOccurred:(
NSError *)parseError {
NSLog(@
"6.监听XML文件是否解析出错 = %@",parseError);
}
- (
NSMutableArray *)videoM {
if (_videoM ==
nil) {
_videoM = [
NSMutableArray array];
}
return _videoM;
}
- (
NSMutableString *)stringM {
if (_stringM ==
nil) {
_stringM = [
NSMutableString string];
}
return _stringM;
}
@end
通过代理方法中的NSLog,可以了解到解析XML文件中数据的过程.以上步骤,2—>3—>4,会不断循环,一直到所有数据解析完成.节点之间的内容并不是一次就能找全的,有时候需要循环多次才能找全.
如果解析数据量非常大的XML文件是很耗时的.当在哪个线程设置了代理协议,就在哪个线程中解析.
不能按照字典转模型的逻辑来处理XML转模型.解析XML数据的过程中没有字典.
每个video标签就是描述一个视频的.每个模型对象也是用来描述一个视频的.所以每找到一个video标签就要创建一个对应的模型对象.模型对象属性赋值会在多个代理方法中进行赋值.所以需要定义成全局的模型对象.
节点之间的内容有时候不会一次性就找全,所以需要多次拼接字符串,而且要在找结束节点代理方法中使用,所以也要定义成全局的可变字符串.
为了能够打印出所有的模型对象,需要将模型对象添加到数组中.
在拼接下一个节点之间的内容之前,给模型属性付完值之后,将供拼接的可变字符串清空.
注意 : 多次拼接完节点之间的内容,且在找结束节点代理方法中,给模型属性赋值完成之后,需要清空这个用于拼接的可变字符串.否则,会c重复拼接字符串,即将上一个节点之间的内容继续拼接到下一个节点之间的内容前面.
转载请注明原文地址: https://ju.6miu.com/read-972224.html