系统有提供的XML解析类,NSXMLParser,但是不是很不好用啊,该类只会以协议的方式通知扫描时所遇到的XML元素,而且该XML数据的层次关系也看不出来,刚刚封装了一个XML解析功能,直接可以得到根结点,然后就可以查看子结点了。
NSXMLParser+Cobbler.h
// // NSXMLParser+Cobbler.h // // // Created by yangjianhong-MAC on 11-12-31. // Copyright (c) 2011年 __MyCompanyName__. All rights reserved. // QQ:18222469 // #import <Foundation/Foundation.h> #pragma mark - #pragma mark XMLNode @interface XMLNode : NSObject { @private NSString *_strNodeName;//结点名称 NSDictionary *_dicAttributes;//结点属性 NSMutableArray *_arrayChild;//子结点 NSString *_strNodeValue;//结点值 NSUInteger _nodeDepth; XMLNode *_nodeParent;//父结点 } @property (nonatomic, copy) NSString *nodeName; @property (nonatomic, copy) NSDictionary *nodeAttributesDict; @property (nonatomic, readonly) NSArray *children; @property (nonatomic, copy) NSString *nodeValue; @property (nonatomic, readonly) NSUInteger nodeDepth; @property (nonatomic, assign) XMLNode *nodeParent; - (void)clear; @end #pragma mark - #pragma mark NSXMLParser Cobbler @interface NSXMLParser (Cobbler) + (XMLNode *)parseToXMLNode:(NSData *)dataXML; @end
// // NSXMLParser+Cobbler.m // // // Created by yangjianhong-MAC on 11-12-31. // Copyright (c) 2011年 __MyCompanyName__. All rights reserved. // QQ:18222469 // #import "NSXMLParser+Cobbler.h" #pragma mark - #pragma mark XMLNode @implementation XMLNode @synthesize nodeName = _strNodeName, nodeValue = _strNodeValue; @synthesize nodeAttributesDict = _dicAttributes, nodeDepth = _nodeDepth; #pragma mark Override //20120610增加 - (void)dealloc { [_strNodeName release]; [_dicAttributes release]; [_strNodeValue release]; _nodeParent = nil; [super dealloc]; } - (NSArray *)children { if (_arrayChild.count > 0) { return [NSArray arrayWithArray:_arrayChild]; } else { return nil; } } - (void)setNodeParent:(XMLNode *)nodeParent { _nodeParent = nodeParent; //计算本结点的深度 if (nil == nodeParent) { //父结点为nil,当前结点深度为0 _nodeDepth = 0; } else { //当前结点深度为父结点深度+1 _nodeDepth = nodeParent.nodeDepth + 1; } //更新子结点的深度 if (_arrayChild.count > 0) { //遍历子结点 for (XMLNode *nodeChild in _arrayChild) { //通过设置父结点的方式更新子结点深度 nodeChild.nodeParent = self; } } } - (XMLNode *)nodeParent { return _nodeParent; } - (NSString *)description { if (_strNodeName.length == 0) { return @""; } NSMutableString *mstrDescription = [NSMutableString string]; //表示深度的空格字符 NSMutableString *mstrSpace = [[NSMutableString alloc] init]; for (int i = 0; i < _nodeDepth; i++) { [mstrSpace appendString:@" "]; } [mstrDescription appendString:mstrSpace]; //结点的名称 [mstrDescription appendFormat:@"\r\n%@<%@", mstrSpace, _strNodeName]; //结点的属性 NSArray *arrayKeys = [_dicAttributes allKeys]; for (NSString *strKey in arrayKeys) { [mstrDescription appendFormat:@" \"%@\"=\"%@\"", strKey, [_dicAttributes objectForKey:strKey]]; } [mstrDescription appendString:@">"]; //结点的值 if (_strNodeValue.length > 0) { [mstrDescription appendFormat:@"%@", _strNodeValue]; } //子结点部分 if (_arrayChild.count > 0) { //遍历所有子结点 for (XMLNode *nodeChild in _arrayChild) { //子结点描述串 [mstrDescription appendFormat:@"%@", nodeChild]; } [mstrDescription appendFormat:@"\r\n%@", mstrSpace]; } //结点的结束 [mstrDescription appendFormat:@"</%@>", _strNodeName]; [mstrSpace release]; // return mstrDescription; } #pragma mark Public - (void)addChildNode:(XMLNode *)childNode { if (nil == _arrayChild) { _arrayChild = [NSMutableArray arrayWithCapacity:5]; } // [_arrayChild addObject:childNode]; } - (void)clear { NSArray *arrayChild = [self children]; //遍历所有子结点 for (XMLNode *node in arrayChild) { //清空子结点的数据 [node clear]; } //清空当前结点数据 _nodeDepth = 0; self.nodeName = nil; self.nodeValue = nil; self.nodeAttributesDict = nil; self.nodeParent = nil; //清空子结点表 [_arrayChild removeAllObjects]; } @end #pragma mark - #pragma mark XMLParser interface @interface XMLParser : NSObject <NSXMLParserDelegate> { @private XMLNode *_rootNode; XMLNode *_currentNode; } - (XMLNode *)parse:(NSData *)dataXML; @end #pragma mark - #pragma mark XMLParser implementation @implementation XMLParser - (XMLNode *)parse:(NSData *)dataXML { _rootNode = nil; _currentNode = nil; // NSXMLParser *parser = [[NSXMLParser alloc] initWithData:dataXML]; //设置XML数据 [parser setShouldProcessNamespaces:NO]; [parser setShouldReportNamespacePrefixes:NO]; [parser setShouldResolveExternalEntities:NO]; [parser setDelegate:self]; [parser parse]; [parser release];//20120610增加 return _rootNode; } #pragma mark NSXMLParserDelegate - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { NSLog(@"element start:%@",elementName); // if (nil == _rootNode) { //创建根结点 _rootNode = [[[XMLNode alloc] init] autorelease]; _rootNode.nodeName = elementName; _rootNode.nodeAttributesDict = attributeDict; _rootNode.nodeParent = nil; // _currentNode = _rootNode; } else { // XMLNode *nodeChild = [[XMLNode alloc] init]; nodeChild.nodeName = elementName; nodeChild.nodeAttributesDict = attributeDict; nodeChild.nodeParent = _currentNode; // [_currentNode addChildNode:nodeChild]; _currentNode = nodeChild; [nodeChild release]; } } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { //去掉字符串首尾的空字符 NSString *strValidValue = [string stringByTrimmingCharactersInSet: [NSCharacterSet whitespaceAndNewlineCharacterSet]]; NSLog(@"element value:%@",strValidValue); _currentNode.nodeValue = strValidValue; } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { NSLog(@"element end."); // _currentNode = _currentNode.nodeParent; } - (void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError { NSLog(@"parse error:%@", parseError); _rootNode = nil; } @end #pragma mark - #pragma mark NSXMLParser Cobbler @implementation NSXMLParser (Cobbler) + (XMLNode *)parseToXMLNode:(NSData *)dataXML { XMLParser *parser = [[XMLParser alloc] init]; XMLNode *node = [parser parse:dataXML]; [parser release]; return node; } @end
为了方便,以及想类名的麻烦,只是给NSXMLParser写了个分类,静态方法,参数为NSData,返回类型为XMLNode。
有什么问题,或者使用不方便的找我哇