XML全称是Extensible Markup Language,译作“可扩展标记语言”
跟JSON一样,也是常用的一种用于交互的数据格式,一般也叫XML文档(XML Document)
例如:
<videos>
<videos name=“name1” length=“30” />
<videos name=“name2” length=“30” />
<videos name=“name3” length=“30” />
</videos>
一个常见的XML文档一般由文档声明,元素(Element)和属性(Attribute)组成
在XML文档的最前面,必须编写一个文档声明,用来声明XML文档的类型
最简单的声明:<?xml version=“1.0” ?>
用encoding属性说明文档的字符编码:<?xml version=“1.0” encoding=“UTF-8” ?>
一个元素包含了开始标签和结束标签
拥有内容的元素:<video>name</video>
没有内容的元素:<video></video>
没有内容的元素简写:<video/>
一个元素可以嵌套若干个子元素(不能出现交叉嵌套)
例如:
<videos>
<video>
<name>name1</name>
<length>30</length>
</video>
</videos>
规范的XML文档最多只有1个根元素,其他元素都是根元素的子孙元素
注意:XML中的所有空格和换行,都会被当作具体内容处理
一个元素可以拥有多个属性,属性值必须用“”或‘’括住
例如:<video name=“name1” length=“30” />
实际上,属性的表示的信息也可以用子元素来表示
例如:
<video>
<name>name1</name>
<length>30</length>
</video>
XML的解析方式有两种:DOM(一次性将整个XML文档加载进内存,比较适合解析小文件)
SAX(从根元素开始,按照顺序一个元素一个元素往下解析,比较适合解析大文件)
iOS中解析XML的方法有两种
苹果自带:NSXMLParser(SAX方式解析,使用简单)
第三方框架:libxml2(纯C语言,默认包含在iOS SDK中,同时支持DOM和SAX方式解析)
GDataXML(DOM方式解析,由Google开发,基于libxml2)
//Parser解析XML - (void)viewDidLoad { [super viewDidLoad]; //1 URL NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"]; //2 创建请求对象 NSURLRequest *request = [NSURLRequest requestWithURL:url]; //3 发送异步请求 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { //4 容错处理 if(connectionError) { NSLog(@"Error"); return; } //5 解析数据 //创建XML解析器 NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; //设置代理 //需遵守协议<NSXMLParserDelegate> parser.delegate = self; //开始解析 [parser parse]; //6 更新UI [self.tableView reloadData]; }]; } //开始解析XML文档时调用 - (void)parserDidStartDocument:(NSXMLParser *)parser { NSLog(@"%s", __func__); } //开始解析某个元素 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict { NSLog(@"开始解析%@----%@", elementName, attributeDict); //过滤根元素 if([elementName isEqualToString:@"videos"]) { return; } //字典转模型 [self.videos addObject:[XYVideo mj_objectWithKeyValues:attributeDict]]; } //某个元素解析完毕 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { NSLog(@"结束解析%@", elementName); } //结束解析时调用 - (void)parserDidEndDocument:(NSXMLParser *)parser { NSLog(@"%s", __func__); }
//GDataXML解析XML - (void)viewDidLoad { [super viewDidLoad]; //1 URL NSURL *url = [NSURL URLWithString:@"http://120.25.226.186:32812/video?type=XML"]; //2 创建请求对象 NSURLRequest *request = [NSURLRequest requestWithURL:url]; //3 发送异步请求 [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { //4 容错处理 if(connectionError) { NSLog(@"Error"); return; } //5 解析数据 //加载XML文档 GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:kNilOptions error:nil]; //获取根元素,得到根元素内部的所有名称为video子孙元素 NSArray *eles = [doc.rootElement elementsForName:@"video"]; //遍历 for (GDataXMLElement *ele in eles) { //把元素内部所有的属性转为模型并添加到self.video XYVideo *video = [[XYVideo alloc] init]; video.name = [ele attributeForName:@"name"].stringValue; video.length = [ele attributeForName:@"length"].stringValue; video.image = [ele attributeForName:@"image"].stringValue; video.ID = [ele attributeForName:@"id"].stringValue; video.url = [ele attributeForName:@"url"].stringValue; [self.videos addObject:video]; } //6 更新UI [self.tableView reloadData]; }]; }