申请博客有一段时间了,一直没有写些什么,今天写一下被遗忘的 xml,因为 ios 现在一般都用 JSON,但毕竟还有一部分老一些的服务器还会有 xml
xml 格式的解析方式有两种
1.SAX解析: IOS 默认的解析方式,速度快,因为他是一行一行的读所以内存占用较小,只读. (因为一开始手机的内存是很小的,所以 ios 默认用 sax)
SAX 逆序列化是苹果提供的类NSXMLParser 代码如下:
创建了一个 xml 叫 test
<person><man ids="1"><name>ZhangSan</name><height>185</height></man><man ids="2"><name>LiSi</name><height>156</height></man></person>
创建这个 xml 的模型类叫 testXMLModel 继承于 NSObject 在 .h 文件中定义属性
1 @property (strong,nonatomic)NSNumber *ids; 2 @property (copy,nonatomic)NSString *name; 3 @property (copy,nonatomic)NSNumber *height;
testXMLModel.m 文件中
-(NSString *)description{ return [NSString stringWithFormat:@"%@ {ids = %@,name = %@,height = %@}",[super description],self.ids,self.name,self.height]; }
// kvc 找不到对应 key 则不处理 - (void)setValue:(id)value forUndefinedKey:(NSString *)key { }
我在 ViewController.m 中解析 代码如下
#import "ViewController.h" #import "testXMLModel.h" @interface ViewController ()<NSXMLParserDelegate> // 集合 @property (strong,nonatomic)NSMutableArray *manListArr; // 用于拼接字符串 @property (copy,nonatomic)NSMutableString *currentString; // 模型对象 @property (strong,nonatomic)testXMLModel *XMLModel; @end @implementation ViewController - (NSMutableArray *)manListArr { if (!_manListArr) { _manListArr = [NSMutableArray array]; } return _manListArr; } - (NSMutableString *)currentString { if (!_currentString) { _currentString = [NSMutableString string]; } return _currentString; } - (void)viewDidLoad { [super viewDidLoad]; // 获取 xml NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"test.xml" ofType:nil]]; // 创建解析器 NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; // 设置代理 parser.delegate = self; // 手动开启 parse [parser parse]; } #pragma mark - 文档出错 -(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{ NSLog(@"%@",parseError); } #pragma mark - 文档开始 -(void)parserDidStartDocument:(NSXMLParser *)parser{ NSLog(@"文档开始"); } #pragma mark - 开始读取元素 -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{ if([elementName isEqualToString:@"man"]){ //建立man对象 self.XMLModel = [[testXMLModel alloc] init]; // 获取 ids self.XMLModel.ids = @(attributeDict[@"ids"].intValue); // 添加到集合 [self.manListArr addObject:self.XMLModel]; } } #pragma mark - 文本 // 多次解析 -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ // 拼接字符串 [self.currentString appendString:string]; } #pragma mark - 元素完成 -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{ // KVC 赋值 [self. XMLModel setValue:self.currentString forKey:elementName]; // 每次赋值完成需要清空string self.currentString.string = @""; } #pragma mark - 文档结束 -(void)parserDidEndDocument:(NSXMLParser *)parser{ NSLog(@"文档结束"); NSLog(@"%@",self.manListArr.copy ); }
解析完成
2.DOM解析:mac 默认的解析方式, iOS是无法直接使用的,他是整个一起全部读出来所以解析过程中内存占用大,支持读写(现在手机的内存已不是当年可比,所以一般小的数据iOS 也可以用这种解析方式)
由于 DOM 解析是IOS 无法直接使用的 所以我们要先导入第三方框架GDataXMLNode
首先配置文件
图好大 大家将就看 不好意思了 xml 和模型还用之前那两个
ViewController 代码如下
#import "ViewController.h" #import "testXMLModel.h" #import "GDataXMLNode.h" @interface ViewController () // 模型对象 @property (strong,nonatomic)testXMLModel *XMLModel; @end @implementation ViewController - (void)viewDidLoad { [super viewDidLoad]; // 获取 xml NSData *data = [NSData dataWithContentsOfFile:[[NSBundle mainBundle] pathForResource:@"test.xml" ofType:nil]]; //集合 NSMutableArray *manListArr = [NSMutableArray array]; //dom解析 //1.加载文档 GDataXMLDocument *documennt = [[GDataXMLDocument alloc] initWithData:data error:NULL]; //根节点person GDataXMLElement *videosElement = documennt.rootElement; //要获取man for (GDataXMLElement *videoElement in videosElement.children) { testXMLModel *XMLModel = [[testXMLModel alloc] init]; [manListArr addObject:XMLModel]; //1.需要得到man的所有子标签 for (GDataXMLElement *baseElement in videoElement.children) { //标签名字 NSString *name = baseElement.name; NSString *value = baseElement.stringValue; //kvc [XMLModel setValue:value forKey:name]; } //2.得到man的所有属性 for (GDataXMLNode *attr in videoElement.attributes) { NSString *name = attr.name; NSString *value = attr.stringValue; //kvc [XMLModel setValue:value forKey:name]; } } NSLog(@"%@",manListArr.copy);
这种方式是很简便的把, 需要注意的是数据大的时候慎用,毕竟还是挺耗内存的..