iOS XML转字典
2016-06-01 00:00
555 查看
#import <Foundation/Foundation.h> enum { XMLReaderOptionsProcessNamespaces = 1 << 0, // Specifies whether the receiver reports the namespace and the qualified name of an element. XMLReaderOptionsReportNamespacePrefixes = 1 << 1, // Specifies whether the receiver reports the scope of namespace declarations. XMLReaderOptionsResolveExternalEntities = 1 << 2, // Specifies whether the receiver reports declarations of external entities. }; typedef NSUInteger XMLReaderOptions; @interface XMLReader : NSObject <NSXMLParserDelegate> + (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)errorPointer; + (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)errorPointer; + (NSDictionary *)dictionaryForXMLData:(NSData *)data options:(XMLReaderOptions)options error:(NSError **)errorPointer; + (NSDictionary *)dictionaryForXMLString:(NSString *)string options:(XMLReaderOptions)options error:(NSError **)errorPointer; @end #import "XMLReader.h" #if !defined(__has_feature) || !__has_feature(objc_arc) #error "XMLReader requires ARC support." #endif NSString *const kXMLReaderTextNodeKey = @"text"; NSString *const kXMLReaderAttributePrefix = @"@"; @interface XMLReader () @property (nonatomic, strong) NSMutableArray *dictionaryStack; @property (nonatomic, strong) NSMutableString *textInProgress; @property (nonatomic, strong) NSError *errorPointer; @end @implementation XMLReader #pragma mark - Public methods + (NSDictionary *)dictionaryForXMLData:(NSData *)data error:(NSError **)error { XMLReader *reader = [[XMLReader alloc] initWithError:error]; NSDictionary *rootDictionary = [reader objectWithData:data options:0]; return rootDictionary; } + (NSDictionary *)dictionaryForXMLString:(NSString *)string error:(NSError **)error { NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; return [XMLReader dictionaryForXMLData:data error:error]; } + (NSDictionary *)dictionaryForXMLData:(NSData *)data options:(XMLReaderOptions)options error:(NSError **)error { XMLReader *reader = [[XMLReader alloc] initWithError:error]; NSDictionary *rootDictionary = [reader objectWithData:data options:options]; return rootDictionary; } + (NSDictionary *)dictionaryForXMLString:(NSString *)string options:(XMLReaderOptions)options error:(NSError **)error { NSData *data = [string dataUsingEncoding:NSUTF8StringEncoding]; return [XMLReader dictionaryForXMLData:data options:options error:error]; } #pragma mark - Parsing - (id)initWithError:(NSError **)error { self = [super init]; if (self) { self.errorPointer = *error; } return self; } - (NSDictionary *)objectWithData:(NSData *)data options:(XMLReaderOptions)options { // Clear out any old data self.dictionaryStack = [[NSMutableArray alloc] init]; self.textInProgress = [[NSMutableString alloc] init]; // Initialize the stack with a fresh dictionary [self.dictionaryStack addObject:[NSMutableDictionary dictionary]]; // Parse the XML NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; [parser setShouldProcessNamespaces:(options & XMLReaderOptionsProcessNamespaces)]; [parser setShouldReportNamespacePrefixes:(options & XMLReaderOptionsReportNamespacePrefixes)]; [parser setShouldResolveExternalEntities:(options & XMLReaderOptionsResolveExternalEntities)]; parser.delegate = self; BOOL success = [parser parse]; // Return the stack's root dictionary on success if (success) { NSDictionary *resultDict = [self.dictionaryStack objectAtIndex:0]; return resultDict; } return nil; } #pragma mark - NSXMLParserDelegate methods - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { // Get the dictionary for the current level in the stack NSMutableDictionary *parentDict = [self.dictionaryStack lastObject]; // Create the child dictionary for the new element, and initilaize it with the attributes NSMutableDictionary *childDict = [NSMutableDictionary dictionary]; [childDict addEntriesFromDictionary:attributeDict]; // If there's already an item for this key, it means we need to create an array id existingValue = [parentDict objectForKey:elementName]; if (existingValue) { NSMutableArray *array = nil; if ([existingValue isKindOfClass:[NSMutableArray class]]) { // The array exists, so use it array = (NSMutableArray *) existingValue; } else { // Create an array if it doesn't exist array = [NSMutableArray array]; [array addObject:existingValue]; // Replace the child dictionary with an array of children dictionaries [parentDict setObject:array forKey:elementName]; } // Add the new child dictionary to the array [array addObject:childDict]; } else { // No existing value, so update the dictionary [parentDict setObject:childDict forKey:elementName]; } // Update the stack [self.dictionaryStack addObject:childDict]; } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { // Update the parent dict with text info NSMutableDictionary *dictInProgress = [self.dictionaryStack lastObject]; // Set the text property if ([self.textInProgress length] > 0) { // trim after concatenating NSString *trimmedString = [self.textInProgress stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]; [dictInProgress setObject:[trimmedString mutableCopy] forKey:kXMLReaderTextNodeKey]; // Reset the text self.textInProgress = [[NSMutableString alloc] init]; } // Pop the current dict [self.dictionaryStack removeLastObject]; } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { // Build the text value [self.textInProgress appendString:string]; } - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { // Set the error pointer to the parser's error object self.errorPointer = parseError; } @end
相关文章推荐
- iOS MD5加密代码
- iOS 开发中关于支付功能的学习心得 ----支付宝
- iOS中简单的浏览器
- IOS iPhone开发中发送e-mail的3种方式
- iOS 图形锁屏demo
- iOS开发探索-多线程(NSThread、NSOperation、GCD)编程浅谈
- 左右侧滑动-----第三方库JASidePanelController使用介绍
- ios练习——加法计算器
- iOS block传值(逆传)
- iOS开发中获取短信验证码倒计时按钮的实现
- iOS-静态库(2)
- iOS之苹果和百度地图的使用
- iOS设置模拟器的经纬度
- ios 测试环境证书 收不到通知栏的APNS消息
- iOS开发笔记(一)
- 多控制器管理
- iOS开发时,用charles配置环境
- iOS 【如何在perfromSelector后面拼接更多参数】
- [iOS] 如何自定义CollectionView中每个元素的大小和间距
- iOS应用内支付(IAP)的那些坑