申请博客有一段时间了,一直没有写些什么,今天写一下被遗忘的 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);

这种方式是很简便的把, 需要注意的是数据大的时候慎用,毕竟还是挺耗内存的..