XML即可扩展标记语言(eXtensible Markup Language)。标记是指计算机所能理解的信息符号,通过此种标记,计算机之间可以处理包含各种信息的文章等。如何定义这些标记,既可以选择国际通用的标记语言,比如HTML,也可以使用象XML这样由相关人士自由决定的标记语言,这就是语言的可扩展性。XML是从SGML中简化修改出来的。它主要用到的有XML、XSL和XPath等。
上面这段是对XML的一个基本定义,一个被广泛接受的说明。简单说,XML就是一种数据的描述语言,虽然它是语言,但是通常情况下,它并不具备常见语言的基本功能——被计算机识别并运行。只有依靠另一种语言,来解释它,使它达到你想要的效果或被计算机所接受。
记住以下几点就行了:
- XML是一种标记语言,很类似HTML
- XML的设计宗旨是传输数据,而非显示数据
- XML标签没有被预定义。您需要自行定义标签。
- XML被设计为具有自我描述性。
- XML是W3C的推荐标准
总结:
XML是独立于软件和硬件的信息传输工具。 目前,XML在Web中起到的作用不会亚于一直作为 Web 基石的 HTML。 XML无所不在。XML是各种应用程序之间进行数据传输的最常用的工具,并且在信息存储和描述领域变得越来越流行。
1.1 XML属性
1.1.1 XML与HTML的主要差异
- XML不是HTML的替代。
- XML和HTML为不同的目的而设计。
- XML被设计为传输和存储数据,其焦点是数据的内容。
- HTML被设计用来显示数据,其焦点是数据的外观。
- HTML旨在显示信息,而 XML 旨在传输信息
1.1.2 XML是不作为的。
也许这有点难以理解,但是XML不会做任何事情。XML被设计用来结构化、存储以及传输信息。
1.1.3 XML仅仅是纯文本
XML没什么特别的。它仅仅是纯文本而已。有能力处理纯文本的软件都可以处理XML。 不过,能够读懂 XML 的应用程序可以有针对性地处理 XML 的标签。标签的功能性意义依赖于应用程序的特性。
1.1.4 XML允许自定义标签
上例中的标签没有在任何XML标准中定义过(比如和)。这些标签是由文档的创作者发明的。这是因为XML没有预定义的标签。
在HTML中使用的标签(以及HTML的结构)是预定义的。HTML文档只使用在HTML标准中定义过的标签(比如<p>
,<h1>
等等)。
XML允许创作者定义自己的标签和自己的文档结构。
1.1.5 XML不是对HTML的替代
XML是对HTML的补充。
XML不会替代HTML,理解这一点很重要。在大多数 web 应用程序中,XML用于传输数据,而HTML用于格式化并显示数据。
1.2 XML的语法
XML的语法规则很简单,且很有逻辑。这些规则很容易学习,也很容易使用。
1.2.1 所有元素都必须有关闭标签
在XML中,省略关闭标签是非法的。所有元素都必须有关闭标签。 在HTML,经常会看到没有关闭标签的元素:
1
2
|
<
p
>This is a paragraph
<
p
>This is another paragraph
|
在XML中,省略关闭标签是非法的。所有元素都必须有关闭标签:
1
2
|
<p>This
is
a paragraph</p>
<p>This
is
another paragraph</p>
|
注释:您也许已经注意到XML声明没有关闭标签。这不是错误。声明不属于XML本身的组成部分。它不是XML元素,也不需要关闭标签。
1.2.2 XML标签对大小写敏感
XML元素使用XML标签进行定义。
XML标签对大小写敏感。在XML中,标签与标签是不同的。
必须使用相同的大小写来编写打开标签和关闭标签:
1
2
|
<
Message
>这是错误的。</
message
>
<
message
>这是正确的。</
message
>
|
1.2.3 XML标签对大小写敏感
在 HTML 中,常会看到没有正确嵌套的元素:
1
|
<
b
><
i
>This text is bold and italic</
b
></
i
>
|
在 XML中,所有元素都必须彼此正确地嵌套:
1
|
<
b
><
i
>This text is bold and italic</
i
></
b
>
|
在上例中,正确嵌套的意思是:由于<i>
元素是在<b>
元素内打开的,那么它必须在<b>
元素内关闭。
1.2.4 XML文档必须有根元素
XML文档必须有一个元素是所有其他元素的父元素。该元素称为根元素。
1
2
3
4
5
|
<
root
>
<
child
>
<
subchild
>.....</
subchild
>
</
child
>
</
root
>
|
1.2.5 XML的属性值须加引号
与 HTML 类似,XML 也可拥有属性(名称/值的对)。 在 XML 中,XML 的属性值须加引号。请研究下面的两个 XML 文档。第一个是错误的,第二个是正确的:
1
2
3
4
5
6
7
8
9
|
<
note
date
=
08
/08/2008>
<
to
>George</
to
>
<
from
>John</
from
>
</
note
>
<
note
date
=
"08/08/2008"
>
<
to
>George</
to
>
<
from
>John</
from
>
</
note
>
|
1.2.6 实体引用
在 XML 中,一些字符拥有特殊的意义。 如果你把字符 “<” 放在 XML 元素中,会发生错误,这是因为解析器会把它当作新元素的开始。 这样会产生 XML 错误:
1
|
<
message
>if salary <
1000
then</message>
|
为了避免这个错误,请用实体引用来代替 “<” 字符:
1
|
<
message
>if salary < 1000 then</
message
>
|
在 XML 中,有 5 个预定义的实体引用:
1
2
3
4
5
|
< < 小于
> > 大于
& & 和号
' ' 单引号
" " 引号
|
注释:在 XML 中,只有字符 “<” 和 “&” 确实是非法的。大于号是合法的,但是用实体引用来代替它是一个好习惯。
1.2.7 XML中的注释
在 XML 中编写注释的语法与 HTML 的语法很相似:
1
|
<!-- This is a comment -->
|
在 XML 中,空格会被保留 HTML 会把多个连续的空格字符裁减(合并)为一个:
1
|
HTML: Hello my name is David.
|
输出: Hello my name is David. 在 XML 中,文档中的空格不会被删节。
2,XML的解析
1.初始化解析器,传入你要解析的数据。
2.parse,启动解析,返回一个是否解析成功Bool值。
3.基本你要处理的就在下面实现的1-5个代理方法了。
其实代理方法和详细,就是一个事物进行流程:
step1是准备解析,然后没意外就是执行到了——>
step2读取到第一个头节点了,然后如果内部有属性值,你可以获取出来,读完头节点,我们会进去值域——》
step3对于简单的节点,可能直接就是一个string值了,但是看例子我们会知道,很多情况下,该节点的值域包含的于是一个节点——》
这步其实分两种,如果是值,那么就是执行step4,获取值的字窜,如果是子节点呢,我们一看就知道,它又是进行了step2,
即读取到头标签了,其实你是很人读一片文章流程一样,只不过我们脑中有个印象<xxx>是头标签了,我们要做什么,独到 头标签的最后一个符号">"
下面进去值域,独到了字窜的话就调用了foundCharacters:(NSString *)string,如果又读到<xxx>这样的,那就又是头标签了。——》
step5就是读到开始尾标签符号了。
最后一个方法
foundCDATA:(NSData *)CDATABlock,其实也是一个格式
要解析的xml如下
<?xml version="1.0" encoding="UTF-8"?>
<postTypes>
<postType name="计算机硬件">
<child code="2401" name="高级硬件工程师"></child>
<child code="2402" name="硬件工程师"></child>
<child code="2403" name="其他"></child>
</postType>
<postType name="计算机软件">
<child code="0106" name="高级软件工程师"></child>
<child code="0107" name="软件工程师"></child>
</postType>
<postType name="互联网开发及应用">
<child code="2501" name="互联网软件开发工程师"></child>
</postType>
</postTypes>
解析方法
#import "ViewController.h"
@interface ViewController ()<NSXMLParserDelegate>
{
NSMutableDictionary *Objectdic;
NSMutableDictionary *NameClassdic;
NSMutableArray *Object;
NSString *class;
}
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
#pragma mark 输出返回的xml值
NSString *Path = [[NSBundle mainBundle]pathForResource:@"post_type" ofType:@"xml"];
NSInputStream *Input = [NSInputStream inputStreamWithFileAtPath:Path];
NSXMLParser *xml = [[NSXMLParser alloc]initWithStream:Input];
xml.delegate = self;
[xml setShouldProcessNamespaces:NO];
[xml setShouldReportNamespacePrefixes:NO];
[xml setShouldResolveExternalEntities:NO];
[xml setDelegate:self];
[xml parse];
NSLog(@"dic is %@", NameClassdic);
}
/**
* 已经开始解析
*
*/
- (void)parserDidStartDocument:(NSXMLParser *)parser
{
NameClassdic = [NSMutableDictionary dictionary];
}
#pragma mark 遍例xml的节点,执行以下代理方法
-(void)parser:(NSXMLParser *)parser didStartElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName attributes:(NSDictionary *)attributeDict {
if ([elementName isEqualToString:@"child"]) { // child 里面的值
[Object addObject:attributeDict];
[NameClassdic removeObjectForKey:class];
if (![NameClassdic valueForKey:class]) {
[NameClassdic setObject:Object forKey:class];
}
}else{
if ([elementName isEqualToString:@"postType"]) {
if (NameClassdic.count != 0) {
}
class = attributeDict[@"name"];
Object = [NSMutableArray array];
}
}
}
//step 3:获取首尾节点间内容
- (void)parser:(NSXMLParser *)parser foundCharacters:(NSString *)string{
}
//step 4 :解析完当前节点
- (void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName{
}
//step 5;解析结束
- (void)parserDidEndDocument:(NSXMLParser *)parser
{
}
//获取cdata块数据
- (void)parser:(NSXMLParser *)parser foundCDATA:(NSData *)CDATABlock
{
}