05、网络解析

2016-12-20  本文已影响0人  深爱久随i

解析:从事先规定好的格式中提取数据
iOS开发常见的解析:XML解析,JSON解析

XML解析

XMl事例:

<?xml version="1.0" encoding="UTF-8"?>
<!-- 根结点 是所有节点的父节点或者爷节点 -->
<students> <!--开始节点-->
<!--student的子节点,position就是该节点的属性-->
   <student position="愤青">
     <!--lyj是name节点的内容,我们可以将该节点所有的特性都用属性来表示,但是为了阅读起来方便,我们一般也会将该节点的特性用他的子节点来表示-->
     <name>lyj</name>
     <age>25</age>
     <sex>男</sex>
   </student>
   <student>
     <name>zza</name>
     <age>22</age>
     <sex>保密</sex>
   </student>
</students> <!--结束节点-->

XML有两种解析方法:DOM(Document Object Model)解析和SAX(Simple API for XML)工具

1.SAX解析

SAX基本原理:采用事件驱动解析XML文件,以流式方式逐行的去读,它不需要解析完整个文档,在按内容顺序解析文档的过各中,SAX会判断当前讲到的字符是否合法XML语法中的某部分,如果符合就触发事件(例如startDocument()、endDocument()诸如此类的事件),它的特点是不会记录前面所碰到的标签,并且它是一个解析速度快并且占用内存少的XML解析器
特点:
一.是基于事件驱动的解析方式
二.逐行解析
三.只能读取(DOM解析可读可写)
四.一般只用做文档比较大的时候

//sax解析
-(void)saxPath{
    //sax解析:基于事件驱动的解析方式,逐行解析
    NSString* xmlPath=[[NSBundle mainBundle] pathForResource:@"xml" ofType:@"xml"];
    NSString* xmlStr=[NSString stringWithContentsOfFile:xmlPath encoding:NSUTF8StringEncoding error:nil];
    //字符串转data类型
    NSData* xmlData=[xmlStr dataUsingEncoding:NSUTF8StringEncoding];
    //参数:需要解析的文件内容
    NSXMLParser* xmlParser=[[NSXMLParser alloc] initWithData:xmlData];
    //设置代理
    xmlParser.delegate=self;
    //开始解析  同步的过程  当整个解析完成了才会执行下一行代码
    BOOL isSuccess=[xmlParser parse];
    if (isSuccess) {
        NSLog(@"解析成功");
    }else{
        NSLog(@"解析失败");
    }
    //解析的过程不结束,就不会执行该打印
    NSLog(@"我在解析的最底下");
  
}

下来遵循协议,实现协议方法,为了方便获取数据,声明一个字典和数组

@interface ViewController ()<NSXMLParserDelegate>
@property(nonatomic,strong)NSMutableArray* allDataArray;//存放所有student的节点
@property(nonatomic,strong)NSMutableDictionary* studentDic;//将student转换为字典
@property(nonatomic,strong)NSString* noteValueString;//存储节点中的值
#pragma mark--------parser解析的代理方法
//开始解析整个文档了
-(void)parserDidStartDocument:(NSXMLParser *)parser{
        NSLog(@"开始解析整个文档了");
    //初始化外部的可变数组,准备存放student节点
    self.allDataArray=[[NSMutableArray alloc] init]; 
    }
//当碰到开始节点或开始标签的时候会执行的代理方法
//elementName:标签名称(节点名),例如<name>
//namespaceURI:命名空间的标识名 例如<teacher xmlns:l="www.lanou3g.com">
//qName:命名空间的值,就是上面的 www.lanou3g.com
//attributeDict:标签的属性 例如 <student position="愤青"> position就是标签的属性,attributeDict=={pasition:"愤青"}
-(void)parser:(NSXMLParser*)parser didStartElement:(nonnull NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(nonnull NSDictionary<NSString *,NSString *> *)attributeDict{
    NSLog(@"碰到开始标签----%@",elementName);
    //当开始解析student节点的时候,说明我们要用到字典了,就需要对字典进行初始化
    if ([elementName isEqualToString:@"student"]) {
        self.studentDic=[[NSMutableDictionary alloc] init];
    }
    
}
    
//取出标签中的值
//string:就是标签中的值
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
    NSLog(@"正在解析的值为---%@",string);
    //将节点的内容存储起来,以供节点解析结束使用
    self.noteValueString=string;
    
}
    
