当前位置: 首页 > news >正文

中国江西网官方网站百度站长中心

中国江西网官方网站,百度站长中心,wordpress date_query,最新旅游新闻播报iOS开发之将XML转换成树是本文要介绍的内容,开发中由于服务端与客户端是两种不同的平台,而且服务端又是老系统,不具备很好的面向对象的性质,所以导致客户端与服务端只好通过一些制定好的xml进行通信。 在iOS中对XML的解析不像done…

iOS开发之将XML转换成是本文要介绍的内容,开发中由于服务端与客户端是两种不同的平台,而且服务端又是老系统,不具备很好的面向对象的性质,所以导致客户端与服务端只好通过一些制定好的xml进行通信。

在iOS中对XML的解析不像donet这么方便。当然也存在一些很方便的开源类库去调用,但是有些开源的类库显得很笨重。本文章将封装一个简单操作XML转换成的类方便自己操作:首先通过NSXMLParser从服务端获取XML,它可以一边下载,一边解析,然后转换成形结构,最后我们可以从形结构中去取值。

使用NSXMLParser解析XML:

NSXMLParser中主要有三个委托方法来解析XML:

1、parser:didStartElement: 当解析器对象遇到xml的开始标记时,调用这个方法。

2、parser:didEndElement:当解析器对象遇到xml的结束标记时,调用这个方法。

3、parser:foundCharacters:当解析器找到开始标记和结束标记之间的字符时,调用这个方法。

了解了NSXMLParser机制。然后我们来封装解析XML的类:XMLParser。

#import <CoreFoundation/CoreFoundation.h>    
#import "TreeNode.h"
@interface XMLParser : NSObject
{
NSMutableArray *stack;
}
+ (XMLParser *) sharedInstance;
- (TreeNode *) parseXMLFromURL: (NSURL *) url;
- (TreeNode *) parseXMLFromData: (NSData*) data;
@end

shareInstance使用一个单例。

调用parseXMLFromURL方法,需要一个NSURL的参数,返回我们需要的树节点。

调用parseXMLFromData方法,需要一个NSData的参数,返回我们需要的树节点。

在此之前,先定义TreeNode类:

 1 #import <CoreFoundation/CoreFoundation.h>    
2 @interface TreeNode : NSObject
3 {
4 TreeNode *parent;
5 NSMutableArray *children;
6 NSString *key;
7 NSString *leafvalue;
8 }
9 @property (nonatomic, retain) TreeNode *parent;
10 @property (nonatomic, retain) NSMutableArray *children;
11 @property (nonatomic, retain) NSString *key;
12 @property (nonatomic, retain) NSString *leafvalue;
13 @property (nonatomic, readonly) BOOL isLeaf;
14 @property (nonatomic, readonly) BOOL hasLeafValue;
15 @property (nonatomic, readonly) NSArray *keys;
16 @property (nonatomic, readonly) NSArray *allKeys;
17 @property (nonatomic, readonly) NSArray *uniqKeys;
18 @property (nonatomic, readonly) NSArray *uniqAllKeys;
19 @property (nonatomic, readonly) NSArray *leaves;
20 @property (nonatomic, readonly) NSArray *allLeaves;
21 @property (nonatomic, readonly) NSString *dump;
22 + (TreeNode *) treeNode;
23 - (NSString *) dump;
24 - (void) teardown;
25 // Leaf Utils
26 - (BOOL) isLeaf;
27 - (BOOL) hasLeafValue;
28 - (NSArray *) leaves;
29 - (NSArray *) allLeaves;
30 // Key Utils
31 - (NSArray *) keys;
32 - (NSArray *) allKeys;
33 - (NSArray *) uniqKeys;
34 - (NSArray *) uniqAllKeys;
35 // Search Utils
36 - (TreeNode *) objectForKey: (NSString *) aKey;
37 - (NSString *) leafForKey: (NSString *) aKey;
38 - (NSMutableArray *) objectsForKey: (NSString *) aKey;
39 - (NSMutableArray *) leavesForKey: (NSString *) aKey;
40 - (TreeNode *) objectForKeys: (NSArray *) keys;
41 - (NSString *) leafForKeys: (NSArray *) keys;
42
43 // Convert Utils
44 - (NSMutableDictionary *) dictionaryForChildren;
45 @end


