iOS IM開發準備工作(一)XML解析,iosim

來源:互聯網
上載者:User

iOS IM開發準備工作(一)XML解析,iosim

  關於XML解析的blog有很多,我本來不想寫的;不過我發現有一些細節他們都沒有說,我這裡就多說一些細節。

  我們在哪些地方用XML:現在json用的這麼多,使用XML通訊的已經不多了。我遇到的情境是,我們的伺服器有很多個,需要使用者去選擇。那麼我們就需要定期維護一個伺服器列表,這個伺服器列表的設定檔我需要每次下載。自然我就需要解析這一個檔案。

  XML解析有兩種模式SAX和DOM。我用的是系統的 NSXMLParser 它是SAX解析。

  我寫了一個工具類,先貼一下代碼,下面會有一些說明

.h

 1 #import <Foundation/Foundation.h> 2  3 typedef NS_ENUM(NSInteger,xmlModelName){// 這裡我對我的XML檔案做了區別 因為要解析表情和伺服器列表兩種 4     xmlModelNameFace, 5     xmlModelNameServer, 6 }; 7 @interface XMLParser : NSObject<NSXMLParserDelegate> 8 // 這個是回調的Block 9 @property(nonatomic,copy)void (^returnParseArray)(NSArray * returnArray);10 @property(nonatomic,readonly)xmlModelName currentModelName;11 12 - (instancetype)initWithFilePath:(NSString *)path fileType:(NSString *)fileType modelName:(xmlModelName)modelName;13 14 - (void)startWithFilePath:(NSString *)path fileType:(NSString *)fileType;15 @end

.m

 1 #import "XMLParser.h" 2 #import "FaceModel.h" 3 #import "ToolClient.h" 4 #import "ServerModel.h" 5 @implementation XMLParser{ 6     NSMutableArray * faceArray; 7     NSMutableArray * serverArray; 8 } 9 10 @synthesize currentModelName;11 - (instancetype)initWithFilePath:(NSString *)path fileType:(NSString *)fileType modelName:(xmlModelName)modelName{12     self = [super init];13     if(self){14         currentModelName = modelName;15     }16     return self;17 }18 19 - (void)startWithFilePath:(NSString *)path fileType:(NSString *)fileType {20     [self parseWithPath:path type:fileType];21 }22 //23 - (void)parseWithPath:(NSString *)filePath type:(NSString *)fileType{24     if (currentModelName == xmlModelNameFace) {25         faceArray = [[NSMutableArray alloc]init];26     }else if(currentModelName == xmlModelNameServer){27         serverArray = [[NSMutableArray alloc]init];28     }29     NSData *xmlData = [[NSData alloc] initWithContentsOfFile:filePath];30     if(xmlData && xmlData.length > 10){31         NSXMLParser *parser = [[NSXMLParser alloc] initWithData:xmlData];32         [parser setShouldProcessNamespaces:NO];33         [parser setShouldReportNamespacePrefixes:NO];34         [parser setShouldResolveExternalEntities:NO];35         [parser setDelegate:self];36         BOOL success = [parser parse];37         if(success) {38             [self parseSuccess];39         }else {40             [ToolClient activityShowMessage:@"XML解析失敗" inView:[UIApplication sharedApplication].windows[0]];41         }42     }else {43         [ToolClient activityShowMessage:@"XML解析失敗" inView:[UIApplication sharedApplication].windows[0]];44     }45 }46 // 成功後的回調47 - (void)parseSuccess {48     if(self.returnParseArray){49         if (currentModelName == xmlModelNameFace) {50             self.returnParseArray(faceArray);51         }else if(currentModelName == xmlModelNameServer){52             self.returnParseArray(serverArray);53         }54     }55 }56 #pragma mark - NSXMLParserDelegate57 58 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName59   namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qualifiedName60     attributes:(NSDictionary *)attributeDict {61     //    NSLog(@"Name:%@",elementName);62     63     if([elementName isEqualToString:@"face"] && currentModelName == xmlModelNameFace) {64         FaceModel * faceModel = [[FaceModel alloc]init];65         faceModel.kID = [attributeDict[@"id"]intValue];66         faceModel.kName = attributeDict[@"name"];67         faceModel.kImage = attributeDict[@"file"];68         [faceArray  addObject:faceModel];69         faceModel = nil;70     }else if([elementName isEqualToString:@"Server"] && currentModelName == xmlModelNameServer){71         ServerModel * sModel = [[ServerModel alloc]init];72         sModel.serverName = attributeDict[@"name"];73         sModel.serverIP = attributeDict[@"ChatServerIP"];74         sModel.chatPort = attributeDict[@"chatPort"];75         sModel.fileServerIP = attributeDict[@"fileServerIP"];76         sModel.filePort = attributeDict[@"filePort"];77         [serverArray addObject:sModel];78         sModel = nil;79     }80 }81 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string  {82     //    NSLog(@"value:%@",string);83 }84 - (void)parserDidEndDocument:(NSXMLParser *)parser {85     //86     //    NSLog(@"%@",faceArray);87     88 }89 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{90     //    NSLog(@"elementName:%@",elementName);91     //    NSLog(@"qualifiedName:%@",qName);92     //93     //    NSLog(@"NSXMLParserDone");94     //    NSLog(@"%@",faceArray);95     //    NSLog(@"%i",(int)faceArray.count);96     97 }98 @end

