既然是速成,那就用最简单粗暴的方式介绍知识。
目录
首先是XML文件的介绍。首先,我们看一个文本文件:
Moyun
Li
25
100
false
false
Fulei
Xie
25
0
false
true
Ke
Lin
38
5
true
false
这个文本文件表达了什么含义呢?很明显,这是三条个人信息,并表达了三条记录,分别表示三个叫Moyun Li,Fulei Xie和Ke Lin的人一些信息。但是,这些信息究竟是什么意思呢?从数据本身来说,我们无法得知究竟这些数据是什么含义。
或许我们可以为这个文本文件在给出一个描述文件。这个描述文件用来标识这些数据的含义。例如:
名字
姓氏
年龄
谈恋爱的次数:)
是否结婚
是否是...俗称“处男”
这样,我们就可以从解读出上面的数据,得知Moyun Li是一个花花公子,而Fulei Xie是一个没人要的死宅男。
但是,这样写有一个坏处,那就是我们得有两个文件:一个文件是数据文件,另一个文件是对数据的描述文件。这样,我们就把“数据”和“描述”分离开了。
数据和描述相分离不是不可以,但是同样带来了一些问题。
第一个问题是,容易出错。例如,对于每一条记录的最后两项,表达的格式分别是true/false。如果程序员不小心,或者保存数据的人不小心,非常容易把记录弄颠倒。
第二个问题是,难以扩展。例如,对于已婚人士,我们希望增加一条信息:是否有小孩。但如果需要增加这一条信息的话,必须要修改“描述”文件,增加这么一个数据项;同时更新所有数据记录。这样,我们的数据描述文件就要变为:
名字
姓氏
年龄
谈恋爱的次数:)
是否结婚
小孩的个数
是否是...俗称“处男”
同时,所有的数据文件都要改:
Moyun
Li
25
100
false
0
false
Fulei
Xie
25
0
false
0
true
Ke
Lin
38
5
true
1
false
我们可以看到,一旦修改数据描述文件,那么牵一发而动全身,不但Kevin这条记录要修改,所有的记录都必须要修改。
正因为数据和描述分离会产生这样或那样的问题,因此我们引入XML,来看看XML是怎样解决问题的。
Back to Top
我们用另一种方式来描述我们之前提到的几条记录。我们为数据加上一些尖括号,在尖括号里面加上对数据的描述。同时,<XXX> 表示数据开始,</XXX>表示数据结束。则结果如下:
<Staff>
<FirstName>Moyun</FirstName>
<LastName>Li</LastName>
<Age>25</Age>
<Lovers>100</Lovers>
<Married>false</Married>
<Virgin>false</Virgin>
</Staff>
<Staff>
<FirstName>Fulei</FirstName>
<LastName>Xie</LastName>
<Age>25</Age>
<Lovers>0</Lovers>
<Married>false</Married>
<Virgin>true</Virgin>
</Staff>
<Staff>
<FirstName>Kevin</FirstName>
<LastName>Lin</LastName>
<Age>38</Age>
<Lovers>5</Lovers>
<Married>true</Married>
<Virgin>false</Virgin>
</Staff>
首先,我们可以看到,为了区分三条不同的记录,我们为每一条记录的开始增加了一个标签<Staff>,为每一条记录的结束增加了一个标签</Staff>。这样,我们通过这种方式,非常清楚的区分了这三条记录。
而在Staff内部,则是每一条记录的数据。我们分别定义了FirstName,LastName,Age,Lovers,Married以及Virgin这样几个标签,分别用来描述数据的含义。
这样,我们就把数据,以及对数据的描述结合在一起了。这种情况下,我们就比较好的解决了“数据”和“描述”相分离的问题,并比较好的解决了“易出错”和“难以扩展”这两个问题。接下来我们来解释一下,这种带标签的文本是如何解决这两个问题的。
首先,“易出错”的问题。对于原来的数据来说,如果我们把Fulei Xie这条记录的最后两项颠倒一下:
Fulei Xie
25
0
true
false
这样一来,整个数据的含义都发生了改变。
但是,如果我们把带标签的Fulei Xie最后两条进行颠倒:
<Staff>
<FirstName>Fulei</FirstName>
<LastName>Xie</LastName>
<Age>25</Age>
<Lovers>0</Lovers>
<Virgin>true</Virgin>
<Married>false</Married>
</Staff>
虽然最后的值变成了true / false,但是实际上表示起来没有任何歧义。因为数据和数据的描述紧密的结合在一起,这样在解释数据的时候,就能够避免很多错误。
其次,我们来看看带标签的文本是如何解决扩展性的问题。我们修改“Kevin Lin”这条记录:
<Staff>
<FirstName>Kevin</FirstName>
<LastName>Lin</LastName>
<Age>38</Age>
<Lovers>5</Lovers>
<Married>true</Married>
<Kids>1</Kids>
<Virgin>false</Virgin>
</Staff>
这样,我们很轻松的为Kevin Lin增加了Kids这个新的字段。同时,为Kevin增加Kids这个描述的同时,对Fulei Xie以及Moyun Li这两条记录的理解完全没有影响。
Back to Top
XML的意思是可扩展标记语言(eXtensible Markup Language,简称XML),在我看来,其基本思想就是带标签的文本,并且把数据以及对数据的描述结合起来。
XML文件的通常有以下几部分组成:
序言看起来的样子往往是这样的:
<?xml version="1.0" encoding="UTF-8" ?>
这里面指定了xml的版本是1.0,并指定XML文件编码方式是UTF-8。
通常,有编码方式,就意味着中文显示会有麻烦。而中文显示的麻烦,又来源于大陆和台湾、香港的不统一。这是一个中国程序员心中永远的痛……算了,不提他了,以后我的XML里面,都用英文吧……
序言通常来说格式固定。关于序言的更多内容,那个……自个儿上网搜吧。速成不教这个。
Back to Top
在xml文件中,可以加注释。注释的格式是:
<!--这里是注释-->
而且注释可以跨越多个换行符,也就是说,可以给XML文件增加多行注释,例如:
<!--多行注释
的例子—>
Back to Top
所谓的元素,是英文"Element"的翻译。通常,一个元素由这样几部分组成:
a) Start-Tag & End Tag
b) Content
c) Attribute
我们一一介绍。
a. Start-Tag & End Tag
Start Tag和End Tag表示开始标记和结束标记,通常的格式是:<xxx>和</xxx>。
在这儿要注意两点:
1、xml区分大小写。也就是说,<test></test>能够组成一对开始和结束标记;而<test></Test>无法组成一对标记。
2、必须要正确的关闭xml标记。也就是说,一方面,有了开始标记,必须有对应的结束标记。另一方面,xml元素之间不允许交错。例如:
<a>xxx<b>yyy</a>zzz</b>
这样在xml中是不允许的。上面这个例子中,a标记的开始和结束,与b标记的开始和结束产生了交错。而下面的例子:
<a>xxx<b>yyy</b>zzz</a>
是允许的。在这种情况下,a元素包含b元素。
除了开始标记和结束标记之外,还有一种标记。例如:
<singleelement/>
这表示这是一个单独的元素,这个元素不包含任何内容。不包含任何内容的元素有用么?有用。一方面,元素不包含内容,但是元素可以包含“属性”。这个属性,就是我们后面会提到的Attribute。另一方面,这个元素可能仅仅用来标识一个很简单的意义。例如,在网页中,可以用<br/>来表示一个回车。这个<br/>就是一个单独的元素,而不用再加上开始标记和结束标记。
b. Content
所谓的Content,指的是一个元素的内容,也就是在开始标记和结束标记之间的东西。
首先,元素可以没有内容。例如我们刚刚提到的,<singleelement/>就是一个没有内容的元素。
其次,元素的内容可以是纯文本或者其他元素。
例如,我们来看Fulei Xie的那条记录:
<Staff1>
<FirstName>Fulei</FirstName>
<LastName>Xie</LastName>
</Staff1>
在这条记录中,有FirstName这么一个元素。这个元素的开始标记和结束标记中间的内容,就是Fulei这个字符串。
需要注意的是,XML没有int或者boolean之类的类型,所有内容都当做纯文本。例如,Age元素的内容是字符串25,而Virgin元素的内容是字符串true。
然后我们来看看<Staff1>这个元素。首先要明确的是,在<Staff1>和</Staff1>之间出现的所有东西,都是Staff1元素的内容。在Staff1元素中,很显然,包含了FirstName,LastName等一系列元素,这也就说明了,元素的内容同样可以是元素。
除此之外,我们看看下面这个例子:
<Staff2><FirstName>Fulei</FirstName><LastName>Xie</LastName></Staff2>
这个Staff2和上面那条Staff1有什么不同么?
很显然,在这条记录中,少了一些回车和空格。
那么,有这么一个问题:空格和回车,算不算之前那个Staff1的内容呢?
答案很明确:算。
也就是说,Staff1的内容由五部分组成,分别是:
1) (<Staff1>后面的)回车和(<FirstName>之前)空格
2) FirstName元素
3) (</FirstName>后面的)回车和(<LastName>之前的)空格
4) LastName元素
5) (</LastName>后面的)回车
而Staff2的内容只有两部分,分别是:
1) FirstName元素
2) LastName元素
请牢牢记住,空格和回车同样是元素的内容。
c. Attribute
Attribute表示属性,元素的Attribute可以这样表示:
<element attributeName=”attributeValue”>…</element>
例如,对于之前Fulei Xie的Lovers元素,如果使用Content,则写成:
<Lovers>0</Lovers>
我们用Attribute的方式,就可以写成:
<Lovers number="0"></Lovers>
这样,元素就没有内容,就可以进一步简写成为:
<Lovers number="0"/>
我们为Lovers元素增加了一个属性,属性的名字为number,而属性的值为0。
需要注意的是,属性的值必须加上双引号或者单引号,下面的写法就是错误的:
<Lovers number=0/>
此外,我们可以为一个元素增加多个属性。例如:
<Lovers tried="50" succeed="0"/>
这个元素,说明Fulei Xie在Lovers的问题上,尝试了50次,但是成功的次数为0。(樱木花道灵魂附体,嗯!)
d. Only one root element
重新回到Fulei Xie的例子。
<Staff1>
<FirstName>Fulei</FirstName>
<LastName>Xie</LastName>
</Staff1>
对于这个例子来说,Staff1元素和FirstName元素,很显然是有着某种联系的。FirstName元素是Staff1元素的组成部分,被成为Staff1元素的子元素(child),而Staff1则被成为是FirstName的父元素(parent)。而FirstName和LastName之间则是并列的关系。
我们可以把这个例子再写的复杂一点。
<Staff>
<Name>
<FirstName>Fulei</FirstName>
<LastName>Xie</LastName>
</Name>
</Staff>
这样,Name元素是Staff的子元素,而是FirstName和LastName的父元素。而Staff是FirstName和LastName的祖先元素。
下面我们要说的是xml的一个重要规定:在一个xml文件中,只能有一个根元素(root element)。也就是说,一个xml文件中,顶级的元素只能有一个,其他的元素必须都是这个顶级元素的子孙。
对于我们之前写的标记文本,因为有三条记录,因此我们写出了三个顶级元素<Staff>。因此,事实上这段文本是不符合xml规范的。要么,我们把这三条记录放到三个xml文件中,要么我们为Staff找一个父元素,写成:
<Staffs>
<!-- Moyun Li -->
<Staff>
...
</Staff>
<!-- Kevin Lin -->
<Staff>
...
</Staff>
...
</Staffs>
这样,我们就能保证xml文件中仅包含一个根节点。
Back to Top
根据我们之前所说的xml文件的种种要求,下面给出一个完整的例子:
<?xml version="1.0" ?>
<Staffs>
<!-- Moyun Li -->
<Staff>
<Name>
<FirstName>Moyun</FirstName>
<LastName>Li</LastName>
</Name>
<Age>25</Age>
<Lovers number="100"/>
<Married>false</Married>
<Virgin>false</Virgin>
</Staff>
<!-- Fulei Xie -->
<Staff>
<Name>
<FirstName>Fulei</FirstName>
<LastName>Xie</LastName>
</Name>
<Age>25</Age>
<Lovers number="0"/>
<Married>false</Married>
<Virgin>true</Virgin>
</Staff>
<!-- Kevin Lin -->
<Staff>
<Name>
<FirstName>Kevin</FirstName>
<LastName>Lin</LastName>
</Name>
<Age>38</Age>
<Lovers number="5"/>
<Married>true</Married>
<Virgin>false</Virgin>
</Staff>
</Staffs>
Back to Top
休息一下,然后做个练习。
练习:
以2.2.4为基础,进行如下修改:
1. 把Virgin作为Lovers的一个属性
2. 为Married增加一个属性'kid',Kevin的kid数为1,其他两个人的kid均为0。
3. 增加一个Staff,基本信息如下:
名字:Wei
姓:Li
年龄:30
谈恋爱的次数:8
婚否:yes
小孩数目:1
virgin :…,你猜?
Back to Top
posted on 2011-01-09 16:12
Antony Lee 阅读(508)
评论(0) 编辑 收藏