TreeNode 实现:

  1 #import "TreeNode.h"    
2 // String stripper utility macro
3 #define STRIP(X) [X stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceAndNewlineCharacterSet]]
4 @implementation TreeNode
5 @synthesize parent;
6 @synthesize children;
7 @synthesize key;
8 @synthesize leafvalue;
9 #pragma mark Create and Initialize TreeNodes
10 - (TreeNode *) init
11 {
12 if (self = [super init])
13 {
14 self.key = nil;
15 self.leafvalue = nil;
16 self.parent = nil;
17 self.children = nil;
18 }
19 return self;
20 }
21 + (TreeNode *) treeNode
22 {
23 return [[[self alloc] init] autorelease];
24 }
25 #pragma mark TreeNode type routines
26 - (BOOL) isLeaf
27 {
28 return (self.children.count == 0);
29 }
30 - (BOOL) hasLeafValue
31 {
32 return (self.leafvalue != nil);
33 }
34 #pragma mark TreeNode data recovery routines
35 // Return an array of child keys. No recursion
36 - (NSArray *) keys
37 {
38 NSMutableArray *results = [NSMutableArray array];
39 for (TreeNode *node in self.children) [results addObject:node.key];
40 return results;
41 }
42 // Return an array of child keys with depth-first recursion.
43 - (NSArray *) allKeys
44 {
45 NSMutableArray *results = [NSMutableArray array];
46 for (TreeNode *node in self.children)
47 {
48 [results addObject:node.key];
49 [results addObjectsFromArray:node.allKeys];
50 }
51 return results;
52 }
53 - (NSArray *) uniqArray: (NSArray *) anArray
54 {
55 NSMutableArray *array = [NSMutableArray array];
56 for (id object in [anArray sortedArrayUsingSelector:@selector(caseInsensitiveCompare:)])
57 if (![[array lastObject] isEqualToString:object]) [array addObject:object];
58 return array;
59 }
60 // Return a sorted, uniq array of child keys. No recursion
61
62 - (NSArray *) uniqKeys
63 {
64 return [self uniqArray:[self keys]];
65 }
66 // Return a sorted, uniq array of child keys. With depth-first recursion
67
68 - (NSArray *) uniqAllKeys
69 {
70 return [self uniqArray:[self allKeys]];
71 }
72 // Return an array of child leaves. No recursion
73
74 - (NSArray *) leaves
75 {
76 NSMutableArray *results = [NSMutableArray array];
77 for (TreeNode *node in self.children) if (node.leafvalue) [results addObject:node.leafvalue];
78 return results;
79 }
80 // Return an array of child leaves with depth-first recursion.
81
82 - (NSArray *) allLeaves
83 {
84 NSMutableArray *results = [NSMutableArray array];
85 for (TreeNode *node in self.children)
86 {
87 if (node.leafvalue) [results addObject:node.leafvalue];
88 [results addObjectsFromArray:node.allLeaves];
89 }
90 return results;
91 }
92 #pragma mark TreeNode search and retrieve routines
93 // Return the first child that matches the key, searching recursively breadth first
94 - (TreeNode *) objectForKey: (NSString *) aKey
95 {
96 TreeNode *result = nil;
97 for (TreeNode *node in self.children)
98 if ([node.key isEqualToString: aKey])
99 {
100 result = node;
101 break;
102 }
103 if (result) return result;
104 for (TreeNode *node in self.children)
105 {
106 result = [node objectForKey:aKey];
107 if (result) break;
108 }
109 return result;
110 }
111 // Return the first leaf whose key is a match, searching recursively breadth first
112
113 - (NSString *) leafForKey: (NSString *) aKey
114 {
115 TreeNode *node = [self objectForKey:aKey];
116 return node.leafvalue;
117 }
118 // Return all children that match the key, including recursive depth first search.
119
120 - (NSMutableArray *) objectsForKey: (NSString *) aKey
121 {
122 NSMutableArray *result = [NSMutableArray array];
123 for (TreeNode *node in self.children)
124 {
125 if ([node.key isEqualToString: aKey]) [result addObject:node];
126 [result addObjectsFromArray:[node objectsForKey:aKey]];
127 }
128 return result;
129 }
130 // Return all leaves that match the key, including recursive depth first search.
131
132 - (NSMutableArray *) leavesForKey: (NSString *) aKey
133 {
134 NSMutableArray *result = [NSMutableArray array];
135 for (TreeNode *node in [self objectsForKey:aKey])
136 if (node.leafvalue)
137 [result addObject:node.leafvalue];
138 return result;
139 }
140 // Follow a key path that matches each first found branch, returning object
141
142 - (TreeNode *) objectForKeys: (NSArray *) keys
143
144 {
145 if ([keys count] == 0) return self;
146 NSMutableArray *nextArray = [NSMutableArray arrayWithArray:keys];
147 [nextArray removeObjectAtIndex:0];
148 for (TreeNode *node in self.children)
149 {
150 if ([node.key isEqualToString:[keys objectAtIndex:0]])
151 return [node objectForKeys:nextArray];
152 }
153 return nil;
154 }
155 // Follow a key path that matches each first found branch, returning leaf
156
157 - (NSString *) leafForKeys: (NSArray *) keys
158 {
159 TreeNode *node = [self objectForKeys:keys];
160 return node.leafvalue;
161 }
162 #pragma mark output utilities
163 // Print out the tree
164
165 - (void) dumpAtIndent: (int) indent into:(NSMutableString *) outstring
166 {
167 for (int i = 0; i < indent; i++) [outstring appendString:@"--"];
168 [outstring appendFormat:@"[%2d] Key: %@ ", indent, key];
169 if (self.leafvalue) [outstring appendFormat:@"(%@)", STRIP(self.leafvalue)];
170 [outstring appendString:@"\n"];
171 for (TreeNode *node in self.children) [node dumpAtIndent:indent + 1 into: outstring];
172 }
173 - (NSString *) dump
174 {
175 NSMutableString *outstring = [[NSMutableString alloc] init];
176 [self dumpAtIndent:0 into:outstring];
177 return [outstring autorelease];
178 }
179 #pragma mark conversion utilities
180 // When you're sure you're the parent of all leaves, transform to a dictionary
181
182 - (NSMutableDictionary *) dictionaryForChildren
183 {
184 NSMutableDictionary *results = [NSMutableDictionary dictionary];
185 for (TreeNode *node in self.children)
186 if (node.hasLeafValue) [results setObject:node.leafvalue forKey:node.key];
187 return results;
188 }
189 #pragma mark invocation forwarding
190 // Invocation Forwarding lets node act like array
191
192 - (id)forwardingTargetForSelector:(SEL)sel
193 {
194 if ([self.children respondsToSelector:sel]) return self.children;
195 eturn nil;
196 }
197 // Extend selector compliance
198 - (BOOL)respondsToSelector:(SEL)aSelector
199
200 {
201 if ( [super respondsToSelector:aSelector] ) return YES;
202 if ([self.children respondsToSelector:aSelector]) return YES;
203 return NO;
204 }
205 // Allow posing as NSArray class for children
206 - (BOOL)isKindOfClass:(Class)aClass
207
208 {
209 if (aClass == [TreeNode class]) return YES;
210 if ([super isKindOfClass:aClass]) return YES;
211 if ([self.children isKindOfClass:aClass]) return YES;
212 return NO;
213 }
214 #pragma mark cleanup
215
216 - (void) teardown
217 {
218 for (TreeNode *node in [[self.children copy] autorelease]) [node teardown];
219 [self.parent.children removeObject:self];
220 self.parent = nil;
221 }
222
223 - (void) dealloc
224 {
225 self.parent = nil;
226 self.children = nil;
227 self.key = nil;
228 self.leafvalue = nil;
229 [super dealloc];
230 }
231 @end

 

