03-IOSCore - XML及解析、Plist
一、XML 可扩展标记语言
是什么?是一段有规范的字符串,
用在哪?用在任何地方
语法:
* 结点Node
<结点名 属性名="属性值">
结点内容
</结点名>
* 结点的开始和结尾配对
* 结点内可以有子结点
* 结点内可以有文本
* 结点名和属性名区分大小写
* 结点不能交叉
* 结点名和属性名 随便写
术语:
结点、属性
叶子结点 :没有子结点的结点
<a b="c"></a>可以简化<a b="c" />
非叶子结点 :有子结点的结点
对于存储数据的xml,非叶子结点几乎不存储任何文本,对于一些xml的变体xhtml,就会出现大量的非叶子子结点存储文本的现象,比如:
<div>
<h1>...</h1>
<p>ggg...<a>...</a></p>
</div>
根结点 :没有父结点的结点,一个xml只能有一个根结点
层级关系:
子结点
父结点
兄弟结点
其他:特殊符号不能直接写在xml中,比如<要写成< >>
xml解析:
XML文件结构解析
1 事件驱动 SAX iOS采用事件驱动解析
ios具体解析xml文档步骤:
1) 准备好xml文档的路径
2) 转换为data数据
3) 创建NSXMLParser对象调用initWithData把data传进来
4) 设置delegate,然后发送parse消息解析文档
NSString *path = @"/.../message.xml";
NSData *data = [NSDatadataWithContentsOfFile:path];
NSXMLParser *xmlParser = [[NSXMLParseralloc] initWithData:data];
xmlParser.delegate = self;
[xmlParser parse];
delegate中几个重要的API:
// 开始解析xml文档
-(void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(@"开始解析...");
}
// 发现结点节点名 + 属性
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
NSLog(@"开始节点名:%@",elementName);
[attributeDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(@"属性名:%@, 属性值:%@",key,obj);
}];
}
// 结束结点
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
NSLog(@"结束结点:%@",elementName);
}
// 发现文本
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
NSLog(@"发现文本:%@",string);
}
// 结束解析xml文档
-(void)parserDidEndDocument:(NSXMLParser *)parser{
NSLog(@"结束文档解析");
}
实现xml解析步骤:
/*
解析xml文档:
根据本例中message.xml文件解析
如果发现Message节点就创建一个类,同时根据attributeDict可以获取到属性order并赋值
为了可以获取xml文件中文本的值并赋给message类的属性(节点名),需要记下最近的那个节点名lastElementName
在发现文本方法中判断lastElementName是否和message类中的属性相同,如果相同就赋值
注意:文本直接赋值会出问题,"\n"这个会覆盖赋值好的文本,所以在结束结点中应该给lastElementName置空
快速修改本文件中所有的属性名技巧:
选中属性名后右击选中refactor -> rename
*/
#import "MXMessageParse.h"
#import "MXMessage.h"
@interfaceMXMessageParse ()
@property(nonatomic,strong) MXMessage *lastMessage;
@property(nonatomic,copy) NSString *lastElementName;
@property(nonatomic,strong) NSMutableArray *messages;
@end
@implementation MXMessageParse
-(void)parser{
NSString *path = @"/Users/tarena/yz/第三阶段(UI核心_Model赵哲)/day03/day0302_xml_parse解析/message.xml";
NSData *data = [NSDatadataWithContentsOfFile:path];
NSXMLParser *xmlParser = [[NSXMLParseralloc] initWithData:data];
xmlParser.delegate = self;
[xmlParser parse];
}
// 开始解析xml文档
-(void)parserDidStartDocument:(NSXMLParser *)parser{
NSLog(@"开始解析...");
}
// 发现结点节点名 + 属性
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict{
NSLog(@"开始节点名:%@",elementName);
[attributeDict enumerateKeysAndObjectsUsingBlock:^(id key, id obj, BOOL *stop) {
NSLog(@"属性名:%@, 属性值:%@",key,obj);
}];
if ([elementName isEqualToString:@"Message"]) {
self.lastMessage = [[MXMessagealloc] init];
self.lastMessage.order = [attributeDict[@"order"] intValue];
}elseif ([elementName isEqualToString:@"messages"]){
self.messages = [NSMutableArrayarray];
}
self.lastElementName = elementName;
}
// 结束结点
-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
NSLog(@"结束结点:%@",elementName);
if ([elementName isEqualToString:@"Message"]) {
[self.messagesaddObject:self.lastMessage];
}
self.lastElementName = Nil;
}
// 发现文本
-(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
NSLog(@"发现文本:%@",string);
if ([self.lastElementNameisEqualToString:@"fromMe"]) {
self.lastMessage.fromMe = [string isEqualToString:@"YES"];
}elseif ([self.lastElementNameisEqualToString:@"type"]){
NSString *type = string;
if ([type isEqualToString:@"TXT"]) {
self.lastMessage.type = MXMessageTypeText;
}
}elseif ([self.lastElementNameisEqualToString:@"content"]){
self.lastMessage.content = string;
}
}
// 结束解析xml文档
-(void)parserDidEndDocument:(NSXMLParser *)parser{
NSLog(@"结束文档解析");
}
2 树状模型 DOM
XML结构 <-> 对象
Node *rootNode = [parser parse:path];
NSString *elementName = rootNode.name;
Node *messageNode = [rootNode childNodeOfName@"Message"];
messageNode.name;
[messageNode attributeByName:@"order"];
3 优缺点对比
事件驱动 树状模型
使用困难 使用简单
边读取边解析 读取完整后在解析
摘取部分重要信息 从完整信息中搜索
二、plist (Property List)
是一个有固定格式的xml文件,用来存储中小型数据,在ios中使用
plist可以存储的数据类型:
NSArray
NSDictionary
根节点必须是上面两个类型之一
NSString
NSNumber
NSData
Boollean
plist解析:
NSArray arrayWithContentsOfFile
NSDictionary dictionaryWithContentsOfFile
plist的解析过程是
plist(XML) <--> OC对象结构 互相转换
对应关系:
OC
<Message order="">
+ fromMe
+ content
MXL
Message
<formMe></formMe>
<content></content>
Plist
formMe ->
content ->
读取plist中的数据
- (void)viewDidLoad
{
[superviewDidLoad];
// 读取plist数据
NSMutableArray *arr = [NSMutableArrayarray];
NSString *path = [[NSBundlemainBundle] pathForResource:@"messages"ofType:@"plist"];
NSArray *array = [NSArrayarrayWithContentsOfFile:path];
for (NSDictionary *dic in array) {
MXMessage *message = [[MXMessagealloc] init];
message.content = dic[@"content"];
message.fromMe = [dic[@"fromMe"] boolValue];
if ([dic[@"type"] isEqualToString:@"TXT"]) {
message.type = MXMessageTypeText;
}
[arr addObject:message];
}
for (MXMessage *message in arr) {
NSLog(@"%@",message.content);
}
}
写入:
writeToFile:
必须确保字典/数组内的所有对象均是plist支持的对象
复杂对象树状结构用plist表达
area
代码如下:
- (void)viewDidLoad
{
[superviewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
NSLog(@"%@",NSHomeDirectory());
NSString *documentsPath = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
NSString *plistPath = [documentsPath stringByAppendingPathComponent:@"china.plist"];
[[NSFileManagerdefaultManager] createFileAtPath:plistPath contents:Nilattributes:Nil];
// 对象 -> 字典
TRArea * puDong = [[TRAreaalloc] init];
puDong.areaName = @"浦东";
NSDictionary *dicPuDong = @{@"areaName": puDong.areaName};
TRArea * shangHai = [[TRAreaalloc] init];
shangHai.areaName = @"上海";
shangHai.subAreas = @[dicPuDong];
NSDictionary *dicShangHai = @{@"areaName": shangHai.areaName,
@"subAreas": shangHai.subAreas};
TRArea * china = [[TRAreaalloc] init];
china.areaName = @"中国";
china.subAreas = @[dicShangHai];
NSDictionary *dicChina = @{@"areaName": china.areaName,
@"subAreas": china.subAreas};
[dicChina writeToFile:plistPath atomically:YES];
}
作业
1. TMessage plist存储支持
2. TContact plist存储支持(放document下)
1) 定义一个plist文件格式
2) 写解析代码
3) 实现读取文件内容显示消息/联系人信息
4) 支持保存
发新消息/建新对象
把messages/contacts数组 转化成
plist支持的数组(数组结构 还要跟定义的结构一样)
03-IOSCore - XML及解析、Plist的更多相关文章
- 玩转iOS开发 - JSON 和 Xml 数据解析
前言 Json 和xml是网络开发中经常使用的数据格式,JSON轻量级.xml相对较复杂.所以如今用JSON的比例很大.基本上从server获取的返回数据都是JSON格式的,作为iOS开发人员,解析J ...
- JavaEE XML DOM解析之DOM4J
DOM解析之DOM4J @author ixenos DOM4J常用API 读取xml文档: Document doc = new SAXReader().read("xml文件" ...
- iOS 应用数据存储方式(XML属性列表-plist)
iOS 应用数据存储方式(XML属性列表-plist) 一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存储自定义对象) ...
- 通过正则表达式实现简单xml文件解析
这是我通过正则表达式实现的xml文件解析工具,有些XHTML文件中包含特殊符号,暂时还无法正常使用. 设计思路:常见的xml文件都是单根树结构,工具的目的是通过递归的方式将整个文档树装载进一个Node ...
- JAVA 中XML的解析
XML: 可扩展标记语言(extensible Markup Language) 用于标记电子文件使其具有结构性的标记语言.XML可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定 ...
- xml的解析与创建——bing到youdao导入文件的转换
首先是为了解决一个问题:如何将必应单词本中记录的单词转入到有道词典中去.实际上,必应词典可以导出xml文件,但是该文件有道词典无法解析.这里涉及到xml的解析和创建了. 代码如下: import ja ...
- iOS-数据持久化基础-JSON与XML数据解析
解析的基本概念 所谓“解析”:从事先规定好的格式串中提取数据 解析的前提:提前约定好格式.数据提供方按照格式提供数据.数据获取方按照格式获取数据 iOS开发常见的解析:XML解析.JSON解析 一.X ...
- 八、Android学习第七天——XML文件解析方法(转)
(转自:http://wenku.baidu.com/view/af39b3164431b90d6c85c72f.html) 八.Android学习第七天——XML文件解析方法 XML文件:exten ...
- iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist)
iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist) 一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存 ...
随机推荐
- go语法之一
Go语法: Go语言要求public的变量必须以 大写字母开头,private变量则以小写字母开头,这种做法不仅免除了public.private关键字,更重要的是统一了命名风格. Go语言对{ } ...
- Python 参数传递
python中的变量: 一个变量是局部还是全局,在编译函数的时候就已经决定,因此读变量值的时候也不会逐层向外查找.变量是全局还是局域,根据如下3条: 1. 如果函数内部有global语句,那么它声明的 ...
- 转换GridView的内容到Excel里面 ---带有格式
http://www.aspsnippets.com/Articles/Export-GridView-to-Excel-in-ASPNet-with-Formatting-using-C-and-V ...
- 【转】Ubuntu常用软件合集
[转]Ubuntu常用软件合集 Ubuntu常用软件合集 我用的使Ubuntu-Kylin14.04,原因呢主要是觉得使本土化的,自带了日历.输入法.优客助手等易于上手的应用.也省的每次安装完原生的系 ...
- BZOJ 1664: [Usaco2006 Open]County Fair Events 参加节日庆祝( dp )
先按时间排序( 开始结束都可以 ) , 然后 dp( i ) = max( dp( i ) , dp( j ) + 1 ) ( j < i && 节日 j 结束时间在节日 i 开 ...
- Myeclipse代码提示及如何设置自动提示
Myeclipse代码提示及如何设置自动提示 (2011-11-18 00:38:41) 转载▼ 标签: 杂谈 分类: Java 1. 设置代码自动提示window --> preference ...
- Binary Tree Preorder Traversal and Binary Tree Postorder Traversal
Binary Tree Preorder Traversal Given a binary tree, return the preorder traversal of its nodes' valu ...
- r语言之给定的概率密度函数生成随机数
假设概率密度函数为: 思路: 首先产生-1到1之间的均匀分布随机数x,和0到1之间的均匀分布随机数y. 如果y<f(x),则x是符合该概率密度的随机数,否则,重复上述操作. 用r语言生成100个 ...
- python学习之lambda匿名函数
1 Python支持运行时使用“lambda”建立匿名函数(anonymous functions that are not bound to a name). python "lambda ...
- html(第一天,div+css)
一.CSS布局属性 Width:设置对象的宽度(width:45px). Height:设置对象的高度(Height:45px;). Background:设置对象的背景颜色.背景图像. 1.背景颜色 ...