[iOS]XML两种解析方法

来源:互联网 发布:手机ping软件 编辑:程序博客网 时间:2024/06/05 22:56

XML的两种解析方法及区别:

 1.SAX 解析,逐行解析,(采用协议回调机制)速度慢 OC级别解析.

 2.DOM 解析,全体读,再分树形结构,C语言级别解析 ,是SAX解析的十几倍.

SAX 解析

解析方法

// 获取bundle包内xml 文件路径    NSString *bundle = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"xml"];    // 转换为二进制对象    NSData *data = [NSData dataWithContentsOfFile:bundle];    // 以二进制对象初始化    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];    parser.delegate = self;        //开始解析    [parser parse];    [parser release];
关于节点名称,最好定义为静态变量,这样后面用起来方便,而且不易写错

// 方便使用,不易写错static NSString *kRoot = @"root";static NSString *kStuArray = @"stu_array";static NSString *kStudent = @"student";static NSString *kName = @"name";static NSString *kAge = @"age";static NSString *kTel = @"tel";
遵循 NSXMLParserDelegate 协议,并且实现下面三个方法

- (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;



在开始解析方法里,我们要判断什么时候创建字典,以及什么时候创建model对象

#pragma mark - 开始解析- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{    // 判断什么时候创建字典    if ([elementName isEqualToString:kStuArray]) {        NSMutableDictionary *dic = [NSMutableDictionary dictionary];        // 取出 attributeDict 里的值,存入 dic 里面        [dic addEntriesFromDictionary:attributeDict];        // 创建存放学生的数组        NSMutableArray *stus = [NSMutableArray array];        [dic setObject:stus forKey:@"array"];                // dic 存入数组        [_stuArray addObject:dic];    }        // 判断什么时候创建学生对象    if ([elementName isEqualToString:kStudent]) {        StudentModel *stu = [[StudentModel alloc] init];        // 找到 学生对应的字典 里的数组        NSMutableDictionary *lastDic = [_stuArray lastObject];        NSMutableArray *lastArray = [lastDic objectForKey:@"array"];        [lastArray addObject:stu];        [stu release];    }

取值函数我们只要将获得的字符串存起来,以结束解析时,根据判断,来确定取出来的十model的哪一个属性值,
@interface SaxXmlParser : NSObject<NSXMLParserDelegate>{    NSMutableArray *_stuArray;    // 测试存值不能是成员变量,会崩溃!!!!!!!!!!!!!//    NSString *_currentValue;}// 测试存值设置为属性!!!!!!!!!!!!!@property (nonatomic,copy) NSString *currentValue;

这里要注意,接收字符串的变量,要定义为属性,不要定义为成员变量,定义为成员变量会崩溃

#pragma mark - 取值- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{    // 获取字符串,传给 结束解析函数,进行判断是哪一个属性    self.currentValue = string;    //    NSLog(@"解析中...");//    NSLog(@"\nparser == %@\nstring == %@",parser,string);}
解析结束方法里,判断取出来的字符串是model的哪一个属性

#pragma mark -结束解析- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{    // 判断取出来的是 student哪个属性    if ([elementName isEqualToString:kName]) {        NSMutableDictionary *dic = [_stuArray lastObject];        NSMutableArray *array = [dic objectForKey:@"array"];        StudentModel *stu = [array lastObject];        stu.name = _currentValue;    }        if ([elementName isEqualToString:kAge]) {        NSMutableDictionary *dic = [_stuArray lastObject];        NSMutableArray *array = [dic objectForKey:@"array"];        StudentModel *stu = [array lastObject];        stu.age = _currentValue;    }        if ([elementName isEqualToString:kTel]) {        NSMutableDictionary *dic = [_stuArray lastObject];        NSMutableArray *array = [dic objectForKey:@"array"];        StudentModel *stu = [array lastObject];        stu.tel = _currentValue;    }        // 判断解析完事    if ([elementName isEqualToString:kRoot]) {        NSLog(@"_stuArray == %@",_stuArray);        // 5.调用协议方法        [self.delegate sendArrayToMainView:_stuArray];    }    //    NSLog(@"结束解析");//    NSLog(@"\nparser == %@\nelementName == %@\nnamespaceURI == %@\nqName == %@",parser,elementName,namespaceURI,qName);}
至此,SAX解析完成。可以用协议传值,将获得的数组传给其他页面

DOM 解析

DOM解析的准备工作:

1.准备好GDataXMLNode 第三方类,这是Google写的

2.导入libxml2.dylib 类库

3.添加 Header Search Paths 如下图


#pragma mark DOM 解析- (void)domParser{    NSString *str = [[NSBundle mainBundle] pathForResource:@"Student" ofType:@"xml"];    NSData *data =[NSData dataWithContentsOfFile:str];        NSError *error = nil;    GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:data options:GDataXMLDocumentKind error:&error];    if (error) {        NSLog(@"error = %@",error);    }        // 获得根节点    GDataXMLElement *root = [doc rootElement];//    NSLog(@"\nroot == %@",root);    // 获取 节点名为 stu_list 的所有 节点数组    NSArray *array = [root elementsForName:@"stu_list"];//    NSLog(@"array = %@",array);        // // 获取 节点名为 stu_array 的所有 节点数组    GDataXMLElement *stu_list = [array firstObject];    NSArray *stuArray = [stu_list elementsForName:@"stu_array"];        // 获取数组里 节点    for (GDataXMLElement *stuA in stuArray) {        // 获得属性名为 name 的节点        GDataXMLNode *node = [stuA attributeForName:@"name"];        // 取节点所对应的内容        NSString *attStr = [node stringValue];                // 存入字典        NSMutableDictionary *dic = [NSMutableDictionary dictionary];        [dic setObject:attStr forKey:@"name"];                // 字典里存数组        NSMutableArray *array = [NSMutableArray array];        [dic setObject:array forKey:@"array"];                // 将字典存入大数组        [_stuArray addObject:dic];                // 获得节点名为 student 的所有节点        NSArray *students = [stuA elementsForName:@"student"];        // 遍历        for (GDataXMLElement *stu in students) {            // 创建model 添加到数组            StudentModel *model = [[StudentModel alloc] init];            [array addObject:model];                        // 获得所有student 子节点            NSArray *children = [stu children];            for (GDataXMLElement *child in children) {                // 取出节点的内容                NSString *childValue = [child stringValue];                                // 判断节点名                if ([[child name] isEqualToString:@"name"]) {                    model.name = childValue;                }                if ([[child name] isEqualToString:@"age"]) {                    model.age = childValue;                }                if ([[child name] isEqualToString:@"tel"]) {                    model.tel = childValue;                }            }        }    }}
一下是xml内数据结构

<root>    <stu_list>        <stu_array name = "A">            <student>                <name>小苹果</name>                <age>18</age>                <tel>120</tel>            </student>            <student>                <name>蓝翔</name>                <age>20</age>                <tel>110</tel>            </student>        </stu_array>                <stu_array name = "B">            <student>                <name>杀马特</name>                <age>19</age>                <tel>100</tel>            </student>            <student>                <name>土豆</name>                <age>20</age>                <tel>120</tel>            </student>        </stu_array>    </stu_list></root>


0 0
原创粉丝点击