从上面的代码可以看出,定义了很多方便的方法来获取数据。

1、teardown:清除所有节点

2、isLeaf:判断是否是叶子节点

3、hasLeafValue:判断节点是否有值

4、- (NSArray *) leaves:返回节点的所有一级子节点值

5、- (NSArray *) allLeaves:返回节点的所有子节点的值

6、keys; 返回节点所有一级子节点名称。

7、 allKeys; 返回节点所有子节点名称。

8、 uniqKeys;返回节点一级子节点名称,不重复。

9、uniqAllKeys;返回节点子节点名称,不重复。

10、- (TreeNode *) objectForKey:根据节点名称查询节点

11、- (NSString *) leafForKey: (NSString *) aKey:根据节点名称查询出节点的值

12、- (NSMutableArray *) objectsForKey: (NSString *) aKey;根据节点名称查询出所以满足条件的节点

13、- (NSMutableArray *) leavesForKey: (NSString *) aKey;根据节点名称查询出所以满足条件的节点的值

14、- (TreeNode *) objectForKeys: (NSArray *) keys;:根据节点名称路径查询出第一个满足条件的节点。

15、- (NSString *) leafForKeys: (NSArray *) keys 根据节点名称路径查询出第一个满足条件的节点的值。

16、- (NSMutableDictionary *) dictionaryForChildren:将转换成dictionary定义好了,下面实现XMLParser类:

  1. #import "XMLParser.h"    
  2. @implementation XMLParser    
  3. static XMLParser *sharedInstance = nil;    
  4. // Use just one parser instance at any time    
  5. +(XMLParser *) sharedInstance     
  6. {    
  7.     if(!sharedInstance) {    
  8.         sharedInstance = [[self alloc] init];    
  9.     }    
  10.     return sharedInstance;    
  11. }    
  12. // Parser returns the tree root. You may have to go down one node to the real results    
  13. - (TreeNode *) parse: (NSXMLParser *) parser    
  14. {    
  15.    stack = [NSMutableArray array];    
  16.     TreeNode *root = [TreeNode treeNode];    
  17.     root.parent = nil;    
  18.     root.leafvalue = nil;    
  19.     root.children = [NSMutableArray array];    
  20.     [stack addObject:root];    
  21.     [parser setDelegate:self];    
  22.     [parser parse];    
  23.     [parser release];    
  24.     // pop down to real root    
  25.     TreeNode *realroot = [[root children] lastObject];    
  26.     root.children = nil;    
  27.     root.parent = nil;    
  28.     root.leafvalue = nil;    
  29.     root.key = nil;    
  30.     realroot.parent = nil;    
  31.     return realroot;    
  32. }    
  33.  
  34. - (TreeNode *)parseXMLFromURL: (NSURL *) url    
  35. {       
  36.     TreeNode *results;    
  37.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];    
  38.     NSXMLParser *parser = [[NSXMLParser alloc] initWithContentsOfURL:url];    
  39.     results = [self parse:parser];    
  40.     [pool drain];    
  41.     return results;    
  42. }    
  43. - (TreeNode *)parseXMLFromData: (NSData *) data    
  44. {       
  45.     TreeNode *results;    
  46.     NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];    
  47.     NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];    
  48.     results = [self parse:parser];    
  49.     [pool drain];    
  50.     return results;    
  51. }    
  52. // Descend to a new element    
  53.  
  54. - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)
  55. namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict    
  56. {    
  57.     if (qName) elementName = qName;    
  58.     TreeNode *leaf = [TreeNode treeNode];    
  59.     leaf.parent = [stack lastObject];    
  60.     [(NSMutableArray *)[[stack lastObject] children] addObject:leaf];    
  61.     leaf.key = [NSString stringWithString:elementName];    
  62.     leaf.leafvalue = nil;    
  63.     leaf.children = [NSMutableArray array];    
  64.     [stack addObject:leaf];    
  65. }    
  66. // Pop after finishing element    
  67.  
  68. - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName    
  69. {    
  70.     [stack removeLastObject];    
  71. }    
  72. // Reached a leaf    
  73.  
  74. - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string    
  75. {    
  76.     if (![[stack lastObject] leafvalue])    
  77.     {    
  78.         [[stack lastObject] setLeafvalue:[NSString stringWithString:string]];    
  79.         return;    
  80.     }    
  81.     [[stack lastObject] setLeafvalue:[NSString stringWithFormat:@"%@%@", [[stack lastObject] leafvalue], string]];    
  82. }    
  83. @end  

