iOS开发之网络编程:XML,JSon解析

一、XML和JSon是什么

  • XML

下面是一段XML文本:

大家可以看看,有什么特点。

好了,我就不卖关子了,第一行介绍XML的版本和编码格式。

下面就是一个个形如<></>而且都是成对出现的,这个叫做标签。<>这是开标签,</>这是关标签。要获取某个标签的数据,需要一步步遍历下去,直到找到你所需要的那个标签下的内容,比如我要获取老师晁辉的年龄<teacher></teacher>里,那我先找到开标签为teacher的,然后找第一个面的名字是不是晁辉,不是那我就直接到第二个teacher,直到第三个teacher是叫晁辉,那我再找第三个teacher下的子标签的开标签为<age>的,那这个age的内容就是我们所需的晁辉的年龄。是不是觉得真特么麻烦??对的。这是没办法的事,XML就是这么不爽,所以如果你们公司的后台给你的数据就是一堆XML,那恭喜你了。

  • JSon

那JSon长什么样呢??机智的少年,直接就会回到前两篇,找到咱们获取数据的那个URL,将这个可爱的URL,拷贝到你的浏览器的地址栏,前往,你就看到长长的可爱的JSon数据(因为咱们之前做的一直是JSon解析啊!!!)。

我截取了部分数据:

iOS开发之网络编程:XML,JSon解析_第1张图片

 

是不是觉得里面的数据很眼熟??对的,一个大括号里面对应一个dictionary,一个中括号对应一个array。就这么点。那我问你,要找dictionary和array里面的对应数据容易不容易??遍历起来方不方便(大声告诉我!),所以啊,拿到JSon数据,你应该放声大笑。下面XML会用代码教你们做人~~~

二、解析XML

XML解析又有sax和DOM解析之分,前一个是逐行解析,文件损坏对解析没影响,但是就和我上面和大家介绍的一样,需要一个一个标签去读,读到你崩溃为止。后一个一个是完全读入整个文件,简单粗暴。但是文件一旦有某个位置错误,就GG了,而且灰常消耗内存。所以啊,都不好用,但非得用。

  • sax解析

先遵守NSXMLParserDelegate协议。

  
  
  
  
  1. // 读入文件
  2. NSString *path = [[NSBundle mainBundle] pathForResource:@"teacher" ofType:@"xml"];
  3. // NSXMLParser对象
  4. NSXMLParser *parser = [[NSXMLParser alloc] initWithData:[NSData dataWithContentsOfFile:path]];
  5. // 设置delegate对象(解析过程放在代理中执行)
  6. parser.delegate = self;
  7. // 执行解析
  8. [parser parse];

代理方法里面进行逐行解析:

  
  
  
  
  1. // 开始标签
  2. - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
  3. {
  4. NSLog(@"%@", elementName);
  5. }
  6.  
  7. // 结束标签
  8. - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
  9. {
  10. NSLog(@"%@", elementName);
  11. }
  12.  
  13. // 取值
  14. - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
  15. {
  16. NSLog(@"%@", string);
  17. }

注意:sax解析是系统提供的一套解析方案,sax解析的优点:逐行解析,不会一次性读入整个文件,减小内存消耗。因为是逐行解析,xml文件损坏对解析没影响;sax解析的缺点:因为是逐行解析,所以没办法获取文件的层级关系,对于程序员获取数据而言比较麻烦。

  • DOM解析

DOM解析需要引入两个文件。有兴趣自己动手的同学,需要注意。

就是上图的两个文件,拖进工程后,需要做三件事。

iOS开发之网络编程:XML,JSon解析_第2张图片

iOS开发之网络编程:XML,JSon解析_第3张图片

iOS开发之网络编程:XML,JSon解析_第4张图片

前两个是处理文件链接路径,下面一个是将MRC文件编译到ARC工程中所需的操作。

接下来上DOM解析代码:

  
  
  
  
  1. /********************************DOM*******************************/
  2. // 获取文件路径
  3. NSString *str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
  4. NSError *error;
  5. GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithXMLString:str options:0 error:&error];
  6. // 获取根节点
  7. // 不断的找子节点来获取数据
  8. GDataXMLElement *rootElement = document.rootElement;
  9. NSLog(@"%@", rootElement);
  10. // 获取子节点
  11. NSArray *array = rootElement.children;
  12. NSLog(@"%@", array[1]);
  13. // 获取子节点的子节点
  14. GDataXMLElement *childElement = array[1];
  15. GDataXMLElement *element = childElement.children[1];
  16. NSLog(@"%@", element);
  17. NSString *sex = element.stringValue;
  18. NSLog(@"%@", sex);

上面就是拿到一个节点,然后找子节点,逐行找。。。

第二种,已知节点名字,找到节点内容:

  
  
  
  
  1. /********************************DOM*******************************/
  2. // 获取文件路径
  3. NSString *str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
  4. NSError *error;
  5. GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithXMLString:str options:0 error:&error];
  6. // 第二种方式:使用elementForName:方法,给出一个节点的名字然后获取节点对应的数据
  7. GDataXMLElement *rootelement = document.rootElement;
  8. NSArray *arr = [rootelement elementsForName:@"teacher"];
  9. NSLog(@"%@", arr[1]);
  10. GDataXMLElement *element = arr[1];
  11. GDataXMLElement *sex = [element elementsForName:@"sex"][0];
  12. NSLog(@"%@", sex.stringValue);
  13.  

第三种,绝对路径。

  
  
  
  
  1. /********************************DOM*******************************/
  2. // 获取文件路径
  3. NSString *str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
  4. NSError *error;
  5. GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithXMLString:str options:0 error:&error];
  6. NSArray *array = [document nodesForXPath:@"teachers/teacher/sex" error:nil];
  7. NSLog(@"%@", [array[1] stringValue]);

第四种,相对路径。

  
  
  
  
  1. /********************************DOM*******************************/
  2. // 获取文件路径
  3. NSString *str = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
  4. NSError *error;
  5. GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithXMLString:str options:0 error:&error];
  6. NSArray *array = [document nodesForXPath:@"//age" error:nil];
  7. NSLog(@"%@", [array[2] stringValue]);

看到这里,是不是被恶心到了。。。

三、解析JSon

这个就非常简单了。一行代码搞定,拿到咱们的NSData,然后

  
  
  
  
  1. NSError *newError = nil;
  2. // 获取数据
  3. NSDictionary *dict = [NSJSONSerialization JSONObjectWithData:data options:NSJSONReadingMutableContainers error:&newError];

第一个参数就是我们从服务器获取的data数据。第二个参数指的是你的容器类型,这是个枚举值。

  
  
  
  
  1. typedef NS_OPTIONS(NSUInteger, NSJSONReadingOptions) {
  2. NSJSONReadingMutableContainers = (1UL << 0), // 用NSDictionary或者NSArray接收,可变的mutable也是可以的。
  3. NSJSONReadingMutableLeaves = (1UL << 1), // 用NSMutableString接收
  4. NSJSONReadingAllowFragments = (1UL << 2) // 既不是NSDictionary也不是NSArray的实例
  5. }

如果获取的数据的最外层是中括号(上面的截图里面最外层是大括号),那么这里用来接收数据的变量类型就不是NSDictionary而是NSArray了。

四、总结

从本节的篇幅就可以看到,JSon用起来不是一般的方便,而XML怎么用都不爽。这个也是没办法的,只有央求你们的后台不会丢给你XML的数据了。

你可能感兴趣的:(ios,json,xml,网络编程)