如果需要了解关于文档对象模型和XML的介绍,参看 http://www.cnblogs.com/xinchrome/p/4890723.html

读取XML

上代码:

NSFileHandle *file = [NSFileHandle fileHandleForReadingAtPath:name];
NSData *data = [file readDataToEndOfFile];
[file closeFile]; //create xml parser
NSXMLParser *parser;
parser = [[NSXMLParser alloc] initWithData:data]; [parser setShouldProcessNamespaces:NO];
[parser setShouldReportNamespacePrefixes:NO];
[parser setShouldResolveExternalEntities:NO];
[parser setDelegate:self]; //start parse
[parser parse];

我们要把文件读取到NSData中,有两种方式,一种是 [[NSData alloc]initWithContentsOfFile:path],另一种是利用文件句柄直接返回一个NSData对象;然后我们用一个parser对象解析data中的数据。

iOS中的XML解析与java语言使用的方式不一样,必须要使用代理的方式,上代码:

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
NSLog(@"=======start element:%@=========", elementName);
if ([elementName isEqualToString:@"skin"]) {
NSLog(@"skin name=%@", [attributeDict objectForKey:@"name"]);
} else if ([elementName isEqualToString:@"string"]) {
NSLog(@"string name= %@ id=%@", [attributeDict objectForKey:@"name"], [attributeDict objectForKey:@"id"]);
}
}

解析文档对象模型

解析 XML 通常有两种方式:DOM 和 SAX,iOS SDK提供了NSXMLParser和libxml2两个类库:
DOM解析XML时,读入整个XML文档并构建一个驻留内存的树结构(节点树),通过遍历树结构可以检索任意XML节点,读取它的属性和值。而且通常情况下,可以借助XPath,直接查询XML节点。
SAX解析XML,是基于事件通知的模式,一边读取XML文档一边处理,不必等整个文档加载完之后才采取操作,当在读取解析过程中遇到需要处理的对象,会发出通知对其进行处理。

特别需要注意的是,在SAX方式中,parser对象只负责解析并发送消息给代理,不会构建文档树!树必须由代理对象自己来构造。上代码:

