1 NSXMLParser解析简要说明
2 1.是sax方法解析
3 2.需要创建NSXMLParser实例 (alloc)
4 并创建解析器 (initWithData:)
5 为解析器定义委托 (setDelegate:)
6 运行解析器 (parser)
7 ++++++当parser初始化并执行parse语句时([parser parse]),程序会跳到代理方法里面走第一个代理方法++++++
8 3.这种解析方式是利用它的代理NSXMLParserDelegate实现的
9 第一个代理方法:开始处理xml数据,它会把整个xml遍历一遍,识别元素节点名称
10 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict;
11 第二个代理方法:也就是得到文本节点里存储的信息数据
12 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
13 第三个代理方法:存储从第二个代理方法中获取到的信息
14 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
15 这就是解析的过程,在这个过程中会不停的重复的执行这三个代理方法,直到遍历完成
16
17 另外:
18 解析开始执行的方法
19 - (void)parserDidStartDocument:(NSXMLParser *)parser;
20 解析结束执行的方法
21 - (void)parserDidEndDocument:(NSXMLParser *)parser;
22 当出现解析错误的时候,会执行这个方法
23 - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError;
1 /*
2 xml文件:
3 <?xml version="1.0" encoding="UTF-8"?>
4 <Student >
5 <dict id="1001">
6 <key>姓名</key>
7 <string>刘冠</string>
8 </dict>
9 <dict id="1002">
10 <key>姓名</key>
11 <string>李勇</string>
12 </dict>
13 </Student>
14 */
15 #import "ViewController.h"
16
17
18 @interface ViewController ()<NSXMLParserDelegate>
19 {
20 NSMutableArray *contents;
21 NSString *elementTag;
22 }
23 @end
24
25 @implementation ViewController
26
27 - (void)viewDidLoad {
28 [super viewDidLoad];
29 NSLog(@"%s",__FUNCTION__);//调用该方法时,打印该方法的名字
30 //解析当前工程文件
31 NSXMLParser *parserFile = [[NSXMLParser alloc] initWithData:[NSData dataWithContentsOfFile:[[NSBundle mainBundle]pathForResource:@"Student" ofType:@"xml"]]];
32
33 parserFile.delegate = self;
34 [parserFile parse];//开始解析
35 }
36 //开始解析xml文件,在解析节点前,可以在该方法中做一些初始化的工作,此方法只有开始解析时调用一次
37 -(void)parserDidStartDocument:(NSXMLParser *)parser{
38 NSLog(@"%s",__FUNCTION__);
39 //初始化数组,用于存储解析出来的数据
40 contents = [NSMutableArray array];
41 }
42
43 /*第一个代理方法与第二个代理方法会交替调用*/
44
45 //第一个代理方法(开始处理xml数据,它会把整个xml遍历一遍,识别元素开始节点名称 )注意:该方法不是一下就执行完了,它会携带者后面的两个方法进行具体的操作(通过NSLog(@"%s",__FUNCTION__);方法可以查看方法的调用)
46 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
47 {
48 NSLog(@"%s",__FUNCTION__);
49 // NSLog(@"parser = %@
",parser);
50 // NSLog(@"didStartElement = %@
",elementName);//是当前解析的标签名
51 // NSLog(@"namespaceURI = %@
",namespaceURI);
52 // NSLog(@"qualifiedName = %@
",qName);
53 // NSLog(@"attributes = %@
",attributeDict);//属性里边包含的值<Student version="1.0">
54 // NSLog(@"*****************");
55 elementTag = elementName;//用于后面的信息重建
56 //判断是否是<dict>节点
57 if([elementName isEqualToString:@"dict"])
58 {
59 //在<dict>节点的前提下提取属性节点<dict id="1002">
60 NSString *s = [attributeDict objectForKey:@"id"];//属性为区分同名节点而生(与节点绑定在一块)
61 NSMutableDictionary *dic = [NSMutableDictionary dictionary];
62 [dic setObject:s forKey:@"id"];
63 [contents addObject:dic];
64 }
65
66 }
67 //第二个代理方法(一般第一个和第三个代理方法执行后都会调用此方法),作用为查找标签伴随的特征 69 //<dict id="1001">
70 //<..>解析到此处(内容)<..>;或者<..> <..>;就是换行时也会调用(总之就是非标签处) 72 //</dict>
73 //解析器,从两个结点之间读取具体内容
74 -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
75 {
76 NSLog(@"%s",__FUNCTION__);
77 //该方法主要是解析元素文本的主要场所,由于换行符和回车符等特殊字符也会触发该方法,因此要判断并剔除换行符和回车符
78 //获取标签存储的字符串
79 if([elementTag isEqualToString:@"key"]||[elementTag isEqualToString:@"string"])
80 {
81 [[contents lastObject] setObject:string forKey:elementTag];
82 }
83 }
//第三个代理方法(遇到结束标签调用此方法),之后再去调用第二个代理方法(查找特征)所以此处要把elementTag置为nil
84 //解析标签结束</..>
85 -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
86 NSLog(@"%s",__FUNCTION__);
87 //解析头标签结束之后,将elementTag置空,避免尾标签对foundCharacters造成的影响
88 elementTag = nil;
89 }
90 //解析结束
91 -(void)parserDidEndDocument:(NSXMLParser *)parser{
92 //NSLog(@"--%@",listArr);
93 NSLog(@"%s",__FUNCTION__);
94 for (NSDictionary *dic in contents) {
95 NSLog(@"-->%@,%@,%@",[dic objectForKey:@"id"],dic[@"key"],dic[@"string"]);
96 }
97 }
98 //解析出错
99 -(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{
100 NSLog(@"%s",__FUNCTION__);
101 }
102
103 - (void)didReceiveMemoryWarning {
104 [super didReceiveMemoryWarning];
105 // Dispose of any resources that can be recreated.
106 }
107 /*
108 注意:
109 解析xml数据的时候,
110 每当遇到元素节点的时候都会执行第一个代理方法,如果有属性节点,可以直接在这个方法中获取里面的值;
111 每当遇到文本节点的时候都会执行第二个代理方法,获取文本节点中的值然后到第三个方法中进行区分。
112 如果是换行符的话也会获取,因为换行符也是文本节点,不过当一个元素节点结束后的换行符是不会获取的。
113 比如说: (换行符1)
114 <li>文本节点</li>
115 (换行符2)
116 元素节点前后各有一个换行符,这时只会获取换行符1,而不会获取换行符2。
117 */
118 //附件:方法执行顺序
119 /*
120 2015-12-04 22:08:28.742 解析[1597:188134] -[ViewController viewDidLoad]
121 2015-12-04 22:08:28.743 解析[1597:188134] -[ViewController parserDidStartDocument:]
122 2015-12-04 22:08:28.743 解析[1597:188134] -[ViewController parser:didStartElement:namespaceURI:qualifiedName:attributes:]
123 2015-12-04 22:08:28.743 解析[1597:188134] -[ViewController parser:foundCharacters:]
124 2015-12-04 22:08:28.743 解析[1597:188134] -[ViewController parser:didStartElement:namespaceURI:qualifiedName:attributes:]
125 2015-12-04 22:08:28.743 解析[1597:188134] -[ViewController parser:foundCharacters:]
126 2015-12-04 22:08:28.744 解析[1597:188134] -[ViewController parser:didStartElement:namespaceURI:qualifiedName:attributes:]
127 2015-12-04 22:08:28.744 解析[1597:188134] -[ViewController parser:foundCharacters:]
128 2015-12-04 22:08:28.744 解析[1597:188134] -[ViewController parser:didEndElement:namespaceURI:qualifiedName:]
129 2015-12-04 22:08:28.744 解析[1597:188134] -[ViewController parser:foundCharacters:]
130 2015-12-04 22:08:28.744 解析[1597:188134] -[ViewController parser:didStartElement:namespaceURI:qualifiedName:attributes:]
131 2015-12-04 22:08:28.744 解析[1597:188134] -[ViewController parser:foundCharacters:]
132 2015-12-04 22:08:28.744 解析[1597:188134] -[ViewController parser:didEndElement:namespaceURI:qualifiedName:]
133 2015-12-04 22:08:28.745 解析[1597:188134] -[ViewController parser:foundCharacters:]
134 2015-12-04 22:08:28.745 解析[1597:188134] -[ViewController parser:didEndElement:namespaceURI:qualifiedName:]
135 2015-12-04 22:08:28.745 解析[1597:188134] -[ViewController parser:foundCharacters:]
136 2015-12-04 22:08:28.745 解析[1597:188134] -[ViewController parser:didStartElement:namespaceURI:qualifiedName:attributes:]
137 2015-12-04 22:08:28.745 解析[1597:188134] -[ViewController parser:foundCharacters:]
138 2015-12-04 22:08:28.745 解析[1597:188134] -[ViewController parser:didStartElement:namespaceURI:qualifiedName:attributes:]
139 2015-12-04 22:08:28.745 解析[1597:188134] -[ViewController parser:foundCharacters:]
140 2015-12-04 22:08:28.746 解析[1597:188134] -[ViewController parser:didEndElement:namespaceURI:qualifiedName:]
141 2015-12-04 22:08:28.746 解析[1597:188134] -[ViewController parser:foundCharacters:]
142 2015-12-04 22:08:28.746 解析[1597:188134] -[ViewController parser:didStartElement:namespaceURI:qualifiedName:attributes:]
143 2015-12-04 22:08:28.746 解析[1597:188134] -[ViewController parser:foundCharacters:]
144 2015-12-04 22:08:28.746 解析[1597:188134] -[ViewController parser:didEndElement:namespaceURI:qualifiedName:]
145 2015-12-04 22:08:28.746 解析[1597:188134] -[ViewController parser:foundCharacters:]
146 2015-12-04 22:08:28.746 解析[1597:188134] -[ViewController parser:didEndElement:namespaceURI:qualifiedName:]
147 2015-12-04 22:08:28.747 解析[1597:188134] -[ViewController parser:foundCharacters:]
148 2015-12-04 22:08:28.747 解析[1597:188134] -[ViewController parser:didEndElement:namespaceURI:qualifiedName:]
149 2015-12-04 22:08:28.747 解析[1597:188134] -[ViewController parserDidEndDocument:]
150 */
151 @end