XML解析

在iPhone开发中,XML的解析有很多选择,iOS SDK提供了NSXMLParser和libxml2两个类库,另外还有很多第三方类库可选,例如TBXML、TouchXML、KissXML、TinyXML和GDataXML。这篇文章使用了NSXMLParser。

解析 XML 通常有两种方式,DOM 和 SAX:

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

    NSXMLParser是基于SAX的解析方式。NSXMLParser采用了委托设计模式,因此他的实现类需要采用协议并支持委托。NSXMLParser解析XML需要委托NSXMLParserDelegate实现。

1、初始化NSXMLParser

要使用NSXMLParser要先创建它,设置各种属性,主要用到以下几个方法:

initWithContentsOfURL  通过NSURL创建解析器

initWithData                 通过NSData创建解析器

setDelegate                  为解析器定义委托

parse                           运行解析器

  1. NSXMLParser *parser=[[NSXMLParser alloc] initWithData:[xml dataUsingEncoding:NSUTF8StringEncoding]];  
  2.    
  3.    NSXMLParser *parser=[[NSXMLParser alloc] initWithContentsOfURL:[NSURL URLWithString:@"http://earthquake.usgs.gov/earthquakes/catalogs/7day-M2.5.xml"]];  
  4.    
  5.  [parser setDelegate:self];//设置NSXMLParser对象的解析方法代理  
  6.  [parser setShouldProcessNamespaces:NO];  
  7.  [parser parse];//开始解析  

2、委托方法