使用这两个类:

下面看下我们如何使用这个类:

在iis中放下面这个xml:

  1. <?xml version="1.0" encoding="UTF-8"?>    
  2. <Login>    
  3. <LoginResult>True</LoginResult>    
  4. <LoginInfo>恭喜你登录成功</LoginInfo>    
  5. <LastLogin>2011-05-09 12:20</LastLogin>    
  6. <Right>    
  7. <A>1</A>    
  8. <B>1</B>    
  9. <C>0</C>    
  10. </Right>   
  11. </Login>  

使用下面代码获取web服务器上的xml,并将xml转换成树:

NSURL * url = [[NSURL alloc] initWithString:@"http://10.5.23.117:4444/Login.xml"];    
TreeNode *node = [parser parseXMLFromURL:url];

 

获取xml中的登录结果:

view sourceprint?NSString * result =  [node leafForKey:@"LoginResult"];  

类似xpath去取值:

NSArray *path =[[NSArray alloc]initWithObjects:@"Right",@"A",nil];      
NSString * result = [node leafForKeys:path];

将xml显示在tableview上:

 1 @implementation TreeBrowserController    
2 @synthesize root;
3 // Each instance of this controller has a separate root, as
4 // descending through the tree produces new roots.
5
6 - (id) initWithRoot:(TreeNode *) newRoot
7 {
8 if (self = [super init])
9 {
10 self.root = newRoot;
11 NSString *s =[newRoot dump];
12 if (newRoot.key) self.title = newRoot.key;
13 }
14 return self;
15 }
16 - (id)initWithStyle:(UITableViewStyle)style
17 {
18 self = [super initWithStyle:style];
19 if (self) {
20 // Custom initialization
21 }
22 return self;
23 }

 

 1 // The number of rows equals the number of children for a node    
