网络数据的XML解析
XML解析一般分两种模式SAX和DOM,事件和文档。具体解析google去吧,有详细。不过看了下面的两个例子,一般就了解了。
一:XML解析之SAX解析,以及对NSXMLParser的应用。
sax解析说白了,就是一个事物模型解析,从头开始读取文档然后根据读取到的头标签标签时要怎么处理,读完头标签后,理论上是读取标签值了,
然后读取后遇到结束标签等
SDK本身是提供了NSXMLParser解析器。
1 -(BOOL)parser:(NSString*)string 2 { 3 //系统自带的 4 NSXMLParser *par = [[[NSXMLParser alloc] initWithData:[string dataUsingEncoding:NSUTF8StringEncoding]]autorelease]; 5 //设置NSXMLParser对象的解析方法代理 6 [par setDelegate:self]; 7 //调用代理解析NSXMLParser对象,看解析是否成功 8 return [par parse]; 9 } 10 11 #pragma mark xmlparser 12 //step 1 :准备解析 13 - (void)parserDidStartDocument:(NSXMLParser *)parser 14 { 15 // NSLog(@"%@",NSStringFromSelector(_cmd) ); 16 } 17 //step 2:准备解析节点 18 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 19 { 20 // NSLog(@"%@",NSStringFromSelector(_cmd) ); 21 } 22 //step 3:获取首尾节点间内容 23 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 24 { 25 NSLog(@"%@",NSStringFromSelector(_cmd) ); 26 } 27 28 //step 4 :解析完当前节点 29 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 30 { 31 NSLog(@"%@",NSStringFromSelector(_cmd) ); 32 } 33 34 //step 5;解析结束 35 - (void)parserDidEndDocument:(NSXMLParser *)parser 36 { 37 // NSLog(@"%@",NSStringFromSelector(_cmd) ); 38 } 39 //获取cdata块数据 40 - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock 41 { 42 // NSLog(@"%@",NSStringFromSelector(_cmd) ); 43 }
1.初始化解析器,传入你要解析的数据。
2.parse,启动解析,返回一个是否解析成功Bool值。
3.基本你要处理的就在下面实现的1-5个代理方法了。
其实代理方法和详细,就是一个事物进行流程:
step1是准备解析,然后没意外就是执行到了——>
step2读取到第一个头节点了,然后如果内部有属性值,你可以获取出来,读完头节点,我们会进去值域——>
step3对于简单的节点,可能直接就是一个string值了,但是看例子我们会知道,很多情况下,该节点的值域包含的于是一个节点——>
这步其实分两种,如果是值,那么就是执行step4,获取值的字窜,如果是子节点呢,我们一看就知道,它又是进行了step2,
即读取到头标签了,其实你是很人读一片文章流程一样,只不过我们脑中有个印象<xxx>是头标签了,我们要做什么,独到 头标签的最后一个符号">"
下面进去值域,独到了字窜的话就调用了foundCharacters:(NSString *)string,如果又读到<xxx>这样的,那就又是头标签了。——>
step5就是读到开始尾标签符号了。
最后一个方法
foundCDATA:(NSData *)CDATABlock,其实也是一个格式
<content:encoded> <![CDATA[ <img src="http://img1.douban.com/mpic/s10489201.jpg" style="float:right;margin-left:16px"/><a href="http://www.douban.com/people/maldini/">减卐肥™</a>评论: <a href="http://movie.douban.com/subject/6799191//">搜索</a><br/> <br/>评价: 力荐<br/><br/> ]]> </content:encoded>
好了,方法和流程大致了解了,拿一个我最近遇到的例子,好多时候,我们会遇到这样读取一组类似于json中数组形式的数据
<channel> <title>我是标题</title> <link>http://write.blog.csdn.net/postedit</link> <description>...</description> <language>zh-cn</language> <pubDate>Fri, 03 Aug 2012 06:20:31 GMT</pubDate> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> <item>...</item> </channel>
1 #pragma mark xmlparser 2 //step 1 :准备解析 3 - (void)parserDidStartDocument:(NSXMLParser *)parser 4 { 5 // NSLog(@"%@",NSStringFromSelector(_cmd) ); 6 7 parserObjects = [[NSMutableArray alloc]init]; 8 } 9 //step 2:准备解析节点 10 - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict 11 { 12 // NSLog(@"%@",NSStringFromSelector(_cmd) ); 13 14 self.currentText = [[NSMutableString alloc]init]; 15 [currentText release]; 16 if ([elementName isEqualToString:@"item"]) { 17 NSMutableDictionary *newNode = [[ NSMutableDictionary alloc ] initWithCapacity : 0 ]; 18 twitterDic = newNode; 19 [parserObjects addObject :newNode]; 20 [newNode release]; 21 } 22 else if(twitterDic) { 23 NSMutableString *string = [[ NSMutableString alloc ] initWithCapacity : 0 ]; 24 [twitterDic setObject :string forKey :elementName]; 25 [string release ]; 26 currentElementName = elementName; 27 } 28 29 30 } 31 //step 3:获取首尾节点间内容 32 - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string 33 { 34 NSLog(@"%@",NSStringFromSelector(_cmd) ); 35 [currentText appendString:string]; 36 } 37 38 //step 4 :解析完当前节点 39 - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName 40 { 41 if ([elementName isEqualToString:@"item"]) { 42 twitterDic = nil; 43 }else 44 if ([elementName isEqualToString:currentElementName]) { 45 46 if ([elementName isEqualToString:@"description"] 47 ||[elementName isEqualToString:@"content:encoded"]) { 48 [twitterDic setObject:Cdata forKey:currentElementName]; 49 }else { 50 [twitterDic setObject:currentText forKey:currentElementName]; 51 } 52 } 53 54 } 55 56 //step 5;解析结束 57 - (void)parserDidEndDocument:(NSXMLParser *)parser 58 { 59 } 60 //获取cdata块数据 61 - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock 62 { 63 Cdata =[[NSString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding]; 64 }
1 - (void)recurrence:(TBXMLElement *)element { 2 3 NSString *eleName = [TBXML elementName:element]; 4 NSString *eleText = [TBXML textForElement:element]; 5 if ([eleName isEqualToString:@"item"]) { 6 self recurrence:element 7 } 8 do { 9 10 NSString *eleName = [TBXML elementName:element]; 11 NSString *eleText = [TBXML textForElement:element]; 12 13 //递归处理子树 14 if (element->firstChild) { 15 NSLog(@"<%@>:",eleName);// Display the name of the element 16 17 [self recurrence:element->firstChild]; 18 }else { 19 NSLog(@"<%@>:%@",eleName,eleText);// Display the name of the element 20 21 TBXMLElement *parent = element->parentElement; 22 if ([[TBXML elementName:parent] isEqualToString:@"item"]) { 23 NLRssInfo *info = [[[NLRssInfo alloc]init] autorelease]; 24 25 if ([eleName isEqualToString:@"title"]) { 26 info.title = eleText; 27 } 28 29 [dataArr addObject:info]; 30 } 31 32 } 33 34 //迭代处理兄弟树 35 } while ((element = element->nextSibling)); 36 } 37 38 - (void) dealloc 39 { 40 [title release]; 41 [subtitle release]; 42 [super dealloc]; 43 }