主要使用一下委托方法:

  1. //发现元素开始符的处理函数  (即报告元素的开始以及元素的属性)   
  2. - (void)parser:(NSXMLParser *)parser   
  3.         didStartElement:(NSString *)elementName   
  4.         namespaceURI:(NSString *)namespaceURI   
  5.         qualifiedName:(NSString *)qName   
  6.         attributes:(NSDictionary *)attributeDict  
  7.   
  8. //处理标签包含内容字符 (报告元素的所有或部分内容)   
  9. - (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string  
  10.   
  11. //发现元素结束符的处理函数,保存元素各项目数据(即报告元素的结束标记)  
  12. - (void)parser:(NSXMLParser *)parser   
  13.         didEndElement:(NSString *)elementName   
  14.         namespaceURI:(NSString *)namespaceURI   
  15.         qualifiedName:(NSString *)qName  
  16.   
  17. //报告解析的结束   
  18. - (void)parserDidEndDocument:(NSXMLParser *)parser  
  19.   
  20. //报告不可恢复的解析错误  
  21. - (void)paser:parserErrorOccured 


// xml文件的样式 的样式有多种样式,标准的是把数据存放在子节点中,还有就是比较简单的读取就是把数据直接存在属性里面

// 第一种,这是自己写出来的一种,把数据存储在子节点中,读取相对麻烦一些
IOS <wbr>XML数据的解析


// 第二种是从中国气象网的api上街区出来的一段,是把数据存储在了属性中,比较容易读取数据
IOS <wbr>XML数据的解析




// 下面是解析第一种样式的代码:
// 头文件

#import

@interface RootViewController : UIViewController<</span>NSXMLParserDelegate>

#pragma mark - 声明--属性

@property (nonatomicretainNSMutableArray *messageeListArray; // 数据存储的地方

@property (nonatomic, retain) NSString *fromTagFlag; // 开始标签

@end


// 实现文件

#import "RootViewController.h"

@interface RootViewController ()

@end

@implementation RootViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil

{

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {

        // Custom initialization

    }

    return self;

}


- (void)viewDidLoad

{

    [super viewDidLoad];


 

    // 获取xml字符串类型文件名

    NSString *xmlDocPath = [[NSBundle mainBundle] pathForResource:@"document"ofType:@"xml"];

    // 把字符串类型的网址转为NSURL类型

    NSURL *url =[[NSURL allocinitFileURLWithPath:xmlDocPath];


    // 使用url实例化网络请求实例

    NSURLRequest *request = [NSURLRequest requestWithURL:url];

    // 同步读取到网络上的数据

    NSData *urlData = [NSURLConnection sendSynchronousRequest:requestreturningResponse:nil error:nil];

    

    

    // 实例化一个具体的解析类对象

    NSXMLParser *xmlParser = [[NSXMLParser allocinitWithData:urlData];


    // 设置该解析类对象的代理

    xmlParser.delegate = self;

    // 调用方法开始解析xml文件

    [xmlParser parse];

    

}


#pragma mark - NSXMLParser Delegate -

#pragma mark 文档开始读取

- (void)parserDidStartDocument:(NSXMLParser *)parser {

    // 实例化存储数据的数组

    self.messageeListArray = [NSMutableArray array];

}

#pragma mark 解析标签开始

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {

    // 首先用属性fromTagFlag获取ElementName,供后面使用

    self.fromTagFlag = elementName;

    // 判断

    if ([elementName isEqualToString:@"Message"]) {

        NSString *identifier = [attributeDict objectForKey:@"id"];

        NSMutableDictionary *oneDic = [NSMutableDictionary dictionary];

        [oneDic setObject:identifier forKey:@"id"];

        [self.messageeListArray addObject:oneDic];

    }

}

#pragma mark 获取到标签对应的数据

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {

    // 剔除获取的文本中空格和换行

    string = [string stringByTrimmingCharactersInSet:[NSCharacterSetwhitespaceAndNewlineCharacterSet]];

    NSMutableDictionary *dict = [self.messageeListArray lastObject];

    

    // 判断from标签

    if ([_fromTagFlag isEqualToString:@"from"] && dict) {

        [dict setObject:string forKey:@"from"];

    }

    // 判断CDate标签

    if ([_fromTagFlag isEqualToString:@"CDate"] && dict) {

        [dict setObject:string forKey:@"CDate"];

    }

    // 判断Content标签

    if ([_fromTagFlag isEqualToString:@"Content"] && dict) {

        [dict setObject:string forKey:@"Content"];

    }

}

#pragma mark - 解析标签结束

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

    self.fromTagFlag = nil;

}

#pragma mark 文档结束读取

- (void)parserDidEndDocument:(NSXMLParser *)parser {

    // 打印获取到的数据的数组

    NSLog(@"%@", self.messageeListArray);

}



#pragma mark - 重写----dealloc方法

- (void)dealloc {

    [_messageeListArray release], _messageeListArray = nil;

    [_fromTagFlag release], _fromTagFlag = nil;

    

    // 调用父类的dealloc方法

    [super dealloc];

}

@end



// 第二种xml样式解析的代码
// 头文件

#import

@interface RootViewController : UIViewController<</span>NSXMLParserDelegate>

#pragma mark - 声明--属性

@property (nonatomicretainNSMutableArray *messageeListArray; // 数据存储的地方

@property (nonatomic, retain) NSString *fromTagFlag; // 开始标签

@end


// 实现文件

#import "RootViewController.h"

@interface RootViewController ()

@end

@implementation RootViewController

- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle*)nibBundleOrNil

{

    self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];

    if (self) {

        // Custom initialization

    }

    return self;

}


- (void)viewDidLoad

{

    [super viewDidLoad];


    

   

    // 准备网址的字符串数据

    NSString *urlString =@"http://flash.weather.com.cn/wmaps/xml/beijing.xml";

    // 把字符串类型的网址转为NSURL类型

    NSURL *url1 = [[NSURL allocinitWithString:urlString];

    // 使用url实例化网络请求实例

    NSURLRequest *request = [NSURLRequest requestWithURL:url1];

    // 同步读取到网络上的数据

    NSData *urlData = [NSURLConnection sendSynchronousRequest:requestreturningResponse:nil error:nil];

    

    

    // 实例化一个具体的解析类对象

    NSXMLParser *xmlParser = [[NSXMLParser allocinitWithData:urlData];


    // 设置该解析类对象的代理

    xmlParser.delegate = self;

    // 调用方法开始解析xml文件

    [xmlParser parse];

    

}


#pragma mark - NSXMLParser Delegate -

#pragma mark 文档开始读取

- (void)parserDidStartDocument:(NSXMLParser *)parser {

    // 实例化存储数据的数组

    self.messageeListArray = [NSMutableArray array];

}

#pragma mark 解析标签开始

- (void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {

    // 首先用属性fromTagFlag获取ElementName,供后面使用

    self.fromTagFlag = elementName;

    // 因为数据都是存储在属性中的,全都存储在了attributeDict里面了,在这里直接打印下

    NSLog(@"%@", attributeDict);

}

#pragma mark 获取到标签对应的数据

- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string {

  // 因为数据都存储在了属性中,所有不需要解析子标签

}

#pragma mark - 解析标签结束

- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {

    self.fromTagFlag = nil;

}

#pragma mark 文档结束读取

- (void)parserDidEndDocument:(NSXMLParser *)parser {

    // 打印获取到的数据的数组

    NSLog(@"%@", self.messageeListArray);

}



#pragma mark - 重写----dealloc方法

- (void)dealloc {

    [_messageeListArray release], _messageeListArray = nil;

    [_fromTagFlag release], _fromTagFlag = nil;

    

    // 调用父类的dealloc方法

    [super dealloc];

}


@end

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值