2
3 - (NSInteger)tableView:(UITableView *)tableView
4 numberOfRowsInSection:(NSInteger)section
5 {
6 return [self.root.children count];
7 }
8 // Color code the cells that can be navigated through
9
10 - (UITableViewCell *)tableView:(UITableView *)tableView
11 cellForRowAtIndexPath:(NSIndexPath *)indexPath
12 {
13 UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"generic"];
14 if (!cell) cell = [[[UITableViewCell alloc]
15 initWithFrame:CGRectZero reuseIdentifier:@"generic"]
16 autorelease];
17 TreeNode *child = [[self.root children]
18 objectAtIndex:[indexPath row]];
19 // Set text
20 if (child.hasLeafValue)
21 cell.textLabel.text = [NSString stringWithFormat:@"%@:%@",
22 child.key, child.leafvalue];
23 else
24 cell.textLabel.text = child.key;
25 // Set color
26 if (child.isLeaf)
27 cell.textLabel.textColor = [UIColor darkGrayColor];
28 else
29 cell.textLabel.textColor = [UIColor blackColor];
30 return cell;
31 }
32 // On selection, either push a new controller or show the leaf value
33
34 - (void)tableView:(UITableView *)tableView
35 didSelectRowAtIndexPath:(NSIndexPath *)indexPath
36
37 {
38 TreeNode *child =
39 [self.root.children objectAtIndex:[indexPath row]];
40 if (child.isLeaf)
41 {
42 return;
43 }
44 TreeBrowserController *tbc = [[[TreeBrowserController alloc]
45 initWithRoot:child] autorelease];
46 [self.navigationController pushViewController:tbc animated:YES];
47 }
48 // These controllers are ephemeral and need dealloc
49
50 - (void) dealloc
51 {
52 self.root = nil;
53 [super dealloc];
54 }
55 @end



