关于网络开发中XML的使用
一、关于XML
XML和JSON一样,也是网络开发中常用的数据交换格式。XML全称是Extensible Markup Language,翻译过来就是“可扩展标记语言”,一般也经常叫做XML文档。
XML的一般格式类似于下面:
XML文档一般由以下三部分组成:
1、文档声明
2、元素(Element)
3、属性(Attribute)
1、文档声明
在XML文档的最前面必须有文档声明,用来声明XML文档的类型。例如:
version属性说明当前XML文档的版本,encoding属性说明当前文档的字符编码。
2、元素(Element)
一个元素包括开始标签和结束标签。
a.元素有内容:视频
b.元素没有内容:
c.元素没有内容的简写:
一个元素可以不交叉的嵌套若干子元素,例如:
规范的XML文档最多只有一个根元素,其他元素都是根元素的子孙元素。XML中的所有空格和换行都会被当做具体内容来处理。
3、属性(Attribute)
一个元素可以有多个属性:
video元素有name和length属性,属性的值必须用双引号或者单引号括住。属性表示的信息也可以用子元素来表示。
二、XML解析
XML的解析方式有两种:
1、DOM
一次性将整个XML文档加载进内存,比较适合解析较小文件。
2、SAX
从根元素开始,按顺序一个元素一个元素往下解析,比较适合解析大文件。
在iOS中,XML的解析方案有以下几种:
1、NSXMLParser:SAX方式解析,使用简单,苹果原生的解析方案。
2、libxml2:第三方框架,纯C语言,默认包含在iOS SDK中,同时支持DOM和SAX方式解析。
3、GDataXML:第三方框架,由Google开发,DOM方式解析,基于libxml2。
在解析XML的时候,建议大文件选择NSXMLParser或者libxml2,小文件选择GDataXML。下面用代码来说一下这三种方案的使用方法。
1、NSXMLParser
/** * 获取XML数据 */ - (void)getXML { NSString *url = @"http://localhost:8080/MJServer/login?username=123&pwd=123&method=get&type=XML"; NSURL *URL = [NSURL URLWithString:url]; NSURLRequest *request = [NSURLRequest requestWithURL:URL]; [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) { NSString *str = [[NSString alloc] initWithData:data encoding:NSUTF8StringEncoding]; NSLog(@"str:%@", str); [self parserXML0:data]; }]; }
下面是这三种方案的解析示例:(使用NSXMLParser)
/** * 使用NSXMLParser */ - (void)parserXML0:(NSData *)data { //传入数据xml数据,创建解析器 NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data]; //设置代理,监听解析过程 parser.delegate = self; //开始解析 [parser parse]; } #pragma mark - NSXMLParser delegate callback /** * 扫描到文档的开始时调用,开始解析 * * @param parser parser description */ - (void)parserDidStartDocument:(NSXMLParser *)parser { NSLog(@"parserDidStartDocument"); } /** * 扫描到文档的结尾时调用,解析完毕 * * @param parser parser description */ - (void)parserDidEndDocument:(NSXMLParser *)parser { NSLog(@"parserDidEndDocument"); } /** * 扫描到元素的开始时调用 * * @param parser parser description * @param elementName 元素名字 * @param namespaceURI 节点的命名空间 * @param qName 命名空间限定的本地名称 * @param attributeDict attributeDict description */ - (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict { NSLog(@"发现元素开始, 元素名:%@ ", elementName); } /** * 扫描到元素的结束时调用 * * @param parser parser description * @param elementName 元素名称 * @param namespaceURI 节点的命名空间 * @param qName 命名空间限定的本地名称 */ - (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName { NSLog(@"发现元素结束, 元素名:%@ ", elementName); } /** * 当XML节点有值时,进入此方法 * * @param parser * @param string 元素值 */ - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string { NSLog(@"元素内容:%@", string); } /** * 发现CDATA时,进入此方法 * * @param parser * @param CDATABlock CDATA块 */ - (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock { }
2、GDataXML
使用GDataXML之前需要进行配置
a.先导入libxml2库
b.设置libxml2的头文件搜索路径--在Header Serach Paths中加入/usr/include/libxml2
c.设置链接参数,自动链接libxml2库--在Other Linker Flags中加入-lxml2
d.由于GDataXML是非ARC的,因此得设置编译参数
最后把GDataXMLNode.h和GDataXMLNode.m添加到项目里面,我的项目结构如下:
OK,试着编译一下,如果按照这个步骤来的,应该是没有问题了。下面开始解析。
/** * 使用GDataXML解析 * * @param data data description */ - (void)parserXML1:(NSData *)data { GDataXMLDocument *xmlDoc = [[GDataXMLDocument alloc] initWithData:data options:0 error:nil]; GDataXMLElement *xmlEle = [xmlDoc rootElement]; NSArray *array = [xmlEle children]; for (GDataXMLElement *ele in array) { NSLog(@"status:%@", [ele stringValue]); } }
输出结果:
2015-07-06 11:26:42.481 HttpDemo[2576:607] str:登录成功2015-07-06 11:26:42.482 HttpDemo[2576:607] status:登录成功