• XML 解析的两种方法


      申请博客有一段时间了,一直没有写些什么,今天写一下被遗忘的 xml,因为 ios 现在一般都用 JSON,但毕竟还有一部分老一些的服务器还会有 xml 

      xml 格式的解析方式有两种 

        1.SAX解析: IOS 默认的解析方式,速度快,因为他是一行一行的读所以内存占用较小,只读. (因为一开始手机的内存是很小的,所以 ios 默认用 sax)

        SAX 逆序列化是苹果提供的类NSXMLParser  代码如下: 

          创建了一个 xml 叫 test

    <person><man ids="1"><name>ZhangSan</name><height>185</height></man><man ids="2"><name>LiSi</name><height>156</height></man></person>
    

           创建这个 xml 的模型类叫 testXMLModel 继承于 NSObject 在 .h 文件中定义属性

        

    1 @property (strong,nonatomic)NSNumber *ids;
    2 @property (copy,nonatomic)NSString *name;
    3 @property (copy,nonatomic)NSNumber *height;

          testXMLModel.m 文件中

    -(NSString *)description{
        return [NSString stringWithFormat:@"%@ {ids = %@,name = %@,height = %@}",[super description],self.ids,self.name,self.height];
    }
    // kvc 找不到对应 key 则不处理 - (void)setValue:(id)value forUndefinedKey:(NSString *)key { }

    我在 ViewController.m 中解析 代码如下

          

    #import "ViewController.h"
    #import "testXMLModel.h"
    
    @interface ViewController ()<NSXMLParserDelegate>
    // 集合
    @property (strong,nonatomic)NSMutableArray *manListArr;
    // 用于拼接字符串
    @property (copy,nonatomic)NSMutableString *currentString;
    // 模型对象
    @property (strong,nonatomic)testXMLModel *XMLModel;
    @end
    
    @implementation ViewController
    
    - (NSMutableArray *)manListArr {
        if (!_manListArr) {
            _manListArr = [NSMutableArray array];
        }
        return _manListArr;
    }
    
    - (NSMutableString *)currentString {
        if (!_currentString) {
            _currentString = [NSMutableString string];
        }
        return _currentString;
    }
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 获取 xml
        NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"test.xml" ofType:nil]];
        
        // 创建解析器
        NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
        
        // 设置代理
        parser.delegate = self;
        
        // 手动开启 parse
        [parser parse];
        
    
    
    }
    #pragma mark - 文档出错
    -(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
        NSLog(@"%@",parseError);
    }
    #pragma mark - 文档开始
    -(void)parserDidStartDocument:(NSXMLParser *)parser{
        NSLog(@"文档开始");
    }
    
    #pragma mark - 开始读取元素
    -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{
        
        if([elementName isEqualToString:@"man"]){
            //建立man对象
            self.XMLModel = [[testXMLModel alloc] init];
            // 获取 ids
            self.XMLModel.ids = @(attributeDict[@"ids"].intValue);
            
            // 添加到集合
            [self.manListArr addObject:self.XMLModel];
        }
    }
    
    #pragma mark - 文本
    // 多次解析
    -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
        // 拼接字符串
        [self.currentString appendString:string];
    }
    
    #pragma mark - 元素完成
    -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
        
        // KVC 赋值
        [self. XMLModel setValue:self.currentString forKey:elementName];
        
        // 每次赋值完成需要清空string
        self.currentString.string = @"";
        
    }
    #pragma mark - 文档结束
    -(void)parserDidEndDocument:(NSXMLParser *)parser{
        NSLog(@"文档结束");
        
        NSLog(@"%@",self.manListArr.copy );
    }
    

         

    解析完成

        2.DOM解析:mac 默认的解析方式, iOS是无法直接使用的,他是整个一起全部读出来所以解析过程中内存占用大,支持读写(现在手机的内存已不是当年可比,所以一般小的数据iOS 也可以用这种解析方式)

          由于 DOM 解析是IOS 无法直接使用的 所以我们要先导入第三方框架GDataXMLNode

          首先配置文件

    图好大 大家将就看 不好意思了 xml 和模型还用之前那两个

    ViewController 代码如下 

    #import "ViewController.h"
    #import "testXMLModel.h"
    #import "GDataXMLNode.h"
    
    @interface ViewController ()
    // 模型对象
    @property (strong,nonatomic)testXMLModel *XMLModel;
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        
        // 获取 xml
        NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"test.xml" ofType:nil]];
        
        //集合
        NSMutableArray *manListArr = [NSMutableArray array];
        //dom解析
        //1.加载文档
        GDataXMLDocument *documennt = [[GDataXMLDocument alloc] initWithData:data error:NULL];
        //根节点person
        GDataXMLElement *videosElement = documennt.rootElement;
        
        //要获取man
        for (GDataXMLElement *videoElement in videosElement.children) {
            
            testXMLModel *XMLModel = [[testXMLModel alloc] init];
            
            [manListArr addObject:XMLModel];
            
            //1.需要得到man的所有子标签
            for (GDataXMLElement *baseElement in videoElement.children) {
                //标签名字
                NSString *name = baseElement.name;
                NSString *value = baseElement.stringValue;
                //kvc
                [XMLModel setValue:value forKey:name];
            }
            
            //2.得到man的所有属性
            for (GDataXMLNode *attr in videoElement.attributes) {
                NSString *name = attr.name;
                NSString *value = attr.stringValue;
                //kvc
                [XMLModel setValue:value forKey:name];
            }
        }
        NSLog(@"%@",manListArr.copy);
    

    这种方式是很简便的把,  需要注意的是数据大的时候慎用,毕竟还是挺耗内存的..

  • 相关阅读:
    IDA断点和搜索
    shell grep正则匹配汉字
    吐槽一下jsoup
    mysql函数
    hutools之批量更新
    Hutools之http工具类
    Java通过腾讯邮箱发送邮件
    访问网络资源的方式--application/json和x-www-form-urlencoded
    HttpClient获取数据
    URLConnection类的使用
  • 原文地址:https://www.cnblogs.com/weijie-1/p/5143827.html
Copyright © 2020-2023  润新知