企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
xml与json的对比,前面文章已经提供参考,至于xml的语法结构也不在这详述。 直奔iOS中解析xml的方法。 **iOS中的XML解析(Dom和SAX)** Dom方式使用的是文档对象模型解析,它首先要将xml文件整个读入内存中,然后再来构建Dom对象,在DOM对象里,xml文件中的所有元素都可以当做节点(Node)对象来处理。这种方式优点是方便对文档进行增加、删除、修改、添加等操作,缺点是它首先要将整个文件读入内存中在解析,如果文件大。会很消耗内存,并且它的执行速度慢。 SAX解析XML文件采用事件驱动的方式进行,也就是说,SAX是逐行扫描文件,遇到符合条件的设定条件后就会触发特定的事件,回调你写好的事件处理程 序。使用SAX的优势在于其解析速度较快,占用内存较少(相对于DOM而言)。而且SAX在解析文件的过程中得到自己需要的信息后可以随时终止解析,并不 一定要等文件全部解析完毕。凡事有利必有弊,其劣势在于SAX采用的是流式处理方式,当遇到某个标签的时候,它并不会记录下以前所遇到的标签,也就是说, 在处理某个标签的时候,所能够得到的信息就是标签的名字和属性,至于标签内部的嵌套结构,上层标签、下层标签以及其兄弟节点的名称等等与其结构 相关的信息都是不得而知的。实际上就是把XML文件的结构信息丢掉了,如果需要得到这些信息的话,只能你自己在程序里进行处理了。所以相对DOM而 言,SAX处理XML文档没有DOM方便,SAX处理的过程相对DOM而言也比较复杂。 **总结:** DOM:一次性将整个XML文档加载进内存,比较适合解析小文件 SAX:SAX采用事件驱动,从根元素开始,按顺序一个元素一个元素往下解析,比较适合解析大文件。 解析方法: 苹果原生 NSXMLParser:SAX方式解析,使用简单 第三方框架 libxml2:纯C语言,默认包含在iOS SDK中,同时支持DOM和SAX方式解析 GDataXML:DOM方式解析,由Google开发,基于libxml2 XML解析方式的选择建议 大文件:NSXMLParser、libxml2 小文件:GDataXML **GDataXML:** 常用的类      GDataXMLDocument:代表整个XML文档      GDataXMLElement:代表文档中的每个元素 常用方法:      elementsForName:根据元素名称得到元素节点      attributeForName:方法可以获得属性值 更多的操作xml的方法和属性,查阅GDataXMLNode.h  使用步骤: 1、下载GDataXMLNode ,下载地址:[http://download.csdn.net/detail/zhixinhuacom/9417644](http://download.csdn.net/detail/zhixinhuacom/9417644),并 解压将其中的GDataXMLNode.h 和 GDataXMLNode.m文件拖到项目中。 2、由于GDataXML基于libxml2库,因此要导入libxml2 ![](https://box.kancloud.cn/2016-03-07_56dd401233131.jpg) 3、设置libxml2的头文件搜索路径(为了能找到libxml2库的所有头文件) 在**Head Search Path**中加入/usr/include/libxml2                                   ![](https://box.kancloud.cn/2016-03-07_56dd40124e2e7.jpg) 4、设置链接参数(自动链接libxml2库) 在**Other Linker Flags**中加入-lxml2 ![](https://box.kancloud.cn/2016-03-07_56dd401279dd7.jpg) 5、如果报arc错误,则设置GDataXML编译参数 ![](https://box.kancloud.cn/2016-03-07_56dd40129d19e.jpg) 6、导入#import "GDataXMLNode.h" 头文件就可以使用了。 例子: 解析下面格式的xml ![](https://box.kancloud.cn/2016-03-07_56dd4012bd5ad.jpg)    ~~~ -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ NSURL *url = [NSURL URLWithString:@"http://localhost:8080/myService/video?type=XML"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { //1、加载xml数据 GDataXMLDocument *document = [[GDataXMLDocument alloc]initWithData:data options:0 error:nil]; //2、获取xml根元素(videos) GDataXMLElement *root = document.rootElement; // //元素子节点个数(不包括子节点下的节点) // NSInteger childCount = root.childCount; // //元素名称 // NSString *elementName = root.name; // //节点内容字符串 // NSString *xmlStr = root.XMLString; // NSLog(@"childCount=%ld\nelementName=%@\nxmlStr=%@",childCount,elementName,xmlStr); //3、获取根元素的所有video元素 NSArray *elements = [root elementsForName:@"video"]; for (GDataXMLElement *element in elements) { //4、获取属性植 NSString *idStr = [element attributeForName:@"id"].stringValue; NSString *name = [element attributeForName:@"name"].stringValue; NSString *length = [element attributeForName:@"length"].stringValue; NSString *image = [element attributeForName:@"image"].stringValue; NSString *url = [element attributeForName:@"url"].stringValue; NSLog(@"id=%@",idStr); NSLog(@"name=%@",name); NSLog(@"length=%@",length); NSLog(@"image=%@",image); NSLog(@"url=%@",url); } }]; } ~~~ NSXMLParser: NSXMLParser采取的是SAX方式解析,特点是事件驱动,下面情况都会通知代理: (1)当扫描到文档(Document)的开始与结束 (2)当扫描到元素(Element)的开始与结束 **一:使用步骤:** 1、传入XML数据,创建解析器 ~~~ NSXMLParser *parser = [[NSXMLParseralloc] initWithData:data]; ~~~ 2、设置代理,监听解析过程 `parser.delegate =self;` 3、开始解析 [parserparse]; **二: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` 例子:同样解析上面格式的xml ~~~ #import "ViewController.h" @interface ViewController ()<NSXMLParserDelegate> @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. } -(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ NSURL *url = [NSURL URLWithString:@"http://localhost:8080/myService/video?type=XML"]; NSURLRequest *request = [NSURLRequest requestWithURL:url]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse * _Nullable response, NSData * _Nullable data, NSError * _Nullable connectionError) { //1、传入xml,创建解析器 NSXMLParser *parser = [[NSXMLParser alloc]initWithData:data]; //2、设置代理、监听解析过程 parser.delegate = self; //3、开始解析 [parser parse]; }]; } #pragma mark NSXMLParserDelegate代理方法 //当扫描到元素的开始时调用(attributeDict存放着元素的属性) -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{ NSLog(@"===========%@元素开始解析========",elementName); if ([@"videos" isEqualToString:elementName]) { NSLog(@"%@是根节点",elementName); return; } NSString *idStr = attributeDict[@"id"]; NSString *name = attributeDict[@"name"]; NSString *length = attributeDict[@"length"]; NSString *image = attributeDict[@"image"]; NSString *urlStr = attributeDict[@"url"]; NSLog(@" \n id=%@ \n name=%@\n length=%@ \n image=%@ \n url=%@",idStr,name,length,image,urlStr); }; //当扫描到元素的结束时调用 -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{ NSLog(@"===========%@元素解析结束========",elementName); } //当扫描到文档的开始时调用(开始解析) -(void)parserDidStartDocument:(NSXMLParser *)parser{ NSLog(@"parserDidStartDocument=====开始解析======="); } //当扫描到文档的结束时调用(解析完毕) -(void)parserDidEndDocument:(NSXMLParser *)parser{ NSLog(@"parserDidEndDocument=====解析完毕========"); } @end ~~~ 解析输入结果: ![](https://box.kancloud.cn/2016-03-07_56dd40130638a.jpg)![](https://box.kancloud.cn/2016-03-07_56dd40133586f.jpg)