zoukankan      html  css  js  c++  java
  • <转>iOS SDK中使用NSXMLParser解析XML

    转自  http://www.cnblogs.com/lovecode/articles/2305840.html

    iOS SDK的NSXMLParser解析XML文档是事件驱动模式的,即采用SAX方式来解析XML格式文档。NSXMLParser在处理XML文档的过程中当遇到一些要素(元素、属性、CDATA块、评论等)时会通知它的委托,而自身不对解析的要素进行任何处理,全权委托给NSXMLParserDelegate处理。同时它也会报告错误。
    1. 打开一个xml文件,读取内容到NSData中。

    NSString *path = [[NSBundle mainBundle] pathForResource:@"filename" ofType:@"xml"];
    NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path];
    NSData *data = [file readDataToEndOfFile];
    [file closeFile];

    2. 调用NSXMLParser的initWithData:方法,并设置代理delegate。

    复制代码
    NSXMLParser *m_parser = [[NSXMLParser alloc] initWithData:data];
    //设置该类本身为代理类,即该类在声明时要实现NSXMLParserDelegate委托协议
    [m_parser setDelegate:self]; //设置代理为本地

    BOOL flag = [m_parser parse]; //开始解析
    if(flag) {
    NSLog(@"获取指定路径的xml文件成功");
    }else{
    NSLog(@"获取指定路径的xml文件失败");
    }
    [m_parser release];
    复制代码

    当然还可以有其他初始化生成方法,如:

    NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:urlString]];

     直接自定义一个方法来实现创建解析:

    复制代码
     1 - (void)parseXMLFileAtURL:(NSURL *)URL parseError:(NSError **)error{
    2 NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:URL];
    3 [parser setDelegate:self];
    4 [parser setShouldProcessNamespaces:NO];
    5 [parser setShouldReportNamespacePrefixes:NO];
    6 [parser setShouldResolveExternalEntities:NO];
    7 [parser parse];
    8 NSError *parseError = [parser parserError];
    9 if (parseError && error) {
    10 *error = parseError;
    11 }
    12 [parser release];
    13 }
    复制代码

    3. 调用回调函数。
          当完成上面的parser初始化并执行parser语句时([parser parse]),程序就会跳到代理方法,调用回调函数didStartElement,该方法会将整个xml遍历一遍,并识别xml里面的元素名称(elementName),在发现要查找的信息时,创建一个如数组或其他变量以便在合适的时候存储这些信息。一般地,具体完成相关存储的操作往往在didEndElement回调函数中完成。

    //开始解析前,在这里可以做一些初始化工作
    // 假设已声明有实例变量 dataDict,parserObject
    - (void)parserDidStartDocument:(NSXMLParser *)parser {
    dataDict = [[NSMutableDictionary alloc] initWithCapacity:0]; //每一条信息都用字典来存储
    parserObjects = [[NSMutableArray alloc] init]; //每一组信息都用数组来存,最后得到的数据即在此数组中
    }
    复制代码
    //当解析器对象遇到xml的开始标记时,调用这个方法。
    //获得结点头的值
    //解析到一个开始tag,开始tag中可能会有properpies,例如<book catalog="Programming">
    //所有的属性都存储在attributeDict中
    - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict {
    if([elementName isEqualToString:@"book"]) {
    NSString *catalog = [attributeDict objectForKey:@"catalog"];
    }else if() {
    //......
    }
    }
    复制代码
    复制代码
    //当解析器找到开始标记和结束标记之间的字符时,调用这个方法。
    //解析器,从两个结点之间读取具体内容
    - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    //记录所取得的文字列
    }

    - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock{
    //NSLog(@"cData:%@",[NSString stringWithUTF8String:[CDATABlock bytes]]);
    }
    复制代码
    //当解析器对象遇到xml的结束标记时,调用这个方法。
    //获取结点结尾的值,此处为一Tag的完成
    - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

    }
    //xml解析结束后的一些操作可在此
    - (void)parserDidEndDocument:(NSXMLParser *)parser {
    //.....
    }


    有关我学习NSXMLPareser解析xml曾经产生的问题与解疑:

      •  类似如下XML文档结构,其分析是从imgList开始读取,而不是img表节点。不然就只读取一次,是不会循环的。
        <imgList><img><src>图片地址1</src><name>图片名称1</name><url>图片指定超链接1</url></img>
        <img><src>图片地址2</src><name>图片名称2</name><url>图片指定超链接2</url></img></imgList> 
      • 在根据xml文档结构组织相关实体类定义时的基本思路:把每个新节点容器都定义描述成一个新的实体类。
  • 相关阅读:
    libcurl进行HTTP GET获取JSON数据(转载)
    c/c++ 动态申请数组(转载)
    利用注册表写开机启动程序(转载)
    VC++使用IMAPI调用Outlook邮箱客户端和Foxmail邮箱客户端遇到的问题
    解决Duilib集成CEF浏览器在Win10无法向客户区拖拽文件
    解决往监控目录拖拽文件夹无法监控到的问题
    VC++ 实现修改文件创建、访问、修改时间属性(转载)
    Windows中的时间(SYSTEMTIME和FILETIME) (转载)
    ThinkPHP真正疑难问题笔记
    git版本控制管理实践-4
  • 原文地址:https://www.cnblogs.com/bucengyongyou/p/2799896.html
Copyright © 2011-2022 走看看