通过soap请求webservice时,返回的数据是XML类型,有时候也需要解析本地的xml数据等,苹果自带类NSXMLParser解析xml还是很方便的,简单轻便

2014-10-16 记:

经热心网友指正,本文存在一定的问题,先置顶提醒我自己,有空时调试改正

有问题也请大家积极帮忙指出,谢谢大家

本文以解析本地XML为例,网络获取到的返回值只需转换成NSData型,解析是同理

需要解析的xml文件如下,users.xml

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?xml version= "1.0" encoding= "UTF-8" ?>
<AllUsers>
     <message>用户信息</message>
     <user>
         <name>芳仔小脚印</name>
         <age>10</age>
         <school>JiangSu University</school>
     </user>
     <user>
         <name>毒虫</name>
         <age>22</age>
         <school>NanJing University</school>
     </user>
     <user>
         <name>女神</name>
         <age>23</age>
         <school>HongKong University</school>
     </user>
</AllUsers>

我们用一个数组来存放,最终数据结构为

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
(
         {
         message = "用户信息" ;
     },
         {
         age = 10;
         name = "芳仔小脚印" ;
         school = "JiangSu University" ;
     },
         {
         age = 22;
         name = "毒虫" ;
         school = "NanJing University" ;
     },
         {
         age = 23;
         name = "女神" ;
         school = "HongKong University" ;
     }
)

解析步骤 

一、声明代理 NSXMLParserDelegate

二、解析

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
// 遇到节点message和user时作为一个字典存放
     NSArray *keyElements = [[NSArray alloc] initWithObjects:@ "message" ,@ "user" , nil];
     // 需要解析的字段
     NSArray *rootElements = [[NSArray alloc] initWithObjects:@ "message" ,@ "name" ,@ "age" ,@ "school" , nil];
     // 获取xml文件的路径
     NSString *xmlPath = [[NSBundle mainBundle] pathForResource:@ "users" ofType:@ "xml" ];
     // 转化为Data
     NSData *data = [[NSData alloc] initWithContentsOfFile:xmlPath];
     
     // 初始化
     NSXMLParser *xmlParser = [[NSXMLParser alloc] initWithData:data];
     
     // 代理
     xmlParser.delegate = self;
     // 开始解析
     BOOL flag = [xmlParser parse];
     if (flag) {
         NSLog(@ "解析成功" );
     }
     else {
         NSLog(@ "解析出错" );
     }

中间变量,在.m的interface的中定义

?
1
2
3
4
5
6
7
NSString *currentElement;
     
     NSString *currentValue;
     
     NSMutableDictionary *rootDic;
     
     NSMutableArray *finalArray;

代理方法

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#pragma - mark 开始解析时
-( void )parserDidStartDocument:(NSXMLParser *)parser
{
     // 用数组存储每一组信息
     finalArray = [[NSMutableArray alloc] init];
     
     
}
#pragma - mark 发现节点时
-( void )parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
     for (NSString *key in self.keyElements){
         if ([elementName isEqualToString:key]) {
             // 关键节点开始时,初始化一个字典来存放值
             rootDic = nil;
             
             rootDic = [[NSMutableDictionary alloc] initWithCapacity:0];
             
         }
         else {
             for (NSString *element in self.rootElements){
                 if ([element isEqualToString:element]) {
                     currentElement = elementName;
                     currentValue = [NSString string];
                 }
             }
         }
     }
     
}
#pragma - mark 发现节点值时
 
-( void )parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
     
     if (currentElement) {
 
         currentValue = string;
         [rootDic setObject:string forKey:currentElement];
     }
     
}
#pragma - mark 结束节点时
-( void )parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
     if (currentElement) {
         [rootDic setObject:currentValue forKey:currentElement];
         currentElement = nil;
         currentValue = nil;
     }
     for (NSString *key in self.keyElements){
 
         if ([elementName isEqualToString:key]) {
             // 关键节点结束时,将字典存放在数组中
             if (rootDic) {
 
                 [finalArray addObject:rootDic];
             }
         }
     }
}
#pragma - mark 结束解析
-( void )parserDidEndDocument:(NSXMLParser *)parser
{
     
}