效果:

详解iOS开发之将XML转换成树 

详解iOS开发之将XML转换成树

总结:详解iOS开发之将XML转换成的内容介绍完了,本文通过封装两个类库,可以从web上很高效获取xml,将xml转换成形结构,可以很方便的对进行操作。

 

 

iOS开发本文章将封装一个简单操作XML转换成树的类方便自己操作:首先通过NSXMLParser从服务端获取XML,它可以一边下载,一边解析,然后转换成树形结构,最后我们可以从树形结构中去取值。

IOS开发之将XML转换成是介绍的内容;上文所述:很好将xml转换成,并进行操作,但是忽略了对xml节点上属性的操作,现在让我来修改代码,将属性添加进来。

1、在treenode中加一个类型为NSDictionary的attributeDict用于存放属性。代码如下:

NSDictionary * attributeDict; 

2、在中可以在parser:didStartElement:方法中取到属性列表,在其中添加添加下面代码。

leaf.attributeDict = [[NSDictionary alloc] initWithDictionary:attributeDict];  

3、修改样例xml

<?xml version="1.0" encoding="UTF-8"?>    
<Login>
<LoginResult id="1">True</LoginResult>
<LoginInfo>OK</LoginInfo>
<LastLogin>2011-05-09 12:20</LastLogin>
<Right>
<A>1</A>
<B>1</B>
<C>0</C>
</Right>
</Login>


4、取属性id的值。

TreeNode * resultTreeNode =  [node objectForKey:@"LoginResult"];    
NSString *result = [resultTreeNode.attributeDict objectForKey:@"id"];



http://www.lbrq.cn/news/2410921.html

相关文章:

  • 经典网站设计案例营销公司网站
  • 龙川网站建设怎样申请网站
  • wordpress文章专题插件平台seo什么意思
  • 网站目录层级建设网站优化的方法
  • asp网站文章自动更新杭州网站
  • 政务性网站建设费用百度开发者平台
  • 沈阳单页网站制作软文投放平台有哪些?
  • 会员制网站建设百度搜索推广怎么做
  • 整站优化网站报价怎么投放网络广告
  • 笔记本做网站seo关键词排名优化技巧
  • 1688网站靠谱吗个人网页制作成品
  • 百度获取入口宁波 seo排名公司
  • 做资源下载网站条件商品关键词优化的方法
  • 成都建工网站谷歌搜索引擎营销
  • 做cpc不做网站可以吗全网营销代理加盟
  • 百度推广如何代理加盟武汉seo广告推广
  • 做快递单的网站会不会是骗人的直通车优化推广
  • 免费企业网站源码生成浏览器网页版入口
  • 延平区城乡建设和旅游局网站seo技术自学
  • 做网站成功网站seo标题是什么意思
  • 怎样制作免费的网站网络运营商
  • 企业网站建设与网页设计运营网站是什么意思
  • 有什么网站做知识吗郑州关键词优化费用
  • 福州营销网站建设团队成都seo培训
  • 郉台网站建设淘宝seo排名优化
  • 浙江网站建设电话企业如何进行网络营销
  • 网站建设加优化如何推广网站方法
  • 用focusky做h5微网站百度账号登录个人中心
  • 做网站需要先申请域名电视剧排行榜
  • 网站源码 一品资源网bt搜索引擎
  • 智慧场景:定制开发开源AI智能名片S2B2C商城小程序赋能零售新体验
  • 用户虚拟地址空间布局架构
  • 【用unity实现100个游戏之34】使用环状(车轮)碰撞器(Wheel Collider)从零实现一个汽车车辆物理控制系统,实现一个赛车游戏
  • 创新几何解谜游戏,挑战空间思维极限
  • Twisted study notes[2]
  • 深度学习图像分类数据集—八种贝类海鲜食物分类