● 全称是Extensible Markup Language,译作“可扩展标记语言”
● 跟JSON一样,也是常用的一种用于交互的数据格式
● 一般也叫XML文档(XML Document)
五、XML ====================总结============================
1.语法
1> 文档声明
<?xml version="1.0" encoding="UTF-8" ?>
2> 元素
3> 属性
<videos>
<video name="小黄人 第01部" length="10"/>
<video name="小黄人 第01部" length="10"/>
</videos>
* videos和video是元素(节点)
* name和length叫做元素的属性
* video元素是videos元素的子元素
2.解析
1> SAX解析:逐个元素往下解析,适合大文件
* NSXMLParser
2> DOM解析:一口气将整个XML文档加载进内存,适合小文件,使用最简单
* GDataXML
==================================================
● DOM:一次性将整个XML文档加载进内存,比较适合解析小文件(常用方式)
- (NSArray *)parseJSONData:(NSData *)data { // 解析数据 NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableLeaves error:nil]; NSArray *array = dict[@"videos"]; NSMutableArray *videos = [NSMutableArray array]; for (NSDictionary *videoDict in array) { HMVideo *video = [HMVideo videoWithDict:videoDict]; [videos addObject:video]; } return videos; }
● SAX:从根元素开始,按顺序一个元素一个元素往下解析,比较适合解析大文 件
● 苹果原生
• NSXMLParser:SAX方式解析,使用简单
● 第三方框架
• libxml2:纯C语言,默认包含在iOS SDK中,同时支持DOM和SAX方式解析
• GDataXML:DOM方式解析,由Google开发,基于libxml2
● XML解析方式的选择建议
● 大文件:NSXMLParser、libxml2
● 小文件:GDataXML
NSXMLParser
// 传入XML数据,创建解析器
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; // 设置代理,监听解析过程
parser.delegate = self;
// 开始解析
[parser parse];
● NSXMLParser采取的是SAX方式解析,特点是事件驱动,下面情况都会通知代理
● 当扫描到文档(Document)的开始与结束
● 当扫描到元素(Element)的开始与结束
- (NSArray *)SAXparseXMLWithData:(NSData *)data { // 1.创建解析器 NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; // 2.设置代理 parser.delegate = self; // 3.开始解析 [parser parse]; // 卡住(解析完毕才会返回) return self.videos; }
NSXMLParserDelegate
- (void)parserDidStartDocument:(NSXMLParser *)parser
● 当扫描到文档的结束时调用(解析完毕)
- (void)parserDidEndDocument:(NSXMLParser *)parser
● 当扫描到元素的开始时调用(attributeDict存放着元素的属性)
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString
*)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:
(NSString *)qName attributes:(NSDictionary *)attributeDict
● 当扫描到元素的结束时调用
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString
*)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:
(NSString *)qName
#pragma mark - NSXMLParserDelegate /** * 开始解析文档时调用 */ - (void)parserDidStartDocument:(NSXMLParser *)parser { // NSLog(@"parserDidStartDocument----"); } /** * 结束解析文档时调用(解析完毕) */ - (void)parserDidEndDocument:(NSXMLParser *)parser { // NSLog(@"parserDidEndDocument----"); } /** * 解析到一个元素的开头时调用 <videos> */ - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { // NSLog(@"didStartElement----%@", elementName); if ([@"videos" isEqualToString:elementName]) { // 解析到一个videos标签 self.videos = [NSMutableArray array]; } else if ([@"video" isEqualToString:elementName]) { // 解析到一个video标签, 创建一个模型 HMVideo *video = [HMVideo videoWithDict:attributeDict]; [self.videos addObject:video]; } } /** * 解析到一个元素的结尾时调用 </videos> */ - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { // NSLog(@"didEndElement----%@", elementName); }
GDataXML配置
● 设置链接参数(自动链接libxml2库) • 在Other Linker Flags中加入-lxml2
GDataXML使用(常用方式)
● GDataXMLDocument:代表整个XML文档
● GDataXMLElement • 代表文档中的每个元素
• 使用attributeForName:方法可以获得属性值
- (NSArray *)DOMparseXMLWithData:(NSData *)data { // 1.加载文档 GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil]; // 2.获得根元素 GDataXMLElement *root = doc.rootElement; // 3.获得所有video元素 NSArray *elements = [root elementsForName:@"video"]; // 4.将GDataXMLElement对象转成HMVideo模型 NSMutableArray *videos = [NSMutableArray array]; for (GDataXMLElement *ele in elements) { HMVideo *video = [[HMVideo alloc] init]; video.ID = [ele attributeForName:@"id"].stringValue.intValue; video.length = [ele attributeForName:@"length"].stringValue.intValue; video.name = [ele attributeForName:@"name"].stringValue; video.image = [ele attributeForName:@"image"].stringValue; video.url = [ele attributeForName:@"url"].stringValue; [videos addObject:video]; } return videos; }
调用XML 类
@implementation HMVideoTool - (NSArray *)parseXMLData:(NSData *)data { return [self DOMparseXMLWithData:data]; }
- (void)viewDidLoad { [super viewDidLoad]; // 去除分割线 self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone; [MBProgressHUD showMessage:@"正在加载视频信息...."]; // 访问服务器数据 NSString *urlStr = @"http://192.168.1.200:8080/MJServer/video?type=XML"; // 发送请求 NSURL *url = [NSURL URLWithString:urlStr]; NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL:url]; // GET request.timeoutInterval = 10; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { // 隐藏 [MBProgressHUD hideHUD]; if (data) { // 解析数据 data : XML数据 HMVideoTool *tool = [[HMVideoTool alloc] init]; self.videos = [tool parseXMLData:data]; // 刷新表格 [self.tableView reloadData]; } else { [MBProgressHUD showError:@"网络繁忙!!!"]; } }]; }