iOS开发之XML解析

来源:互联网 发布:英国 博士 知乎 编辑:程序博客网 时间:2024/05/21 06:43

本文利用苹果自带的、基于SAX的解析器:NSXMLParser和基于libxml2的DOM方式的GDataXML解析本地XML文件。前者也就是所谓的“事件驱动”的解析器。

新建项目,向项目中添加一个.xml文件,如下xml文件:

<books>    <book id = "1">        <title>西游记</title>        <author>吴承恩</author>        <remark>孙悟空</remark>    </book>    <book id = "2">        <title>红楼梦</title>        <author>曹雪芹</author>        <remark>林黛玉</remark>    </book>    <book id = "3">        <title>水浒传</title>        <author>施耐庵</author>        <remark>林冲</remark>    </book>    <book id = "4">        <title>三国演义</title>        <author>罗贯中</author>        <remark>曹操</remark>    </book></books>

在控制器.m文件中提前声明两个变量:

HXBook *book;// 模型

NSString*currentString;// 当前解析到的元素之间的字符内容

在控制器view加载完毕后,加载xml文件,并利用xml文件创建NSXMLParser对象设置代理,再调用NSXMLParser对象的parse方法开始解析。如下:

- (void)viewDidLoad {    [super viewDidLoad];    //    NSURL *pathURL = [[NSBundle mainBundle] URLForResource:@"text" withExtension:@"xml"];    NSString *path = [[NSBundle mainBundle] pathForResource:@"text.xml" ofType:nil];    NSData *data = [NSData dataWithContentsOfFile:path];        // 根据xml文件创建NSXMLParser对象//    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:pathURL];    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];        // 设置代理    parser.delegate = self;        // 开始解析(SAX解析)    [parser parse];}#pragma mark NSXMLParserDelegate/** *  当扫描到文档的开始时调用(开始解析) */- (void)parserDidStartDocument:(NSXMLParser *)parser {    NSLog(@"开始解析");}/** *  当扫描到文档的结尾时调用(结束解析) */- (void)parserDidEndDocument:(NSXMLParser *)parser {    NSLog(@"结束解析");        for (HXBook *b in self.books) {        NSLog(@"书:%@", b.remark);    }}/** *  当扫描到一个元素的开始时候调用(attributeDict存放着元unsude属性) */- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict {    NSLog(@"开始处理元素:%@", elementName);        if ([elementName isEqualToString:@"book"]) {        // 创建模型        book = [[HXBook alloc] init];        book.ID = [[attributeDict objectForKey:@"id"] integerValue];    }        }/** *  解析到元素间的字符内容时调用 */- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {        NSLog(@"处理的字符内容:%@", string);    // 如果当前字符内容不为nil,则保存当前字符内容    if (string) {        currentString = string;    }    }/** *  当扫描到一个元素的结尾时候调用 */- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {    NSLog(@"结束处理元素:%@", elementName);    if ([elementName isEqualToString:@"book"]) {                // 添加模型到模型数组中        [self.books addObject:book];        // 重置book        book = nil;            }else {// 解析的不是<books.../>也不是<book.../>元素        // 利用KVC方式为当前HXBook对象的属性赋值        [book setValue:currentString forKey:elementName];  // 重置currentString        currentString = nil;    }}

运行后,parser开始解析,打印如下:

下面介绍是用基于DOM方式的GDataXML解析XML文件。先根据这篇文章配置好环境。将GDataXMLNode.h和GDataXMLNode.m文件拖进项目中。

代码如下:

- (void)testGDataXML {    // 获取XML文件路径    NSString *path = [[NSBundle mainBundle] pathForResource:@"text.xml" ofType:nil];    NSString *xmlString = [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];    // 根据XML文件路径加载XML文件    GDataXMLDocument *xmlDocu = [[GDataXMLDocument alloc] initWithXMLString:xmlString options:0 error:nil];        // 根据XML文件,获取XML文件中的根元素    GDataXMLElement *xmlEle = [xmlDocu rootElement];        // 在根据主元素,获取其下面的所有直接子元素    NSArray *array = [xmlEle children];    NSLog(@"array.count = %lu", (unsigned long)array.count);        // 遍历所有子元素    for (int i = 0; i < array.count; i ++) {        // 获取对应索引的子元素        GDataXMLElement *element = [array objectAtIndex:i];                // 根据元素判断        if ([[element name] isEqualToString:@"book"]) {                        // 创建模型            book = [[HXBook alloc] init];                        //取出元素中属性值            NSString *IDString = [[element attributeForName:@"id"] stringValue];            book.ID = [IDString integerValue];                        // 获取"book"下的所有直接子元素            NSArray *childs = [element children];            for (int j = 0; j < childs.count; j ++) {                GDataXMLElement *chilE = [childs objectAtIndex:j];                if ([[chilE name] isEqualToString:@"title"]) {                    // 书名                    NSString *title = [chilE stringValue];                    book.title = title;                                    }else if ([[chilE name] isEqualToString:@"author"]) {                    // 作者                    NSString *author = [chilE stringValue];                    book.author = author;                                    }else {                    // 人物                    NSString *remark = [chilE stringValue];                    book.remark = remark;                }            }            [self.books addObject:book];            book = nil;        }    }    // 转换模型完毕后    for (HXBook *b in self.books) {        NSLog(@"书:%@", b.remark);    }}
运行结果:


GDataXML是利用根元素的直接子元素来获取内容的。根元素和子元素是相对的。

两种解析XML的方法就介绍到这里。




0 0