网络应用中的数据解析,因为最近的应用,无论是Android的和ios平台的,一直用也是建议用的都是Json解析,
xml解析都有点被遗忘了。
然后最近自己在做着玩一个ios的小应用,涉及网络数据的抓取,一些网站可能都提供了自己api平台,这些一般都是支持
我们对于数据协议格式的设定的。但是后来我在找寻到一些Rss资源时,发现返回的数据都是xml格式的,
因此,那就只好用xml解析了。
XML解析其实这个概念出现了算够久了,以前javaweb什么到处都在用。这边我们主要大致介绍下,然后在在ios编程如何使用。
XML解析一般分两种模式SAX和DOM,事件和文档。具体解析google去吧,有详细。不过看了下面的两个例子,一般就了解了。
一:XML解析之SAX解析,以及对NSXMLParser的应用。
sax解析说白了,就是一个事物模型解析,从头开始读取文档然后根据读取到的头标签标签时要怎么处理,读完头标签后,理论上是读取标签值了,
然后读取后遇到结束标签等
简单举个例子
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" version="2.0"> 头标签,里面的xmlns,可以看成是属性
<channel>
<title>呵呵呵呵</title>结束标签,中间的“呵呵呵呵”是首尾标签标签值空间
.......
好了,那么在ios开发中如何使用。
SDK本身是提供了NSXMLParser解析器。
- -(BOOL)parser:(NSString*)string
- {
- //系统自带的
- NSXMLParser *par = [[[NSXMLParser alloc] initWithData:[string dataUsingEncoding:NSUTF8StringEncoding]]autorelease];
- [par setDelegate:self];//设置NSXMLParser对象的解析方法代理
- return [par parse];//调用代理解析NSXMLParser对象,看解析是否成功 }
- }
- #pragma mark xmlparser
- //step 1 :准备解析
- - (void)parserDidStartDocument:(NSXMLParser *)parser
- {
- // NSLog(@"%@",NSStringFromSelector(_cmd) );
- }
- //step 2:准备解析节点
- - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
- {
- // NSLog(@"%@",NSStringFromSelector(_cmd) );
- }
- //step 3:获取首尾节点间内容
- - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
- {
- NSLog(@"%@",NSStringFromSelector(_cmd) );
- }
- //step 4 :解析完当前节点
- - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
- {
- NSLog(@"%@",NSStringFromSelector(_cmd) );
- }
- //step 5;解析结束
- - (void)parserDidEndDocument:(NSXMLParser *)parser
- {
- // NSLog(@"%@",NSStringFromSelector(_cmd) );
- }
- //获取cdata块数据
- - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
- {
- // NSLog(@"%@",NSStringFromSelector(_cmd) );
- }
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>...