网络数据的XML解析
网络应用中的数据解析,因为最近的应用,无论是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>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- <item>...</item>
- </channel>
一般来说,我们要的数据其实都是这20个item,对吧,每个item下都是相同的3个标签,title,author,time。形式上
- #pragma mark xmlparser
- //step 1 :准备解析
- - (void)parserDidStartDocument:(NSXMLParser *)parser
- {
- // NSLog(@"%@",NSStringFromSelector(_cmd) );
- parserObjects = [[NSMutableArray alloc]init];
- }
- //step 2:准备解析节点
- - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
- {
- // NSLog(@"%@",NSStringFromSelector(_cmd) );
- self.currentText = [[NSMutableString alloc]init];
- [currentText release];
- if ([elementName isEqualToString:@"item"]) {
- NSMutableDictionary *newNode = [[ NSMutableDictionary alloc ] initWithCapacity : 0 ];
- twitterDic = newNode;
- [parserObjects addObject :newNode];
- [newNode release];
- }
- else if(twitterDic) {
- NSMutableString *string = [[ NSMutableString alloc ] initWithCapacity : 0 ];
- [twitterDic setObject :string forKey :elementName];
- [string release ];
- currentElementName = elementName;
- }
- }
- //step 3:获取首尾节点间内容
- - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
- {
- NSLog(@"%@",NSStringFromSelector(_cmd) );
- [currentText appendString:string];
- }
- //step 4 :解析完当前节点
- - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
- {
- if ([elementName isEqualToString:@"item"]) {
- twitterDic = nil;
- }else
- if ([elementName isEqualToString:currentElementName]) {
- if ([elementName isEqualToString:@"description"]
- ||[elementName isEqualToString:@"content:encoded"]) {
- [twitterDic setObject:Cdata forKey:currentElementName];
- }else {
- [twitterDic setObject:currentText forKey:currentElementName];
- }
- }
- }
- //step 5;解析结束
- - (void)parserDidEndDocument:(NSXMLParser *)parser
- {
- }
- //获取cdata块数据
- - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
- {
- Cdata =[[NSString alloc] initWithData:CDATABlock encoding:NSUTF8StringEncoding];
- }
对于上面代码说几点
注意这个代理方法的注释
// This returns the string of the characters encountered thus far. You may not necessarily get the longest character run. The parser reserves the right to hand these to the delegate as potentially many calls in a row to -parser:foundCharacters:
下面是google翻译。
这将返回迄今为止遇到的字符的字符串。你不一定得到的最长字符运行。解析器有权交行解析器可能多次呼吁这些委托:foundCharacters:
这个说明,在获取一个标签首尾间的字符数据时,这个方法可能被调用多次。
举个我碰到的最简单的列子
<copyright>© 2012, douban.com.</copyright>
我在解析这个节点时,上面方法就调用了两次,
第一次只返回&,紧接着第二次返回copy; 2012, douban.com.
因此你如果要获取完整的的,应该用string的append方法来获取完整的一条记录。
- //- (void)recurrence:(TBXMLElement *)element {
- //
- // NSString *eleName = [TBXML elementName:element];
- // NSString *eleText = [TBXML textForElement:element];
- // if ([eleName isEqualToString:@"item"]) {
- // self recurrence:element
- // }
- //
- //
- //
- //
- // do {
- //
- // NSString *eleName = [TBXML elementName:element];
- // NSString *eleText = [TBXML textForElement:element];
- //
- // //递归处理子树
- // if (element->firstChild) {
- // NSLog(@"<%@>:",eleName);// Display the name of the element
- //
- // [self recurrence:element->firstChild];
- // }else {
- // NSLog(@"<%@>:%@",eleName,eleText);// Display the name of the element
- //
- // TBXMLElement *parent = element->parentElement;
- // if ([[TBXML elementName:parent] isEqualToString:@"item"]) {
- // NLRssInfo *info = [[[NLRssInfo alloc]init] autorelease];
- //
- // if ([eleName isEqualToString:@"title"]) {
- // info.title = eleText;
- // }
- //
- //
- // [dataArr addObject:info];
- // }
- //
- // }
- //
- //
- // //迭代处理兄弟树
- // } while ((element = element->nextSibling));
- //}
递归遍历,常规的树操作,具体内容可以网上搜搜,很多。
网络数据的XML解析的更多相关文章
- IOS-网络(JSON解析数据与XML解析数据)
一.JSON解析数据 // // VideoModel.h // IOS_0130_网络视频 // // Created by ma c on 16/1/30. // Copyright © 2016 ...
- 网络热恋之XML解析
XML 可扩展标记语言 用于标记电子文件使其具有结构性的标记语言,可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定义的源语言 易读性高,编码手写难度小,数据量大 NSXMLPars ...
- iOS 网络编程:XML解析
1 XML文档结构 1.1 简介 XML 指可扩展标记语言(eXtensible Markup Language).XML 被设计用来传输和存储数据.其非常像HTML的标记语言,但与之不同的是,XML ...
- 分布式缓存系统 Memcached 状态机之网络数据读取与解析
整个状态机的基本流程如下图所示,后续分析将按该流程来进行. 接上节分解,主线程将接收的连接socket分发给了某工作线程,然后工作线程从任务队列中取出该连接socket的CQ_ITEM,开始处理该连接 ...
- XML解析之DOM详解及与SAX解析方法的比较
XML解析(DOM) XML文件解析方法介绍 我们所用到的NSXMLParser是采用SAX方法解析 SAX(Simple API for XML) 只能读,不能修改,只能顺序访问,适合解析大型XML ...
- 2016 - 1- 23 iOS中xml解析 (!!!!!!!有坑要解决!!!!!!)
一: iOS中xml解析的几种方式简介 1.官方原生 NSXMLParser :SAX方式解析,使用起来比较简单 2.第三方框架 libxml2 :纯C 同时支持DOM与SAX GDataXML: D ...
- JavaEE:XML解析
XML解析技术概述1.XML 技术主要企业应用1)存储和传输数据 2)作为框架的配置文件2.使用xml 存储和传输数据涉及到以下两点1)通过程序生成xml2)读取xml 中数据 ---- xml 解析 ...
- XML解析【介绍、DOM、SAX详细说明、jaxp、dom4j、XPATH】
什么是XML解析 前面XML章节已经说了,XML被设计为"什么都不做",XML只用于组织.存储数据,除此之外的数据生成.读取.传送等等的操作都与XML本身无关! XML解析就是读取 ...
- Android从网络中获取xml文件并解析数据
public class XmlwebData { @SuppressLint("UseValueOf") public static List<Person> get ...
随机推荐
- 联想VIBE UI 固件ROM刷机包集合
固件下载_联想乐问吧http://ask.lenovomobile.com/?c-157.html 联想VIBE UI 固件ROM刷机包集合 悬赏分:0 解决时间:2014/09/12 15: ...
- 能源项目xml文件 -- app-context.xml
<?xml version="1.0" encoding="UTF-8"?> <beans xmlns="http://www.sp ...
- 【EasyX】RGB to Gray
code: #include <graphics.h> #include <conio.h> void main() { initgraph(, ); // 读取图片 load ...
- validate插件:验证密码没有空格 用户名是5-10位 至少包含数字和大小写字母中的两种字符
//校验密码是否含有空格 jQuery.validator.addMethod("notblank", function(value, element) { var pwdblan ...
- Hadoop-env.sh[翻译]
说明: 某天 ,把hadoop-env.sh的注释看了看 , 感觉受益匪浅,于是想要写一篇告诉大家,文档是最靠谱的,鉴于我的水平有限,只能翻译大概,切勿吐槽,提建议请留言 摘要: 1.这个文件中只有J ...
- SQL批量删除与批量插入
批量删除: DELETE FROM MyTable WHERE ID IN (1,2); 批量插入: INSERT INTO MyTable(ID,NAME) VALUES(1,'123');INSE ...
- Lambda表达式与Function接口
Lambda表达式是一个匿名函数.C++ 11和 java 8 相继引入了有关对Lambda表达式的支持. Lambda表达式对于高级语言而言并不是必要的,对于Java而言它的功能和一个简易的接口差不 ...
- Asp.Net MVC EF各版本区别
2009年發行ASP.NET MVC 1.0版 2010年發行ASP.NET MVC 2.0版,VS2010 2011年發行ASP.NET MVC 3.0版+EF4,需要.Net4.0支持,VS2 ...
- windows系统下Tomcat与Apache服务器集成
说明:此文是看书真实试验成功的,书中提到了不同版本不兼容的问题,但是很荣幸我没碰到,此例可供参考. 本文假设你已经有了java环境和tomcat,你已经熟悉tomcat的应用. Jdk 1.7.0_5 ...
- 转载:完全卸载oracle11g步骤
完全卸载oracle11g步骤: 1. 开始->设置->控制面板->管理工具->服务 停止所有Oracle服务. 2. 开始->程序->Oracle - OraHo ...