您的位置:首页 > 移动开发 > IOS开发

iOS基础--数据解析(XML)

2015-07-30 23:04 274 查看
在开发的时候一般都是使用JSON数据,解析方便,体积小,但是XML的基本使用还是必须要掌握的,希望能够通过阅读这篇文章帮助读者初步了解iOS开发中XML文档的解析方法,在了解XML的解析之前,有必要先说说什么是XML?

XML

一种用于标记电子文件使其具有结构性的标记语言。(百度百科)

跟JSON一样,XML也是经常使用的一种用于交互的数据格式,简单的来说,一个XML文档需要由以下几部分组成:

- 文档声明

- 元素(Element)

- 属性(Attribute)

文档声明:

<?xml version="1.0" encoding="UTF-8" ?>


这是一个最简单的xml文档声明,包括版本信息以及字符编码。

元素

一个XML元素包括一个开始标签和一个结束标签

<title>标题</title>


当然,一个元素也可以没有内容

<title></title>


此时我们就可以把他简写成

<title/>


元素也允许进行嵌套

<blog>
<title>我是标题</title>
<content>我是内容</content>
</blog>


其中,title和content元素为blog的子元素,虽说如此,但是元素也绝对不允许交叉嵌套

并且,一个规范的XML文档只能拥有一个根元素,其他元素都是这个根元素的子元素

属性

对于每一个元素,它可以拥有多个属性,或者没有属性

<blog title="标题" content="内容"/>


属性包括属性名和属性值,两者通过=连接,属性值需要使用“ ”或者‘ ’引用

通常我们也可以使用子元素来表示属性,

介绍了半天XML的格式,现在正式进入正题,如何解析XML:

XML解析:

在iOS的开发过程中,XML的解析方式主要有两种,今天主要介绍第二种:

- DOM:解析时会一次性将文件加载到内存中,文件体积越大越占内存,缺点越明显。

- SAX:从根元素开始一级级进行解析,使用灵活。

NSXMLParser:

苹果源生SDK,采用事件驱动(event-driven)模式,即SAX的方式来解析XML文档,当NSXMLParser在处理过程中,遇到特定的事件时会通知自身的代理,调用代理方法进行解析。

通常情况,解析一个XML需要以下步骤:

假设有一XML文档格式如下:

<books>
<book bookId="1">
<name>计算机网络</name>
<page>310</page>
<author>谢希仁</author>
</book>
<book bookId="2">
<name>数据结构</name>
<page>200</page>
<author>严蔚敏</author>
</book>
</books>


// 定义数据保存所有数据
@property (nonatomic, strong) NSMutableArray *elements;
// 定义字典保存正在处理的元素
@property (nonatomic, strong) NSMutableDictionary *currentElement;
// 定义字符串保存正在处理的内容
@property (nonatomic, strong) NSMutableString *currentContent;


1.创建一个NSXMLParser对象,并设置代理:

// data通常为服务器返回的NSData类型的数据
NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
// 设置代理为本地
parser.delegate = self;
// 开始解析
BOOl isSucess = [parser parse];
if (isSuccess) {
NSLog(@"获取xml文件成功");
}else {
NSLog(@"获取xml文件失败");
}


当然必不可少的,代理需要遵守NSXMLParserDelegate协议

2.当调用解析器的Parse方法之后,程序就会开始执行代理方法解析XML文档,此处介绍需要经常使用的代理方法:

/**
*  开始解析文档的回调方法
*/
- (void)parserDidStartDocument:(NSXMLParser *)parser {
// 可以在此处初始化数组和字典以保存数据
...
}


/**
*  开始解析某一元素
*  elementName:元素名
*  attributeDict:元素属性字典
*/
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
// 由于我们需要保存的是book对象,所以当解析到开始标记为book时,创建一个可变字典,设置它的bookId;
if ([elementName isEqualToString:@"book"]) {
self.currentElement = [NSMutableDictionary dictionary];
self.currentElement[@"bookId"] = attributeDict[@"bookId"];
}
}


/**
*  解析元素内容,当解析器找到了开始标记和结束标记之间的内容是会调用这个方法,视内容长度,该方法可能会被重复调用多次
*/
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
// 当解析器找到内容时,拼接内容到当前处理的字符串
[self.currentString appendString:string];
}


/**
*  结束解析某一元素
*  elementName:元素名
*  attributeDict:元素属性字典
*/
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
if ([elementName isEqualToString:@"book"]) {
// 如果找到了结束标记为book的元素,那么证明book元素以及它的所有子元素全部处理完毕,将处理完毕的book元素存入数组当中
[self.elements addObject:self.currentElement];
return;
}
// 如果标记不是book,说明此时处理完毕的元素是book元素的子元素,那么为当前处理的book元素赋值
self.currentElement[elementName] = self.currentString;
self.currentString = nil;
}


/**
*  结束解析文件
*/
- (void)parserDidEndDocument:(NSXMLParser *)parser {
...
}


/**
*  解析出现错误时的回调方法
*/
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSLog(@"%@",parseError);
}


NSXMLParser的好处在于其事件驱动的处理模式,条例清晰,可以在每一步骤进行对应的处理,刚看到可能会觉得很复杂,多加练习自然可以掌握。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  ios xml ios开发