iOS - XML解析

3,972 阅读4分钟

前些日子,看到一个同学在问xml解析的问题,自己也对xml解析了解不是很多,都是用了jsno解析。别去学习了一下xml解析。
在收xml解析之前,首先先简单说一下xml的基本语法。
XML :是Extensible Markup Language的简写,全名叫做可扩展标记语言。
简单的语法如下:

这里写图片描述

这里写图片描述

这里写图片描述

示例:
需求:北京 晴 最高温度15℃ 最低温度5℃
XML实现:


另一种实现方式:


  北京
  晴
  15
  5

以上就是简单的xml的基本语法。下面开始说iOS中xml的解析的事。
关于XML,有两种解析方式,分别是SAX(Simple API for XML,基于事件驱动的解析方式,逐行解析数据,采用协议回调机制)和DOM(Document Object Model ,文档对象模型。解析时需要将XML文件整体读入,并且将XML结构化成树状,使用时再通过树状结构读取相关数据,查找特定节点,然后对节点进行读或写)。苹果官方原生的NSXMLParse类库采用第一种方式,即SAX方式解析XML,它基于事件通知的模式,一边读取文档一边解析数据,不用等待文档全部读入以后再解析,所以如果你正打印解析的数据,而解析过程中间出现了错误,那么在错误节点之间的数据会正常打印,错误后面的数据不会被打印。解析过程由NSXMLParserDelegate协议方法回调。在这里,我们主要讲iOS原生的解析方式,就是使用NSXMLParserDelegate协议方法回调。
首先使用这个了解这个协议的代理方法:

//准备解析
-(void)parserDidStartDocument:(NSXMLParser *)parser;
//准备解析当前节点
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict;
//获取首尾节点间内容
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
//解析完当前节点
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
//解析结束
-(void)parserDidEndDocument:(NSXMLParser *)parser;

简单介绍完代理后,进行写demo。
解析第一个xml的:James
撸代码:

- (IBAction)onParse:(id)sender {
    NSString *xmlStr1 = @"James";
    NSData *xmlData = [xmlStr1 dataUsingEncoding:NSUTF8StringEncoding];
    //初始化NSXMLParser,并遵循协议
    NSXMLParser *xmlParaser = [[NSXMLParser alloc]initWithData:xmlData];
    xmlParaser.delegate = self;
    //开始解析
    [xmlParaser parse];
}
//准备解析
-(void)parserDidStartDocument:(NSXMLParser *)parser{
    _label.text = [_label.text stringByAppendingString:@"准备解析"];
    _label.text = [_label.text stringByAppendingString:@"\n"];
}
//准备解析当前节点
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
    _label.text = [_label.text stringByAppendingString:@"准备解析当前节点"];
    _label.text = [_label.text stringByAppendingString:@"\n"];
}
//获取首尾节点间内容
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    _label.text = [_label.text stringByAppendingString:string];
    _label.text = [_label.text stringByAppendingString:@"\n"];
}
//解析完当前节点
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
    _label.text = [_label.text stringByAppendingString:@"解析完当前节点"];
    _label.text = [_label.text stringByAppendingString:@"\n"];
}
//解析结束
-(void)parserDidEndDocument:(NSXMLParser *)parser{
    _label.text = _label.text = [_label.text stringByAppendingString:@"解析结束"];
    _label.text = [_label.text stringByAppendingString:@"\n"];
}
@end

运行结果:

这里写图片描述

第二个例子:解析:
直接撸代码:

- (IBAction)onParse:(id)sender {
//    NSString *xmlStr1 = @"James";
    NSString *xmlStr2 = @"";
    NSData *xmlData = [xmlStr2 dataUsingEncoding:NSUTF8StringEncoding];
    NSXMLParser *xmlParaser = [[NSXMLParser alloc]initWithData:xmlData];
    xmlParaser.delegate = self;
    [xmlParaser parse];
}
//准备解析
-(void)parserDidStartDocument:(NSXMLParser *)parser{
    _label.text = [_label.text stringByAppendingString:@"准备解析"];
    _label.text = [_label.text stringByAppendingString:@"\n"];
}
//准备解析当前节点
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
    _label.text = [_label.text stringByAppendingString:@"准备解析当前节点"];
    _label.text = [_label.text stringByAppendingString:elementName];
    _label.text = [_label.text stringByAppendingString:@"\n"];
    _label.text = [_label.text stringByAppendingString:[attributeDict objectForKey:@"name"]];
    _label.text = [_label.text stringByAppendingString:@"\n"];
}
//获取首尾节点间内容
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    _label.text = [_label.text stringByAppendingString:@"获取首尾节点间内容"];
    _label.text = [_label.text stringByAppendingString:@"\n"];
}
//解析完当前节点
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
    _label.text = [_label.text stringByAppendingString:@"解析完当前节点"];
    _label.text = [_label.text stringByAppendingString:@"\n"];
}
//解析结束
-(void)parserDidEndDocument:(NSXMLParser *)parser{
    _label.text = _label.text = [_label.text stringByAppendingString:@"解析结束"];
    _label.text = [_label.text stringByAppendingString:@"\n"];
}
@end

运行结果:

这里写图片描述

另一种的解析,可以使用GDataXML第三方进行解析。这里不再详细说。

最后总结:
xml两种解析SAX和DOM,各有优势,比如在应对比较大数据量的XML文件时,后者由于需要先读取整个文档,性能和速度上就必然不及前者了。解析小数据量的时候使用DMO更加高效,大家可以根据数据量的多少进行合理选择。

以上就是xml的简单解析。再次感谢慕课网(www.imooc.com/)。
以上如有错误,请指出,非常感谢。

微信公众号:不靠谱程序猿 微信公众号:Sheffi_Programmer
Github:Sheffi(github.com/goingmyway1…
新浪微博:Sheffi567
掘金:Sheffi(juejin.cn/user/148619…
博客地址:blog.csdn.net/qq_34195670…