#import <UIKit/UIKit.h>
#import "XMLElement.h" @interface ViewController : UIViewController <NSXMLParserDelegate> // 解析器对象
@property (nonatomic,strong) NSXMLParser *parser; // 根元素
@property (nonatomic,strong) XMLElement *rootElement; // 当前的元素
@property (nonatomic,strong) XMLElement *currentElementPointer; @end
#import "ViewController.h"
#import "UIColor+ColorWithARGB.h"
@interface ViewController ()
@end @implementation ViewController -(id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if(self != nil){
self.title = @"XML解析";
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
self.view.backgroundColor = [UIColor r:0xA5 g:0xA5 b:0x52];
NSString *xmlFilePath = [[NSBundle mainBundle]pathForResource:@"person" ofType:@"xml"];
NSData *data = [[NSData alloc]initWithContentsOfFile:xmlFilePath];
self.parser = [[NSXMLParser alloc]initWithData:data];
self.parser.delegate = self;
if([self.parser parse]){
NSLog(@"The XML is Parsed");
NSMutableString *str = [[NSMutableString alloc]init];
[str appendFormat:@"%@\n",self.rootElement.name];
NSMutableArray *subs = self.rootElement.subElements;
for(int i = ;i < [subs count];i++){
XMLElement *personElement = [subs objectAtIndex:i];
[str appendFormat:@"\tname:%@",personElement.name];
[str appendFormat:@",text:%@\n",personElement.text];
NSArray *subPersonElements = personElement.subElements;
for(int j = ;j < [subPersonElements count];j++){
XMLElement *subElement = [subPersonElements objectAtIndex:j];
[str appendFormat:@"\t\tname:%@",subElement.name];
[str appendFormat:@",text:%@\n",subElement.text];
}
}
NSLog(@"======解析结果:%@" ,str);
}else{
NSLog(@"Failed to parse the XML");
}
} - (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
// 文档开始
-(void)parserDidStartDocument:(NSXMLParser *)parser
{
self.rootElement = nil;
self.currentElementPointer = nil;
}
// 文档结束
-(void)parserDidEndDocument:(NSXMLParser *)parser
{
self.currentElementPointer = nil;
}
// 元素开始
- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict
{
if(self.rootElement == nil){
self.rootElement = [[XMLElement alloc]init];
self.currentElementPointer = self.rootElement;
}else{
XMLElement *newElement = [[XMLElement alloc]init];
newElement.parent = self.currentElementPointer;
[self.currentElementPointer.subElements addObject:newElement];
self.currentElementPointer = newElement;
}
self.currentElementPointer.name = elementName;
self.currentElementPointer.attributes = attributeDict;
NSLog(@"name:%@" , elementName);
}
// 元素结束
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName
{
self.currentElementPointer = self.currentElementPointer.parent;
NSLog(@"end name:%@" , elementName);
}
// 解析文本,会多次解析,每次只解析1000个字符,如果多月1000个就会多次进入这个方法
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string
{
if([self.currentElementPointer.text length] > ){
self.currentElementPointer.text = [self.currentElementPointer.text stringByAppendingString:string];
}else{
self.currentElementPointer.text = [NSMutableString stringWithString:string];
}
NSLog(@"string:%@" , string);
} @end

libxml2

  上面的代码十分冗长,因为不能用parser对象直接获得文档结构。所以我们采用libxml2,http://xmlsoft.org/,它是一套默认包含在iOS SDK中的开源类库,它是基于C语言的API,所以使用起来可能不如NSXML方便。这套类库同时支持DOM和SAX解析,libxml2的SAX解析方式还是非常酷的,因为它可以边读取边解析,尤其是在从网上下载一个很大的XML文件,就可以一边下载一边对已经下载好的内容进行解析,极大的提高解析效率。

  但是基于C语言的api在代码中显得很不协调。

GDataXML类库

  如果需要经常解析XML,第三方类库能带来更多方便。

GDataXMLDocument读取xml文件,并且解析成为dom对象:

NSString *filePath = [[NSBundle mainBundle] pathForResource:@"test" ofType:@"xml"];
NSData *xmlData = [[NSMutableData alloc] initWithContentsOfFile:filePath];
NSError *error;
GDataXMLDocument *doc = [[GDataXMLDocument alloc] initWithData:xmlData options: error:&error];
if (doc == nil) { return nil; }
NSLog(@"%@", doc.rootElement);
//[doc release];
//[xmlData release];

IOS的XML文件解析,利用了NSData和NSFileHandle的更多相关文章

  1. android基础知识13:AndroidManifest.xml文件解析

    注:本文转载于:http://blog.csdn.net/xianming01/article/details/7526987 AndroidManifest.xml文件解析. 1.重要性 Andro ...

  2. Python实现XML文件解析

    1. XML简介 XML(eXtensible Markup Language)指可扩展标记语言,被设计用来传输和存储数据,已经日趋成为当前许多新生技术的核心,在不同的领域都有着不同的应用.它是web ...

  3. 通过正则表达式实现简单xml文件解析

    这是我通过正则表达式实现的xml文件解析工具,有些XHTML文件中包含特殊符号,暂时还无法正常使用. 设计思路:常见的xml文件都是单根树结构,工具的目的是通过递归的方式将整个文档树装载进一个Node ...

  4. 八、Android学习第七天——XML文件解析方法(转)

    (转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 八.Android学习第七天——XML文件解析方法 XML文件:exten ...

  5. Android之AndroidManifest.xml文件解析

    转自:Android学习笔记之AndroidManifest.xml文件解析 一.关于AndroidManifest.xml AndroidManifest.xml 是每个android程序中必须的文 ...

  6. 9.XML文件解析

    一.XML简介 XML(EXtensible Markup Language),可扩展标记语言 特点:XML与操作系统.编程语言的开发平台无关 实现不同系统之间的数据交换 作用:数据交互 配置应用程序 ...

  7. Python3将xml文件解析为Python对象

    一.说明 从最开始写javascript开始,我就很烦感使用getElementById()等函数来获取节点的方法,获取了一个节点要访问其子孙节点要么child半天要么就再来一个getElementB ...

  8. XML文件解析-DOM4J方式和SAX方式

    最近遇到的工作内容都是和xml内容解析相关的. 1图片数据以base64编码的方式保存在xml的一个标签中,xml文件通过接口的方式发送给我,然后我去解析出图片数据,对图片进行进一步处理. 2.xml ...

  9. java基础之概谈xml文件解析

    XML已经成为一种非常通用的数据交换格式,它的平台无关性,语言无关性,系统无关性,给数据集成与交互带来了极大的方便. 诸多web应用框架,其可配置的编程方式,给我们的开发带来了非常大程度的便捷,但细细 ...

随机推荐

  1. 初识PCA数据降维

    PCA要做的事降噪和去冗余,其本质就是对角化协方差矩阵. 一.预备知识 1.1 协方差分析 对于一般的分布,直接代入E(X)之类的就可以计算出来了,但真给你一个具体数值的分布,要计算协方差矩阵,根据这 ...

  2. cookie中转注入实战

    随着网络安全技术的发展,SQL注入作为一种很流行的攻击方式被越来越多的人所知晓.很多网站也都对SQL注入做了防护,许多网站管理员的做法就是添加一个防注入程序.这时我们用常规的手段去探测网站的SQL注入 ...

  3. java代码判断图片文件格式, 不是根据文件后缀来判断。

    public static final String TYPE_JPG = "jpg"; public static final String TYPE_GIF = "g ...

  4. java调用dll文件中的类型转换

    char *转String   (env)->NewStringUTF("the content you want to type in"); char *转jbyteArr ...

  5. POJ 3228 Gold Transportation(带权并查集,好题)

    参考链接:http://www.cnblogs.com/jiaohuang/archive/2010/11/13/1876418.html 题意:地图上某些点有金子,有些点有房子,还有一些带权路径,问 ...

  6. .net中的认证(authentication)与授权(authorization)

    “认证”与“授权”是几乎所有系统中都会涉及的概念,通俗点讲: 1.认证(authentication) 就是 "判断用户有没有登录?",好比windows系统,没登录就无法使用(不 ...

  7. EXPRESS.JS再出发

    那个那个MEAN的书,看得七七八八,有了大概,现在就要一样一样的加深记忆啦.. EXPRSS.JS的东东,网上有现成入门书籍: 第一期代码测试: var express = require('expr ...

  8. lintcode 中等题:N Queens N皇后问题

    题目: N皇后问题 n皇后问题是将n个皇后放置在n*n的棋盘上,皇后彼此之间不能相互攻击.<不同行,不同列,不同对角线> 给定一个整数n,返回所有不同的n皇后问题的解决方案. 每个解决方案 ...

  9. lintcode:Plus One 加一

    题目: 加一 给定一个非负数,表示一个数字数组,在该数的基础上+1,返回一个新的数组. 该数字按照大小进行排列,最大的数在列表的最前面. 样例 给定 [1,2,3] 表示 123, 返回 [1,2,4 ...

  10. 移植 FFMPEG-2.2.4 -(编译)

    源码下载:http://www.ffmpeg.org/download.html编译安装: http://trac.ffmpeg.org/wiki/CompilationGuide/Ubuntu su ...