//遇到当前正在解析标签结束标签
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
    NSLog(@"碰到结束标签----%@",elementName);
    if ([elementName isEqualToString:@"name"]) {
        //说明name标签解析结束
        [self.studentDic setObject:self.noteValueString forKey:elementName];
    }
    
    if ([elementName isEqualToString:@"age"]) {
        //说明age标签解析结束
        [self.studentDic setObject:self.noteValueString forKey:elementName];
    }
    if ([elementName isEqualToString:@"sex"]) {
        //说明sex标签解析结束
        [self.studentDic setObject:self.noteValueString forKey:elementName];
    }
    if ([elementName isEqualToString:@"student"]) {
        //说明一个student已经解析完成,说明一个字典已经完整,应该将字典放入数组中了
        [self.allDataArray addObject:self.studentDic];
    }
}
    
//整个文档解析结束
-(void)parserDidEndDocument:(NSXMLParser *)parser{
        NSLog(@"整个文档解析结束");
    //当整个文档解析结束,说明所有的数据我们已经拿到,可以正常使用了
    NSLog(@"----%@",self.allDataArray);
  }

//当解析出错会调用的方法
-(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
    NSLog(@"解析出现错误---%@",parseError.description);
}
    
2.DOM解析

dom解析基于文档驱动的解析方式,DOM解析XML时,读入整个XML文档并构建一个驻留内存的树结构(节点树),通过遍历树结构可以检索任意XML节点,读取他的属性和值,而且通常情况下,可以借助XPath,直接查询XML节点


使用方法:
1.获取GDataXMLNode.h/m文件,将GDataXMLNode.h/m文件添加到工程中
2.向工程中增加“libxml2.dylib”动态库
具体做法 选中整个工程 在Build Phases的倒数第二个选项中点“+”号,搜索libxml2.dylib 并添加
3.在工程的“Build Settings”页中找到“Header Search Path” 点击添加 "/usr/include/libxml2"
4.导入“GDataXMLNode.h”文件到头文件 如果工程能编译通过,说明添加成功
注意:
(1)在工程的Build phases设置的Link Binary With Libraries里面点击加号,搜索libxml2.tbd,选择添加

11111.png

(2)在工程的Build Settings设置里面搜索search,找到Search paths选项下的Header Search Paths,加入一条/usr/include/libxml2这里三个反斜杠不能少

222.png

(3)在工程的Build Settings设置里面搜索Other Linker Flags,找到Other Linker Flags,双击空白处输入-lxml2


3333.png

这样在编译就不会报错啦。☺️

