现大多公司使用接口数据都是json格式,但也有少量很老的系统还是使用XML格式来传递数据,相对来传递一样的数据json格式的数据比使用xml传递更小。简单说说json、及xml的解析
JSON
什么是json?
首先来说说什么是json。
- json是一种轻量级的数据格式,一般用于数据交互;服务器方会给客户端的数据,一般都是json格式或者xml(文件下载除外)
- JSON的格式很像OC中的数组和字典,如下
{"name":"张三","age":22}、[{"name":"张三","age":22},{"name":"李四","age":22}] - 标准的JSON格式key必须用双引号
在开发过程中,有些服务端同学偷懒会使用单引号,这种在javaScript和安卓开发是能正常解析的,但iOS不行,遇到该种情况一定要强烈要求使用标准格式
JSON数据看上去像字典或数组,但实际上是一串字符串,想要使用它需要进行解析。
JSON转换OC数据类型对应表
JSON | OC |
|
|
|
|
双引号 |
|
数字 |
|
|
|
|
|
解析JSON一种使用原生自带NSJSONSerialization,一种使用第三方框架JSONKit、SBJson、TouchJSON这三个框架性能逐次变差;原生解析性能是最好的,NSJSONSerialization在ios7推出macOS 10.9推出,此版本之前的json解析需要第三方
NSJSONSerialization解析
NSJSONSerialization常见方法
JSON数据转OC对象
-
+ JSONObjectWithData:options:error:json data数据转换成oc对象(NSDictionary、NSArray) -
JSONObjectWithStream:options:error:json数据流转换成oc对象 - 两个方法都有使用到
NSJSONReadingOptions参数,该参数用于表明
-
NSJSONReadingMutableContainers指定将数组和字典创建为可变对象 -
NSJSONReadingMutableLeaves指定json数据中内部所有字符串数据创建为NSMutableString(一般不使用) -
NSJSONReadingAllowFragments即不是字典也不是数组,则必须使用该枚举值(如数据为"这是数据"将会解析对应的NSString)
NSString *jsonStr = @"{\"name\":\"张三\",\"age\":24}";
NSData *jsonData = [jsonStr dataUsingEncoding:NSUTF8StringEncoding];
NSError *error=nil;
NSMutableDictionary *ocInstance = [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingMutableContainers error:&error];
[ocInstance setObject:@(12) forKey:@"child"];注意,通常枚举的第一个枚举值不等于0的话传入0效率最高
OC对象转JSON数据方法
-
+ dataWithJSONObject:options:error:从oc对象返回JSON数据。 -
+ isValidJSONObject:返回一个布尔值,该值指示是否可以将给定对象转换为JSON数据 + writeJSONObject:toStream:options:error:将给定的JSON对象写入流中。不常用
上述两个转换方法中都有使用到NSJSONWritingOptions枚举,枚举含义如下
-
NSJSONWritingPrettyPrinted = (1UL << 0)使用空格和缩进的写入选项使输出更具可读性 -
NSJSONWritingSortedKeys API_AVAILABLE(macos(10.13), ios(11.0), watchos(4.0), tvos(11.0)) = (1UL << 1)按字典顺序对键进行排序的写入选项 -
NSJSONWritingFragmentsAllowed = (1UL << 2)允许写入片段非标准如@"要转换的数据"。 -
NSJSONWritingWithoutEscapingSlashes API_AVAILABLE(macos(10.15), ios(13.0), watchos(6.0), tvos(13.0)) = (1UL << 3)不转义斜线
NSDictionary *dic = @{@"name":@"张三",
@"age":@(24),
@"child":@{@"name":@"张小三",
@"age":@(2)}
};
NSData *jsonData=[NSJSONSerialization dataWithJSONObject:dic options:0 error:nil];
NSString *json= [[NSString alloc]initWithData:jsonData encoding:NSUTF8StringEncoding];
NSLog(@"%@",json);注意,通常枚举的第一个枚举值不等于0的话传入0效率最高
XML
XML 指可扩展标记语言
XML 被设计用来传输和存储数据。
XML由以下几部分构成
- 文档声明(通常可忽略不计)
- 元素(Element)
- 属性(Attribute)
文档声明
文档声明在xml文档的最前面,必须编写一个文档声明,用来声明xml文档的类型<?xml version="1.0" ?>最简单的声明,用encoding属性说明文档的字符编码<?xml version="1.0" encoding="utf-8"?>
元素(Element)
- 一个元素包括了开始标签和结束标签
- 有内容的元素
<from>John</from> - 没内容的元素
<from></from>,可简写成<from/> - 元素可嵌套其他元素,不可出现交叉嵌套。
<note>
<to>George</to>
<from>John</from>
</note>- 规范的xml文档最多只有一个根元素,其他元素都是根元素的子孙节点
-
<from>John</from>与
<from>
John
</from>是不一样的,第二个的空格和换行符也是元素的内容
属性
- 一个元素可以有多个属性
<book category="COOKING">
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>在这个里面book里面有个category属性,title有lang属性。
- 属性必须使用双引号
""或者单引号''包住 - 属性表示的信息也可以用子元素来表示比如
<book >
<category>COOKING</category>
<title lang="en">Everyday Italian</title>
<author>Giada De Laurentiis</author>
<year>2005</year>
<price>30.00</price>
</book>XML解析
要想从xml中提取信息,就得解析xml;解析xml有两种方式
-
DOM解析:一次性将xml文档加载进内存,比较合适解析小的xml文档 -
SAX解析:从根元素开始,按顺序一个元素逐次解析,比较合适解析大文件
ios解析xml中有两种
- 苹果原生,使用
NSXMLParse:SAX方式解析,使用简单 - 第三方框架:
libxml2、GDataXML
-
libxml2纯c语音,默认包含在iOS SDK中,同时支持DOM和SAX方式解析 -
GDataXMLDOM解析,由google基于libxml2开发,
解析xml大文件建议使用```NSXMLParse、libxml2``;小文件上述三种可
NSXMLParse 使用
- 创建
NSXMLParse解析器 - 设置代理
- 开始解析
NSXMLParse解析是在代理里面开始的
常用解析的代理方法如下
-
- parserDidStartDocument:开始解析 -
- parserDidEndDocument:成功完成解析后 -
- parser:didStartElement:namespaceURI:qualifiedName:attributes:当解析器对象遇到元素的开始标签时 -
- parser:didEndElement:namespaceURI:qualifiedName:当解析器对象元素的结束标签时 -
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string当解析器找到开始标记和结束标记之间的字符时,调用这个方法解析当前节点的所有字符
附上使用NSXMLPares的简单封装XMLParseDome,该Dome将xml解析出的内容封装到了XPDXMLElement
















