再次對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 { //判斷是否是meetingif ([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 *)elementNamenamespaceURI:(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]);}