现在的位置: 首页 > 综合 > 正文

IOS成长之路-用NSXMLParser实现XML解析

2012年10月18日 ⁄ 综合 ⁄ 共 3413字 ⁄ 字号 评论关闭

再次对xml进行解析,又有了些理解,如果有不对的地方,请给小弟指出,谢谢!

<?xml version="1.0" encoding="UTF-8"?>
<result>
    <meeting addr="203">
        <creator>张一</creator>
        <member>
            <name>张二</name>
            <age>20</age>
        </member>
        <member>
            <name>张三</name>
            <age>21</age>
        </member>
        <member>
            <name>张四</name>
            <age>22</age>
        </member>
    </meeting>
	
    <meeting addr="204">
        <creator>李一</creator>
        <member>
            <name>李二</name>
            <age>20</age>
        </member>
        <member>
            <name>李三</name>
            <age>21</age>
        </member>
        <member>
            <name>李四</name>
            <age>22</age>
        </member>
    </meeting>
</result>

1.获取xml文件中的数据:存放到字符串中

//bundle是一个目录,包含了程序会使用到的资源
    NSString *path=[[NSBundle mainBundle] pathForResource:@"test" ofType:@"xml"];
    NSString *_xmlContent=[[NSString alloc] initWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];

用NSXMLParser实现解析:

NSXMLParser解析简要说明
         1.是sax方法解析
         2.需要创建NSXMLParser实例 (alloc)
               并创建解析器 (initWithData:)
                  为解析器定义委托 (setDelegate:)
                      运行解析器 (parser)
         ++++++当parser初始化并执行parse语句时([parser parse]),程序会跳到代理方法里面走第一个代理方法++++++
         3.这种解析方式是利用它的代理NSXMLParserDelegate实现的
         第一个代理方法:开始处理xml数据,它会把整个xml遍历一遍,识别元素节点名称
         - (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
         这就是解析的过程,在这个过程中会不停的重复的执行这三个代理方法,直到遍历完成
         
         另外:
             解析开始执行的方法
         - (void)parserDidStartDocument:(NSXMLParser *)parser;
             解析结束执行的方法
         - (void)parserDidEndDocument:(NSXMLParser *)parser;
             当出现解析错误的时候,会执行这个方法
         - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError;

解析开始:

2.准备工作:

NSXMLParser *parse=[[NSXMLParser alloc] initWithData:[_xmlContent dataUsingEncoding:NSUTF8StringEncoding]];
        [parse setDelegate:self];
        [parse parse];
        [parse release];

3.三个代理方法具体实现:

//第一个代理方法:
- (void) parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName attributes:(NSDictionary *)attributeDict 
{
    //判断是否是meeting
	if ([elementName isEqualToString:@"meeting"]) {
        //判断属性节点
        if ([attributeDict objectForKey:@"addr"]) {
            //获取属性节点中的值
            NSString *addr=[attributeDict objectForKey:@"addr"];
        }
	}
    //判断member
    if ([elementName isEqualToString:@"member"]) {
        NSLog(@"member"]);
    }
}

//第二个代理方法:
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 
{
    //获取文本节点中的数据,因为下面的方法要保存这里获取的数据,所以要定义一个全局变量(可修改的字符串)
    //NSMutableString *element = [[NSMutableString alloc]init];
    //这里要赋值为空,目的是为了清空上一次的赋值
    [element setString:@""];
    [element appendString:string];//string是获取到的文本节点的值,只要是文本节点都会获取(包括换行),然后到下个方法中进行判断区分
}

//第三个代理方法:
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName
namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    
    NSString *str=[[NSString alloc] initWithString:element];
    
	if ([elementName isEqualToString:@"creator"]) {
        NSLog(@"creator=%@",str);
    }
    if ([elementName isEqualToString:@"name"]) {
        NSLog(@"name=%@",str);
    }
    if ([elementName isEqualToString:@"age"]) {
        NSLog(@"age=%@",str);
    }
    [str release];
}

注意:

解析xml数据的时候,

                 每当遇到元素节点的时候都会执行第一个代理方法,如果有属性节点,可以直接在这个方法中获取里面的值;

              
  每当遇到文本节点的时候都会执行第二个代理方法,获取文本节点中的值然后到第三个方法中进行区分。

                          如果是换行符的话也会获取,因为换行符也是文本节点,不过当一个元素节点结束后的换行符是不会获取的。

   比如说:      (换行符1)

                                                  <li>文本节点</li>

                                                  (换行符2)

             
元素节点前后各有一个换行符,这时只会获取换行符1,而不会获取换行符2。

4.处理错误:打印错误

- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
    NSLog(@"%@",[parseError description]);
}

抱歉!评论已关闭.