年年有"余"

 找回密码
 立即注册

QQ登录

只需一步,快速开始

查看: 2681|回复: 1

iOS开发中XML网络解析的基本步骤与实现方法

[复制链接]
  • TA的每日心情
    奋斗
    2022-12-13 21:26
  • 签到天数: 371 天

    [LV.9]以坛为家II

    发表于 2014-11-7 02:22:32 | 显示全部楼层 |阅读模式
    一、基本思路
    1、请求网络数据到本地
    2、创建NSXMLParser对请求到的数据进行解析
    3、设置代理方法并实现
    4、主要涉及到6个NSXMLParserDelegate代理方法,分别是
    1. // 解析开始
    2. -(void)parserDidStartDocument:(NSXMLParser *)parser
    3. // 解析出错
    4. -(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
    5. // 解析结束
    6. - (void)parserDidEndDocument:(NSXMLParser *)parser
    7. // 1、开始解析某个节点
    8. -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
    9. // 2、解析某个节点数值
    10. -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
    11. // 3、结束某个节点解析
    12. -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
    复制代码
    5、XML解析的原理是遍历xml文件,并对"<>"敏感,当读取到"<>"时即断定为某个节点的开始,读取到"</>"时即断定为某个节点的结束,但xml中的节点是嵌套的,因此哪个节点的开始为组数据的开始(即我们的对象单元),哪个节点为对象内容的读取,需要我们在代理方法进行判断并拼接赋值给对象相对应的成员变量

    二、代码示例及相关注释说明
    1、对象定义
    SAUrl.h
    1. #import <Foundation/Foundation.h>
    2. @interface SAUrl : NSObject
    3. @property (nonatomic, strong) NSString  *loc;
    4. @property (nonatomic, strong) NSString  *lastmod;
    5. @property (nonatomic, strong) NSString  *changefreq;
    6. @property (nonatomic, strong) NSString  *priority;
    7. @end
    复制代码
    SAUrl.m
    1. #import "SAUrl.h"
    2. @implementation SAUrl
    3. @end
    复制代码
    2、xml解析关键代码
    1. #pragma mrak 请求网络数据
    2. - (void)requestData
    3. {
    4.     // 创建url
    5.     NSString *string = @"http://www.yusian.com/sitemap.xml";
    6.     NSURL *url = [NSURL URLWithString:string];
    7.    
    8.     // 从url中加载数据到内存对象
    9.     NSData *data = [NSData dataWithContentsOfURL:url];
    10.    
    11.     // 对加载到的数据进行XML解析
    12.     NSXMLParser *perser = [[NSXMLParser alloc] initWithData:data];
    13.     perser.delegate = self;
    14.     [perser parse];
    15. }
    16. #pragma mark 解析开始
    17. -(void)parserDidStartDocument:(NSXMLParser *)parser
    18. {
    19.     // 开始解析,初始化相关变量
    20.     _tempStr = [NSMutableString string];
    21.     _dataList = [NSMutableArray array];
    22.     NSLog(@"解析开始");
    23. }
    24. #pragma mark 解析出错
    25. -(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError
    26. {
    27.     NSLog(@"解析出错:%@", parseError.localizedDescription);
    28. }
    29. #pragma mark 解析结束
    30. - (void)parserDidEndDocument:(NSXMLParser *)parser
    31. {
    32.     // 解析结束,打印数组中各对象的值进行检测
    33.     for (SAUrl *url in _dataList) {
    34.         NSLog(@"%@", url.loc);
    35.     }
    36.     NSLog(@"解析结束");
    37. }
    38. #pragma mark 1、开始解析某个节点
    39. -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
    40. {
    41.     // 找到对象的节点名称,如果解析结点为url,则为一组对象的开始,开始解析时创建对象
    42.     if ([elementName isEqualToString:@"url"]) _url = [[SAUrl alloc] init];
    43. }
    44. #pragma mark 2、解析某个节点数值
    45. -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
    46. {
    47.     // 节点内容中的值有可能分多次返回,因此需要拼接字符串
    48.     [_tempStr appendString:string];
    49. }
    50. #pragma mark 3、结束某个节点解析
    51. -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
    52. {
    53.     // 某节点内容中的值取完后,简单处理(比如去掉拼接过种中带来的回车符)
    54.     NSString *result = [_tempStr stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]];
    55.    
    56.     // 如果解析节点为loc,则在结束时将解析出来的内容赋值给对象的相对应成员变量,其他同理
    57.     if ([elementName isEqualToString:@"loc"]) _url.loc = result;
    58.     if ([elementName isEqualToString:@"lastmod"]) _url.lastmod = result;
    59.     if ([elementName isEqualToString:@"changefreq"]) _url.changefreq = result;
    60.     if ([elementName isEqualToString:@"priority"]) _url.priority = result;
    61.    
    62.     // 如果解析节点为url,则该组节点解析完毕,将该对象存入数组中
    63.     if ([elementName isEqualToString:@"url"]) [_dataList addObject:_url];
    64.    
    65.     // 每次节点结束均需要清空中间变量的值,准备下一个节点值的接收
    66.     _tempStr.string = @"";
    67. }
    复制代码
    三、Demo下载:
    游客,如果您要查看本帖隐藏内容请回复

  • TA的每日心情
    犯困
    2015-1-11 14:36
  • 签到天数: 5 天

    [LV.2]偶尔看看I

    发表于 2015-6-26 12:12:43 | 显示全部楼层
    看一看,是什么
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    手机版|小黑屋|Archiver|iOS开发笔记 ( 湘ICP备14010846号 )

    GMT+8, 2024-4-24 19:06 , Processed in 0.056940 second(s), 25 queries .

    Powered by Discuz! X3.4

    Copyright © 2001-2021, Tencent Cloud.

    快速回复 返回顶部 返回列表