XML数据结构和解析
1.1XML数据结构
XML 是可扩展标记语言(Extensible Markup Language)的缩写,其中的 标记(markup)是关键部分。可以创建内容,然后使用限定标记标记它,从而使每个单词、短语或块成为可识别、可分类的信息。创建的文件,或文档实例 由元素(标记)和内容构成。当从打印输出读取或以电子形式处理文档时,元素能够帮助更好地理解文档。元素的描述性越强,文档各部分越容易识别。自从出现标记至今,带有标记的内容就有一个优势,即在计算机系统缺失时,仍然可以通过标记理解打印出来数据。
什么是 XML?
XML 指可扩展标记语言(EXtensible Markup Language)
XML 是一种标记语言,很类似 HTML
XML 的设计宗旨是传输数据,而非显示数据
XML 标签没有被预定义。您需要自行定义标签。
XML 被设计为具有自我描述性。
没有任何行为的 XML
XML 是不作为的。
也许这有点难以理解,但是 XML 不会做任何事情。XML 被设计用来结构化、存储以及传输信息。
下面是 John 写给 George 的便签,存储为 XML:
<note>
<to>George</to>
<from>John</from>
<heading>Reminder</heading>
<body>Don‘t forget the meeting!</body>
</note>
上面的这条便签具有自我描述性。它拥有标题以及留言,同时包含了发送者和接受者的信息。但是,这个 XML 文档仍然没有做任何事情。它仅仅是包装在 XML 标签中的纯粹的信息。我们需要编写软件或者程序,才能传送、接收和显示出这个文档。
XML 仅仅是纯文本
XML 没什么特别的。它仅仅是纯文本而已。有能力处理纯文本的软件都可以处理 XML。
不过,能够读懂 XML 的应用程序可以有针对性地处理 XML 的标签。标签的功能性意义依赖于应用程序的特性。
XML 是独立于软件和硬件的信息传输工具。
1.2 使用SAX解析XML
SAX是Simple API for XML的缩写,解析XML时并不需要读入整个文档,而文档的读入过程也就是SAX的解析过程。
1.2 .1 第一种格式(没有写属性)
data_XML1.txt
<messages>
<message>
<sender>小明</sender>
<receiver>小红</receiver>
<content>今天放学操场见</content>
<date>2015年10月19日</date>
</message>
<message>
<sender>小花</sender>
<receiver>小王</receiver>
<content>明天中午公园见</content>
<date>2015年10月19日</date>
</message>
</messages>
//解析XML //1.SAX 逐行解析(系统提供)数据大使用 //1.1提供文件路径字符串 //获取文件1 NSString * filePath1=[[NSBundle mainBundle]pathForResource:@"data_XML1" ofType:@"txt"]; NSData * data1=[NSData dataWithContentsOfFile:filePath1]; //1.2XML解析器 NSXMLParser *parser1=[[NSXMLParser alloc]initWithData:data1]; //设置代理 parser1.delegate=self; //1.3启动解析器 [parser1 parse]; //显示解析得到的文档 for (Message *m in self.dataArray) { NSLog(@"sender:%@",m.sender); NSLog(@"receiver:%@",m.receiver); NSLog(@"content:%@",m.content); NSLog(@"date:%@",m.date); } #pragma mark --第一种文件格式 //开始解析文档 -(void)parserDidStartDocument:(NSXMLParser *)parser{ NSLog(@"第一种文件格式"); NSLog(@"开始解析文档"); self.dataArray=[NSMutableArray array];//初始化数组 } //解析到开始标签 -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{ NSLog(@"开始标签elementName=%@",elementName); //判断标签,创建对象 if ([elementName isEqualToString:@"message"]) { //检测到message 创建保存信息对象 Message * m=[[Message alloc]init]; //存入数组 [self.dataArray addObject:m]; } self.appendString=[NSMutableString string];//初始化拼接字符串 //以数字开头的时候,读两次-所以需要拼接字符串 //2015-10-19 11:10:46.411 内容string=2015 //2015-10-19 11:10:46.411 内容string=年10月19日 } //解析到内容标签 -(void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{ NSLog(@"内容string=%@",string); //拼接字符串 [self.appendString appendString:string]; } //解析到结束标签 -(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{ NSLog(@"结束标签elementName=%@",elementName); //存入对象 Message *m=self.dataArray.lastObject;//排在最后 //存值-这种方式一个一个的赋值,如果标签太多就不方便了 // if ([@"sender" isEqualToString:elementName]) {m.sender=self.appendString;} // if ([@"receiver" isEqualToString:elementName]) {m.receiver=self.appendString;} // if ([@"date" isEqualToString:elementName]) {m.date=self.appendString;} // if ([@"content" isEqualToString:elementName]) { m.content=self.appendString;} //存值 使用KVC很方便 [m setValue:self.appendString forKey:elementName]; } //解析到错误 -(void)parser:(NSXMLParser *)parser parseErrorOccurred:(NSError *)parseError{ NSLog(@"XML Error!");} //结束解析文档 -(void)parserDidEndDocument:(NSXMLParser *)parser{ NSLog(@"结束解析文档");}
1.2 .2 第二种格式(写在属性中)
data_XML2.txt
<messages>
<message sender="Sam" receiver="Jack" content="School 4PM" date="2015-10-19">
</message>
<message sender="Bob" receiver="Kate" content="School 7PM" date="2015年10月19日">
</message>
</messages>
//解析XML //1.SAX 逐行解析(系统提供)数据大使用 //1.1提供文件路径字符串 //获取文件2 NSString * filePath2=[[NSBundle mainBundle]pathForResource:@"data_XML2" ofType:@"txt"]; NSData * data2=[NSData dataWithContentsOfFile:filePath2]; //1.2XML解析器 NSXMLParser *parser2=[[NSXMLParser alloc]initWithData:data2]; //设置代理 parser2.delegate=self; //1.3启动解析器 [parser2 parse]; //显示解析得到的文档 for (Message *m in self.dataArray) { NSLog(@"sender:%@",m.sender); NSLog(@"receiver:%@",m.receiver); NSLog(@"content:%@",m.content); NSLog(@"date:%@",m.date); } #pragma mark --第二种文件格式 //第二种文件格式 -(void)parserDidStartDocument:(NSXMLParser *)parser{ self.dataArray=[NSMutableArray array]; NSLog(@"开始解析"); } -(void)parserDidEndDocument:(NSXMLParser *)parser{ NSLog(@"结束解析"); } -(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary<NSString *,NSString *> *)attributeDict{ //NSLog(@"attributeDict=%@",attributeDict); if ([elementName isEqualToString:@"message"]) { Message *m=[[Message alloc]init]; [m setValuesForKeysWithDictionary:attributeDict]; [self.dataArray addObject:m]; } }