zoukankan      html  css  js  c++  java
  • 03-IOSCore

    一、XML 可扩展标记语言

    是什么?是一段有规范的字符串,

    用在哪?用在任何地方

     

    语法:

    * 结点Node

    <结点名 属性名="属性值">

        结点内容

    </结点名>

    * 结点的开始和结尾配对

    * 结点内可以有子结点

    * 结点内可以有文本

    * 结点名和属性名区分大小写

    * 结点不能交叉

    * 结点名和属性名 随便写

     

    术语:

    结点、属性

    叶子结点  :没有子结点的结点

        <a b="c"></a>可以简化<a b="c" />

    非叶子结点  :有子结点的结点

        对于存储数据的xml,非叶子结点几乎不存储任何文本,对于一些xml的变体xhtml,就会出现大量的非叶子子结点存储文本的现象,比如:

        <div>

            <h1>...</h1>

            <p>ggg...<a>...</a></p>

        </div>

    根结点  :没有父结点的结点,一个xml只能有一个根结点

    层级关系:

    子结点

    父结点

    兄弟结点

    其他:特殊符号不能直接写在xml中,比如<要写成&lt;    >&gt;

     

    xml解析:

    XML文件结构解析

    1 事件驱动 SAX  iOS采用事件驱动解析

    ios具体解析xml文档步骤:

    1) 准备好xml文档的路径

    2) 转换为data数据

    3) 创建NSXMLParser对象调用initWithDatadata传进来

    4) 设置delegate,然后发送parse消息解析文档

    NSString *path = @"/.../message.xml";

        NSData *data = [NSDatadataWithContentsOfFile:path];

        NSXMLParser *xmlParser = [[NSXMLParseralloc] initWithData:data];

       

        xmlParser.delegate = self;

        [xmlParser parse];

     

    delegate中几个重要的API

    // 开始解析xml文档

    -(void)parserDidStartDocument:(NSXMLParser *)parser{

        NSLog(@"开始解析...");

    }

    // 发现结点节点名 + 属性

    -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{

       

        NSLog(@"开始节点名:%@",elementName);

        [attributeDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {

            NSLog(@"属性名:%@, 属性值:%@",key,obj);

        }];

    }

    // 结束结点

    -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{

        NSLog(@"结束结点:%@",elementName);

    }

    // 发现文本

    -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{

        NSLog(@"发现文本:%@",string);

    }

    // 结束解析xml文档

    -(void)parserDidEndDocument:(NSXMLParser *)parser{

        NSLog(@"结束文档解析");

    }

     

    实现xml解析步骤:

    /*

     解析xml文档:

     根据本例中message.xml文件解析

     如果发现Message节点就创建一个类,同时根据attributeDict可以获取到属性order并赋值

     为了可以获取xml文件中文本的值并赋给message类的属性(节点名),需要记下最近的那个节点名lastElementName

     在发现文本方法中判断lastElementName是否和message类中的属性相同,如果相同就赋值

     注意:文本直接赋值会出问题," "这个会覆盖赋值好的文本,所以在结束结点中应该给lastElementName置空

     

     快速修改本文件中所有的属性名技巧:

     选中属性名后右击选中refactor -> rename

     */

    #import "MXMessageParse.h"

    #import "MXMessage.h"

     

    @interfaceMXMessageParse ()

    @property(nonatomic,strong) MXMessage *lastMessage;

    @property(nonatomic,copy) NSString *lastElementName;

    @property(nonatomic,strong) NSMutableArray *messages;

    @end

     

    @implementation MXMessageParse

    -(void)parser{

        NSString *path = @"/Users/tarena/yz/第三阶段(UI核心_Model赵哲)/day03/day0302_xml_parse解析/message.xml";

        NSData *data = [NSDatadataWithContentsOfFile:path];

        NSXMLParser *xmlParser = [[NSXMLParseralloc] initWithData:data];

       

        xmlParser.delegate = self;

        [xmlParser parse];

       

    }

    // 开始解析xml文档

    -(void)parserDidStartDocument:(NSXMLParser *)parser{

        NSLog(@"开始解析...");

    }

    // 发现结点节点名 + 属性

    -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{

       

        NSLog(@"开始节点名:%@",elementName);

        [attributeDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {

            NSLog(@"属性名:%@, 属性值:%@",key,obj);

        }];

        if ([elementName isEqualToString:@"Message"]) {

            self.lastMessage = [[MXMessagealloc] init];

            self.lastMessage.order = [attributeDict[@"order"] intValue];

        }elseif ([elementName isEqualToString:@"messages"]){

            self.messages = [NSMutableArrayarray];

        }

        self.lastElementName = elementName;

    }

    // 结束结点

    -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{

        NSLog(@"结束结点:%@",elementName);

        if ([elementName isEqualToString:@"Message"]) {

            [self.messagesaddObject:self.lastMessage];

        }

        self.lastElementName = Nil;

    }

    // 发现文本

    -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{

        NSLog(@"发现文本:%@",string);

        if ([self.lastElementNameisEqualToString:@"fromMe"]) {

            self.lastMessage.fromMe = [string isEqualToString:@"YES"];

        }elseif ([self.lastElementNameisEqualToString:@"type"]){

            NSString *type = string;

            if ([type isEqualToString:@"TXT"]) {

                self.lastMessage.type = MXMessageTypeText;

            }

        }elseif ([self.lastElementNameisEqualToString:@"content"]){

            self.lastMessage.content = string;

        }

       

    }

    // 结束解析xml文档

    -(void)parserDidEndDocument:(NSXMLParser *)parser{

        NSLog(@"结束文档解析");

    }

     

    2 树状模型  DOM

    XML结构 <-> 对象

    Node *rootNode = [parser parse:path];

    NSString *elementName = rootNode.name;

    Node *messageNode = [rootNode childNodeOfName@"Message"];

    messageNode.name;

    [messageNode attributeByName:@"order"];

     

    3 优缺点对比

    事件驱动          树状模型

    使用困难          使用简单

    边读取边解析      读取完整后在解析

    摘取部分重要信息  从完整信息中搜索

     

    二、plist (Property List)

    是一个有固定格式的xml文件,用来存储中小型数据,在ios中使用

    plist可以存储的数据类型:

    NSArray

    NSDictionary

    根节点必须是上面两个类型之一

    NSString

    NSNumber

    NSData

    Boollean

     

    plist解析:

    NSArray arrayWithContentsOfFile

    NSDictionary dictionaryWithContentsOfFile

    plist的解析过程是

    plist(XML) <--> OC对象结构  互相转换

     

    对应关系:

    OC                        

    <Message order="">

    + fromMe               

    + content              

     

    MXL

    Message

    <formMe></formMe>

    <content></content>

     

    Plist

    formMe ->

    content ->

     

    读取plist中的数据

    - (void)viewDidLoad

    {

        [superviewDidLoad];

        // 读取plist数据

        NSMutableArray *arr = [NSMutableArrayarray];

        NSString *path = [[NSBundlemainBundle] pathForResource:@"messages"ofType:@"plist"];

        NSArray *array = [NSArrayarrayWithContentsOfFile:path];

        for (NSDictionary *dic in array) {

            MXMessage *message = [[MXMessagealloc] init];

            message.content = dic[@"content"];

            message.fromMe = [dic[@"fromMe"] boolValue];

            if ([dic[@"type"] isEqualToString:@"TXT"]) {

                message.type = MXMessageTypeText;

            }

            [arr addObject:message];

        }

        for (MXMessage *message in arr) {

            NSLog(@"%@",message.content);

        }

    }

     

    写入:

    writeToFile

    必须确保字典/数组内的所有对象均是plist支持的对象

     

    复杂对象树状结构用plist表达

            area

    代码如下:

    - (void)viewDidLoad

    {

        [superviewDidLoad];

                   // Do any additional setup after loading the view, typically from a nib.

        NSLog(@"%@",NSHomeDirectory());

        NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];

        NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"china.plist"];

        [[NSFileManagerdefaultManager] createFileAtPath:plistPath contents:Nilattributes:Nil];

        // 对象 -> 字典

        TRArea * puDong = [[TRAreaalloc] init];

        puDong.areaName = @"浦东";

        NSDictionary *dicPuDong = @{@"areaName": puDong.areaName};

       

        TRArea * shangHai = [[TRAreaalloc] init];

        shangHai.areaName = @"上海";

        shangHai.subAreas = @[dicPuDong];

        NSDictionary *dicShangHai = @{@"areaName": shangHai.areaName,

                                      @"subAreas": shangHai.subAreas};

       

        TRArea * china = [[TRAreaalloc] init];

        china.areaName = @"中国";

        china.subAreas = @[dicShangHai];

        NSDictionary *dicChina = @{@"areaName": china.areaName,

                                   @"subAreas": china.subAreas};

       

        [dicChina writeToFile:plistPath atomically:YES];

    }

     

    作业

        1.  TMessage  plist存储支持

        2.  TContact  plist存储支持(放document下)

              1) 定义一个plist文件格式

              2) 写解析代码

              3) 实现读取文件内容显示消息/联系人信息

             

              4)    支持保存

                  发新消息/建新对象

                  messages/contacts数组 转化成

                  plist支持的数组(数组结构 还要跟定义的结构一样)

     

     

     

     

  • 相关阅读:
    圈子
    限制我们的最大敌人不是自己,也不是思维,是时空。
    社交的本质就是生活!
    没有归零思维,就不会有突破
    什么是老板思维,什么是员工思维,深有体会,最近被N个行业洗脑……
    太相信书的人,格局不会太大
    在一个规则没有被建立好的时代,那些活生生的牛人,就是仅存的有效教科书
    个人发展阶段与回报对应表
    分布式,去中心化,协作性,可适应性
    [测试题]line
  • 原文地址:https://www.cnblogs.com/yangmx/p/3583094.html
Copyright © 2011-2022 走看看