//dom解析  基于文档驱动的解析方式
-(void)domParser{
    //需要获取解析的源文件
    NSString* xmlPath=[[NSBundle mainBundle] pathForResource:@"xml" ofType:@"xml"];
    NSString* xmlStr=[NSString stringWithContentsOfFile:xmlPath encoding:NSUTF8StringEncoding error:nil];
    //字符串转data类型
    NSData* xmlData=[xmlStr dataUsingEncoding:NSUTF8StringEncoding];
   //dom解析
    //step1:将源xml文件转换成树状结构的文档放在内存中,以供遍历获取每个节点
    GDataXMLDocument* xmlDoc=[[GDataXMLDocument alloc] initWithData:xmlData encoding:NSUTF8StringEncoding error:nil];
    //step2:获取根节点 就相当于获取到了students节点
    GDataXMLElement* rootElement=[xmlDoc rootElement];
    //step3:获取我们需要的子节点
    //参数:我们需要获取的标签名
//    NSArray* studentArray=[rootElement elementsForName:@"student"];
    //初始化一个可变数组,准备存放所有的student转换成的字典
    NSMutableArray* allStudentsArray=[[NSMutableArray alloc] init];
    
    //添加节点(向现有的文档动态的增加一个student节点)
    //节点创建   <student></student>
    GDataXMLElement* studentElement = [GDataXMLElement elementWithName:@"student"];
    //将student节点加入到它的父节点中
//    [rootElement addChild:studentElement];
    //为student增加子节点
    GDataXMLElement* nameElement = [GDataXMLElement elementWithName:@"name" stringValue:@"ze an"];
    GDataXMLElement* ageElement = [GDataXMLElement elementWithName:@"age" stringValue:@"23"];
    GDataXMLElement* genderElement = [GDataXMLElement elementWithName:@"gender" stringValue:@"未知"];
    [studentElement addChild:nameElement];
    [studentElement addChild:ageElement];
    [studentElement addChild:genderElement];
     [rootElement addChild:studentElement];
     NSArray* studentArray=[rootElement elementsForName:@"student"];
   

    
    //step4:遍历数组
    //stuNode:对应一个student节点
/*<student>
    <name></name>
    <age></age>
    <sex></sex>
</student>
    */
    
    //每执行一次循环体,就相当于获取了一个完整的student节点,结构如上
//    for (GDataXMLElement* stuelement in studentArray) {
//        //初始化一个字典
//      NSMutableDictionary* studentDic=[[NSMutableDictionary alloc] init];
////        NSString* name=[[[stuelement elementsForName:@"name"] firstObject] stringValue];
//        //获取name节点
//        GDataXMLElement* nameElement=[stuelement elementsForName:@"name"].firstObject;
//        //取出节点中的值
//        NSString* name=[nameElement stringValue];
//        //将name的值放入字典中
//        [studentDic setObject:name forKey:@"name"];
//        
//        //获取age节点
//        GDataXMLElement* ageElement=[stuelement elementsForName:@"age"].firstObject;
//        NSString* age=[ageElement stringValue];
//        [studentDic setObject:age forKey:@"age"];
//        
//        //获取sex节点
//        GDataXMLElement* sexElement=[stuelement elementsForName:@"sex"].firstObject;
//        NSString* sex=[sexElement stringValue];
//        [studentDic setObject:sex forKey:@"sex"];
//        //将字典放入数组中
//        [allStudentsArray addObject:studentDic];
//    }
//    NSLog(@"----%@",allStudentsArray);
    
   
    for (GDataXMLElement* studentNode in studentArray) {
        //遍历获取student所有的子节点
        NSArray* subStudentNode=[studentNode children];
         NSMutableDictionary* studentDic=[[NSMutableDictionary alloc] init];
        for (GDataXMLElement* subOfStudentNode in subStudentNode) {
            //获取子节点的名称
            NSString* noteName=[subOfStudentNode name];
            //获取节点内容
            NSString* noteValue=[subOfStudentNode stringValue];
            [studentDic setObject:noteValue forKey:noteName];
           
        }
        //  将字典加入到数组中
         [allStudentsArray addObject:studentDic];
    }
    NSLog(@"----%@",allStudentsArray);
    
    
}
3.JSON解析
//json解析
-(void)jsonParser{
    //获取要解析的json源文件
    NSString* jsonPath=[[NSBundle mainBundle] pathForResource:@"DemoJson" ofType:@"json"];
    NSString* jsonStr=[NSString stringWithContentsOfFile:jsonPath encoding:NSUTF8StringEncoding error:nil];
    //字符串转data类型
    NSData* jsonData=[jsonStr dataUsingEncoding:NSUTF8StringEncoding];
    //json解析
   NSDictionary* dic= [NSJSONSerialization JSONObjectWithData:jsonData options:NSJSONReadingAllowFragments error:nil];
    NSLog(@"---%@",dic);
    
}
    
上一篇下一篇

猜你喜欢

热点阅读