現在我來說一下XML解析的設定裡面那3個設定為NO的參數是什麼作用

 1 [parser setShouldProcessNamespaces:NO]; 2 [parser setShouldReportNamespacePrefixes:NO]; 3 [parser setShouldResolveExternalEntities:NO]; 

  第一個 setShouldProcessNamespaces 這個屬性設定為YES的話,這兩個方法會有值輸出:parser:didStartElement:namespaceURI:qualifiedName:attributes: 和 parser:didEndElement:namespaceURI:qualifiedName: 這兩個在解析過程中都是都是可以看到裡面的節點或欄位的名字的。我覺得調試的時候可以用一下。

  第二個 setShouldReportNamespacePrefixes 這個屬性設定為YES的話,這兩個方法會有值輸出:parser:didStartMappingPrefix:toURI: 和 parser:didEndMappingPrefix: 這個我覺得完全沒有必要用它

  第三個 setShouldResolveExternalEntities 這個屬性設定為YES的話,這個方法會有值輸出:parser:foundExternalEntityDeclarationWithName:publicID:systemID: 其中publicID 和systemID 都是XML文檔的特有的標識。官方文檔對這個兩個的變數都是這麼說的:

You may access this property once a parsing operation has begun or after an error occurs.

也就是當XML解析已經開始或者出現錯誤的時候,再去看它。也就是說如果你的XML寫的夠好 你就忽略它吧。

  上面的代碼是工具類,下面這段會告訴你這段代碼怎麼用:

 1 // 解析檔案  2 - (void)parseFile:(NSString *)filepath{ 3     NSLog(@"filepath%@",filepath);// 檔案的路徑 4     if(data.length>10){// 簡單的長度檢測 5         __weak SelectServerViewController * ws = self;// 弱引用 6         // do parse 7         XMLParser * xp = [[XMLParser alloc]initWithFilePath:filepath fileType:@"xml" modelName:xmlModelNameServer]; 8         // 先設定回調 9         xp.returnParseArray = ^(NSArray * array){10             // 回調的結果 去給tableView 展示11             [ws gotDataArray:array];12         };13         // 再開始解析14         [xp startWithFilePath:filepath fileType:@"xml"];15     }16    17 }18 19 - (void)gotDataArray:(NSArray *)array {20     if(array){21 //        NSLog(@"array:%@",array);22         dataArray = [array mutableCopy];23         [myTableView reloadData];24     }25 }

XML解析我就寫這麼多了,給一個建議 解析的時候用一個Model來儲存資料,後續的使用會很方便。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.