解析完成后,打印出finalArray为

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
         message = "\U7528\U6237\U4fe1\U606f" ;
     },
         {
         age = 10;
         name = "\U82b3\U4ed4\U5c0f\U811a\U5370" ;
         school = "JiangSu University" ;
     },
         {
         age = 22;
         name = "\U6bd2\U866b" ;
         school = "NanJing University" ;
     },
         {
         age = 23;
         name = "\U5973\U795e" ;
         school = "HongKong University" ;
     }
)
【原创】转帖请注明来源,谢谢 -tag 1- 测试无内存泄露 1 创建数据对象() NSMutableDictionary *map = [[NSMutableDictionary alloc]init]; [map setObject:@"a" forKey:@"author"]; [map setObject:@"b" forKey:@"title"]; [map setObject:@"c" forKey:@"content"]; 或者 NSMutableArray *list = [[NSMutableArray alloc]init]; NSMutableDictionary *map1 = [[NSMutableDictionary alloc]init]; [map1 setObject:@"a1" forKey:@"author"]; [map1 setObject:@"b1" forKey:@"title"]; [map1 setObject:@"c1" forKey:@"content"]; [list addObject:map1]; NSMutableDictionary *map2 = [[NSMutableDictionary alloc]init]; [map2 setObject:@"a2" forKey:@"author"]; [map2 setObject:@"b2" forKey:@"title"]; [map2 setObject:@"c2" forKey:@"content"]; [list addObject:map2]; 2 调用封装,声明对象名称及XML模板,组装器会根据XML模板填充数据XmlPackage *xmlPackage = [[XmlPackage alloc]init]; NSData *data = [xmlPackage objctPackage:map objectName:@"book1" xmlTemplateName:@"template1"]; 或者 NSData *data = [xmlPackage listPackage:list objectName:@"book1" xmlTemplateName:@"template1"]; 3 返回DATA 4 利用解析解析并展现到UIView 部分代码如下: @implementation XmlPackage @synthesize obj; @synthesize isList; @synthesize xmlString; @synthesize objectName; @synthesize lvUp; @synthesize root; @synthesize buildEnd; -(NSData *)objctPackage:(NSMutableDictionary *)object objectName:(NSString *)name xmlTemplateName:(NSString *)templateName { NSMutableArray *array = [[NSMutableArray alloc]init]; [array addObject:object]; NSData *data = [self listPackage:array objectName:name xmlTemplateName:templateName]; [array release]; return data; } -(NSData *)listPackage:(NSMutableArray *)objects objectName:(NSString *)name xmlTemplateName:(NSString *)templateName { isList = YES; self.objectName = name; NSString *path = [[NSBundle mainBundle] pathForResource:templateName ofType:@"xml"]; NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:path]; NSData *xmlData = [file readDataToEndOfFile]; NSXMLParser *xmlRead = [[NSXMLParser alloc] initWithData:xmlData]; [xmlRead setDelegate:self]; [xmlRead parse]; [xmlRead release]; //get dataTemplate for (int i=0;i<[objects count]; i++) { NSMutableDictionary *map = [objects objectAtIndex:i]; XmlNode *node = [[[XmlNode alloc]init]autorelease]; node.nodeName = objectName; [node addChildByMap:map]; [lvUp addChildNode:node]; } //get root's xmlString NSMutableString *x = [self.root getXmlString]; //NSLog(@"%@",x); if ((int)[x length]>0) { return [x dataUsingEncoding:NSUTF8StringEncoding]; } return nil; } - (void)dealloc { [obj release]; [xmlString release]; [objectName release]; [lvUp release]; //[root release]; [super dealloc]; } - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { } - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { } - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { if ([elementName isEqualToString:objectName]) { buildEnd = YES; }else{ if (!buildEnd) { //create node XmlNode *node = [[XmlNode alloc]init]; node.nodeName = elementName; //dataTemplate building... if (lvUp!=nil) { [lvUp addChildNode:node]; }else{ root = node; } lvUp = node; } } } @end ===== #import "XmlNode.h" @implementation XmlNode @synthesize nodeName; @synthesize nodeValue; @synthesize isLast; @synthesize list; @synthesize xmlString; - (void)dealloc { [nodeName release]; [nodeValue release]; [list release]; [xmlString release]; [super dealloc]; } -(NSString *)getXmlString { xmlString = [[NSMutableString alloc]init]; [xmlString appendString:@"<?xml version=\"1.0\" encoding=\"UTF-8\"?>"]; [self getNodeStr:self string:xmlString]; return xmlString; } -(void)getNodeStr:(XmlNode *)node string:(NSMutableString *)str { if (node.isLast) { NSString *res = [[NSString alloc]initWithFormat:@"<%@>%@</%@>", node.nodeName, node.nodeValue, node.nodeName]; [str appendString:res]; [res release]; }else{ NSMutableString *a = [[[NSMutableString alloc]init]autorelease]; NSMutableArray *nodelist = [node getChilds]; for (int i=0;i<[nodelist count];i++) { XmlNode *node = [nodelist objectAtIndex:i]; [node getNodeStr:node string:a]; } NSString *res = [[NSString alloc]initWithFormat:@"<%@>%@</%@>", node.nodeName, a, node.nodeName]; [str appendString:res]; [res release]; } } -(void)addChildNode:(XmlNode *)node; { if (list==nil) { list = [[NSMutableArray alloc]init]; } [list addObject:node]; isLast = NO; } -(NSMutableArray *)getChilds { return list; } -(void)addChildByMap:(NSMutableDictionary *)map { NSEnumerator *keys = [map keyEnumerator]; id key; while (key = [keys nextObject]) { XmlNode *node = [[[XmlNode alloc]init]autorelease]; node.isLast = YES; node.nodeName = key; node.nodeValue = [map objectForKey:key]; [self addChildNode:node]; } } @end
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值