一、XML 可扩展标记语言

是什么?是一段有规范的字符串,

用在哪?用在任何地方

语法:

* 结点Node

<结点名 属性名="属性值">

结点内容

</结点名>

* 结点的开始和结尾配对

* 结点内可以有子结点

* 结点内可以有文本

* 结点名和属性名区分大小写

* 结点不能交叉

* 结点名和属性名 随便写

术语:

结点、属性

叶子结点  :没有子结点的结点

<a b="c"></a>可以简化<a b="c" />

非叶子结点  :有子结点的结点

对于存储数据的xml,非叶子结点几乎不存储任何文本,对于一些xml的变体xhtml,就会出现大量的非叶子子结点存储文本的现象,比如:

<div>

<h1>...</h1>

<p>ggg...<a>...</a></p>

</div>

根结点  :没有父结点的结点,一个xml只能有一个根结点

层级关系:

子结点

父结点

兄弟结点

其他:特殊符号不能直接写在xml中,比如<要写成&lt;    >&gt;

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的更多相关文章

  1. 玩转iOS开发 - JSON 和 Xml 数据解析

    前言 Json 和xml是网络开发中经常使用的数据格式,JSON轻量级.xml相对较复杂.所以如今用JSON的比例很大.基本上从server获取的返回数据都是JSON格式的,作为iOS开发人员,解析J ...

  2. JavaEE XML DOM解析之DOM4J

    DOM解析之DOM4J @author ixenos DOM4J常用API 读取xml文档: Document doc = new SAXReader().read("xml文件" ...

  3. iOS 应用数据存储方式(XML属性列表-plist)

    iOS 应用数据存储方式(XML属性列表-plist) 一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存储自定义对象) ...

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

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

  5. JAVA 中XML的解析

    XML:  可扩展标记语言(extensible Markup Language) 用于标记电子文件使其具有结构性的标记语言.XML可以用来标记数据.定义数据类型,是一种允许用户对自己的标记语言进行定 ...

  6. xml的解析与创建——bing到youdao导入文件的转换

    首先是为了解决一个问题:如何将必应单词本中记录的单词转入到有道词典中去.实际上,必应词典可以导出xml文件,但是该文件有道词典无法解析.这里涉及到xml的解析和创建了. 代码如下: import ja ...

  7. iOS-数据持久化基础-JSON与XML数据解析

    解析的基本概念 所谓“解析”:从事先规定好的格式串中提取数据 解析的前提:提前约定好格式.数据提供方按照格式提供数据.数据获取方按照格式获取数据 iOS开发常见的解析:XML解析.JSON解析 一.X ...

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

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

  9. iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist)

    iOS开发UI篇—ios应用数据存储方式(XML属性列表-plist) 一.ios应用常用的数据存储方式 1.plist(XML属性列表归档) 2.偏好设置 3.NSKeydeArchiver归档(存 ...

随机推荐

  1. 大一C语言结课设计之《简单计算器》

    /*===============================================*\ ** 设计目的:简单计算器,计算形如10*(20.2-30.6)+5.0/2的表达式值 ** 简 ...

  2. c#程序将excel文件转换成xml文件

    要程序你自己去组装去,我只写两个部分,一个是读Excel的部分,然后是写入到xml的1) 从指定的excel读出信息string strConn="provider=Microsoft.Je ...

  3. ASP.NET页面传值的几种方式

    页面传值是学习asp.net初期都会面临的一个问题,总的来说有页面传值. 存储对象传值.ajax.类.model.表单等!下面欧柏泰克和大家一起来看看asp.net页面传值方式一般有哪些?常用的较简单 ...

  4. 关于SOQL(一)

    SOQL 是Salesforce中的查询语言,他的全称是Salesforce Object Query Language. 从字面上就能够看出,这个语言是一种基于对象的查询语言. 在Salesforc ...

  5. Group By 多个分组集小结 --GROUPING SETS,GROUP BY CUBE,GROUP BY ROLLUP,GROUPING(),GROUPING_ID()

    T-SQL 多个分组集共有三种 GROUPING SETS, CUBE, 以及ROLLUP, 其中 CUBE和ROLLUP可以当做是GROUPING SETS的简写版 示例数据库下载: http:// ...

  6. iOS开发之第三方分享QQ分享,史上最新最全第三方分享QQ方式实现

    本文章源码地址: https://github.com/zhonggaorong/QQLoginDemo 项目搭建参考:  (包含QQ登录源码下载 . QQ sdk集成) http://blog.cs ...

  7. JavaSE学习总结第22天_IO流4

    -  22.01  数据输入输出流的概述和讲解 操作基本数据类型 public class DataInputStreamextends FilterInputStream implements Da ...

  8. jQuery的扩展

    我们自己通过扩展jQuery来达到 “通过$.xx(paras)的形式来进行调用某个jQuery对象的xx(paras)方法”. 下面就是一个实例: (function(j){//这里的j是一个形参, ...

  9. 用composer安装 Laravel | Laravel需要的环境配置

    一:安装 参考网站 http://v4.golaravel.com/docs/4.2/installation 1.先确保安装好了PHP,和服务器环境 2.然后下载composer可执行文件到当前目录 ...

  10. 转: seajs手册与文档之 -- require规则

    require 规则 正确拼写 不要修改 使用直接量 动态依赖的小提示 书写规则 使用 SeaJS 书写模块代码时,需要遵循一些简单规则: 1. 正确拼写 在模块代码中,第一个参数 必须 命名为 re ...