再次对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]); }