今天來介紹一下XML數(shù)據(jù)解析的基礎(chǔ)內(nèi)容
通俗的來講 所謂XML數(shù)據(jù)解析就是將帶有標(biāo)簽樣式的數(shù)據(jù) 利用XML解析方法將數(shù)據(jù)解析成為賦值給model的數(shù)據(jù)
我所了解的XML數(shù)據(jù)解析的方法有三種
- SAX解析
- DOM解析
- 利用一個(gè)三方(XMLReader 在githab上可以找得到)將XML數(shù)據(jù)解析成一個(gè)字典類型的數(shù)據(jù)
1.對(duì)于SAX解析他是利用系統(tǒng)的類 (NSXMLParser)進(jìn)行數(shù)據(jù)解析 所以這種方法和其他方法進(jìn)行比較 效率較高 這種方式進(jìn)行數(shù)據(jù)解析是逐行進(jìn)行操作的 讓我們結(jié)合代碼來看
首先我們得到一個(gè)XML的數(shù)據(jù)文件 獲取這個(gè)文件路徑 將其轉(zhuǎn)化為NSData類型 然后創(chuàng)建NSXMLParser對(duì)象 將參數(shù)data填入(NSXMLParser我們要簽這個(gè)類的協(xié)議)
NSString *path = [[NSBundle mainBundle] pathForResource:@"stu_xml" ofType:@".xml"];
NSData *data = [NSData dataWithContentsOfFile:path];
NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:data];
xmlParser.delegate = self;
// 運(yùn)行
[xmlParser parse];
// 在解析開始這個(gè)方法中 我們初始化數(shù)組
- (void)parserDidStartDocument:(NSXMLParser *)parser {
self.stuArray = [NSMutableArray array];
}
// 逐行解析 遇到節(jié)點(diǎn)頭
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName attributes:(NSDictionary<NSString *, NSString *> *)attributeDict {
// 逐行運(yùn)行 將每一行的節(jié)點(diǎn)名賦值給定義的變量(記錄節(jié)點(diǎn) 方便后期賦值)
_currentElementName = elementName;
// 遇到節(jié)點(diǎn)student 創(chuàng)建model
if ([elementName isEqualToString:@"student"]) {
Student *stu = [[Student alloc] init];
[_stuArray addObject:stu];
}
}
// 節(jié)點(diǎn)的值 (根據(jù)節(jié)點(diǎn)決定值)
- (void)parser:(NSXMLParser *)parser foundCharacters:(nonnull NSString *)string {
// string是"\n" "\t"
if (_currentElementName) {
Student *stu = [_stuArray lastObject];
// 賦值 (將節(jié)點(diǎn)名和節(jié)點(diǎn)值 通過 setValue forKey 賦值給model)
[stu setValue:string forKey:_currentElementName];
}
}
// 逐行解析 遇到節(jié)點(diǎn)尾 (直到數(shù)據(jù)每行都運(yùn)行完畢執(zhí)行該方法)
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(nullable NSString *)namespaceURI qualifiedName:(nullable NSString *)qName {
// 在節(jié)點(diǎn)尾 給節(jié)點(diǎn)名賦值為空
_currentElementName = nil;
}
// 解析結(jié)束
- (void)parserDidEndDocument:(NSXMLParser *)parser {
NSLog(@"%@", _stuArray);
}
- (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError {
NSLog(@"解析失敗%@", parseError);
}
- DOM
第二種解析方式 DOM(document Object model)解析 不是逐行解析
關(guān)于GDataXMLNode的引入 - 引入.h .m 文件
- 引入系統(tǒng)libxml2.tbd
- 根據(jù)GDataXMLNode頭文件 添加 /usr/include/libxml2
- 如果是ARC環(huán)境需要對(duì)該文件進(jìn)行mrc編譯(添加 -fno-objc-arc)
self.DOMStuArray = [NSMutableArray array];
NSString *path = [[NSBundle mainBundle] pathForResource:@"stu_xml" ofType:@".xml"];
NSData *data = [NSData dataWithContentsOfFile:path];
NSError *error = nil;
// 創(chuàng)建GDataXMLDocument對(duì)象
// 根據(jù)xml的Data數(shù)據(jù)生成一個(gè)樹形結(jié)構(gòu)的 document
GDataXMLDocument *document = [[GDataXMLDocument alloc] initWithData:data options:0 error:&error];
// 根據(jù)document 獲取根節(jié)點(diǎn)
GDataXMLElement *rootElement = [document rootElement];
// 根據(jù)根節(jié)點(diǎn) 獲取子節(jié)點(diǎn)數(shù)組
NSArray *rootChildrenElementArray = rootElement.children;
// 遍歷子節(jié)點(diǎn)數(shù)組 得到對(duì)應(yīng)所有student節(jié)點(diǎn)
for (GDataXMLElement *childElement in rootChildrenElementArray) {
Student *stu = [Student new];
NSLog(@"ARRAY %@", childElement);
[self.DOMStuArray addObject:stu];
// 遍歷所有student的所有子節(jié)點(diǎn)
for (GDataXMLElement *grandSonElement in childElement.children) {
// .stringValue(節(jié)點(diǎn)值) .name(節(jié)點(diǎn)名)
[stu setValue:grandSonElement.stringValue forKey:grandSonElement.name];
}
}
3.用三方進(jìn)行數(shù)據(jù)解析
NSString *path = [[NSBundle mainBundle] pathForResource:@"stu_xml" ofType:@".xml"];
NSData *data = [NSData dataWithContentsOfFile:path];
NSError *error = nil;
NSDictionary *dic = [XMLReader dictionaryForXMLData:data error:&error];
// NSLog(@"%@", dic);