網絡數據解析

XML文件寫法

<Classes>//根節(jié)點
  <Class1>//開始標簽
    <Students>
      <Student position = "CEO">//"CEO"節(jié)點屬性
       //節(jié)點屬性
        <name>hmx</name>
        <age>23</age>
        <height>160</height>
      <Student>
        <name>xiaoming</name>
        <age>24</age>
        <height>170</height>
      </Student>
    </Students>
  </Class1>
</Classes>

XML解析

SAX:逐行解析(主類:NSXMLParser)

逐行解析顧名思義就是一行一行的讀取解析,需要遵循代理<NSXMLParserDelegate>

SAX一般分為5步
1.開始解析
- (void)parserDidStartDocument:(NSXMLParser *)parser;
2.開始解析標簽
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict;
3.標簽對應的值
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string;
4.結束解析標簽
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName;
5.結束解析
- (void)parserDidEndDocument:(NSXMLParser *)parser;
以上面的Student為例子

1.創(chuàng)建一個Student的model類

//Student的model類h文件
#import <Foundation/Foundation.h>
@interface Student : NSObject
@property (nonatomic, strong) NSString *name;
@property (nonatomic, assign) NSInteger age;
@property (nonatomic, assign) float height;
@end

2.定義一個全局變量數組用來存儲解析后的數據,定義一個全局變量用來存儲標簽,因為我們要通過標簽來判斷數據

@property (nonatomic, strong) NSMutableArray *studentArray;
@property (nonatomic, strong) NSString *currentElementName;

3.這里使用一個UIbutton動作來進行解析,點擊button就進行XML解析,UIButton創(chuàng)建不在多說

//點擊按鈕進行解析
- (IBAction)SAXDidTapAction:(UIButton *)sender {
    //獲取文件絕對路徑
    NSString *path = [[NSBundle mainBundle] pathForResource:@"student" ofType:@"txt"];
    //創(chuàng)建一個NSData
    NSData *data = [NSData dataWithContentsOfFile:path];
    //初始化XMLParser
    NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:data];
    
    xmlParser.delegate = self;
    [xmlParser parse];
}

4.遵循協議,重寫方法,記得數組需要先初始化

//開始解析
- (void)parserDidStartDocument:(NSXMLParser *)parser {
    NSLog(@"DidStart");
}
//解析開始元素(標簽)
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict {
    //記錄當前elementName
    self.currentElementName = elementName;
//創(chuàng)建學生屬性并添加到數組中
    if ([elementName isEqualToString:@"Student"]) {
        Student *student = [[Student alloc] init];
        [self.studentArray addObject:student];
    }
}
//每一個標簽對應的值
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {
    //獲取最后一個元素
    Student *stu = [self.studentArray lastObject];
    //KVC模式賦值,記得在Student類中重寫方法
//- (void)setValue:(id)value forUndefinedKey:(NSString *)key;
    [stu setValue:string forKey:self.currentElementName];
}
//解析結束標簽
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
 //這里設置為空的原因: foundCharacters方法在結束標簽處會調用一次,
//不置為空會再次進入KVC賦值,Student內容會變?yōu)榭栈?
    self.currentElementName = @"";
}
//結束解析
- (void)parserDidEndDocument:(NSXMLParser *)parser {
    NSLog(@"DidEnd");
    for (Student *stu in self.studentArray) {
        NSLog(@"%@", stu);
    }
}

DOM解析:通過GDataXMLNode類進行解析,該類會將數據全部解析完畢,在使用前先做一些處理

1.將文件添加到工程(http://pan.baidu.com/s/1eSrvPgY)
2.在工程中添加動態(tài)庫: libxml2.dylib
3.在工程的Build Settings中找到Header Search Path項 添加/usr/include/libxml2
4.將第三方庫文件改為ARC MRC通用狀態(tài),找到Build Phases中的Compile Sources中的GDataXMLNode.m文件雙擊添加-fno-objc-arc

程序

  1. 初始化GDataXMLDocument
//data為路徑,解析例子同SAX, data為SAX中的data
GDataXMLDocument *GDocument = [[GDataXMLDocument alloc] initWithData:data options:0 error:&error];
  1. 獲取根節(jié)點
GDataXMLElement *rootElement = GDocument.rootElement;
  1. 獲取子節(jié)點
for (GDataXMLElement *subElement in rootElement.children) {
        Student *stu = [[Student alloc] init];
        //找到student的子節(jié)點, 也就是name age height,然后賦值
        for (GDataXMLElement *contactElement in subElement.children) {
            [stu setValue:contactElement.stringValue forKey:contactElement.name];
        }
        [self.studentArray addObject:stu];
    }

通過XMLDictionary類進行解析

NSDictionary *dict = [NSDictionary dictionaryWithXMLData:data];
    
    NSArray *array = dict[@"Student"];
    
    for (NSDictionary *stuDict in array) {
        Student *stu = [[Student alloc] init];
        [stu setValuesForKeysWithDictionary:stuDict];
        
        [self.studentArray addObject:stu];
    }

上面的均為簡單的例子,下面來看一個比較復雜的例子,這里使用XMLDictionary類進行解析: Cartoon.xml進行解析

這里我們只需要兩個數據,name跟desc

  1. 創(chuàng)建Model類
    Model.h
@interface CartoonModel : NSObject

@property (nonatomic, strong) NSString *name;
@property (nonatomic, strong) NSString *desc;

@end

Model.m

#import "CartoonModel.h"

@implementation CartoonModel
//當沒有找到key時會進入這個方法
- (void)setValue:(id)value forUndefinedKey:(NSString *)key {
    
}
@end
  1. 數據解析
//這里使用懶加載方法,cartoonArray為全局變量(NSMutableArray)
- (NSMutableArray *)cartoonArray {
    if (!_cartoonArray) {
        _cartoonArray = [[NSMutableArray alloc] init];
        //獲取絕對路徑
        NSString *path = [[NSBundle mainBundle] pathForResource:@"Cartoon" ofType:@"xml"];
        NSData *data = [NSData dataWithContentsOfFile:path];
        //使用方法dictionaryWithXMLData將數據轉換為字典
        NSDictionary *dict = [NSDictionary dictionaryWithXMLData:data];
        //通過字典的key獲取下級字典
        NSDictionary *resultDict = dict[@"results"];
        //通過數組接收數據
        NSArray *albumInfoDict = resultDict[@"AlbumInfo"];
        //通過model類接收數組內部的各個model數據
        for (NSDictionary *modelDict in albumInfoDict) {
            CartoonModel *model = [[CartoonModel alloc] init];
            //KVC模式賦值
            [model setValuesForKeysWithDictionary:modelDict];
            [_cartoonArray addObject:model];
        }
    }
    return _cartoonArray;
}
最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
【社區(qū)內容提示】社區(qū)部分內容疑似由AI輔助生成,瀏覽時請結合常識與多方信息審慎甄別。
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發(fā)布,文章內容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務。

相關閱讀更多精彩內容

友情鏈接更多精彩內容