xml基础知识

1.1.2 什么是XML

正象HTML一样,可扩展置标语言XML(eXtensible Markup Language)也是一种置标语言。它同样依赖于描述一定规则的标签和能够读懂这些标签的应用处理工具来发挥它的强大功能。这一点,从XML的命名上也可窥见一斑。

“关于此规范的正确题目,亦即XML的正确全名,应该是Extensible Markup Language, eXtensible Markup Language只不过是一个拼写错误罢了。但是,现在简写XML不仅正确,而且正如它在本规范的标题中一样,是Extensible Markup Language的官方名称。

这个名称和简写是由James Clark最先提出的,其它可供选择的名称还包括小型标准置标语言MGML (Minimal Generalized Markup Language), 标准置标语言的小型结构MAGMA (Minimal Architecture For Generalized Markup Applications), 以及互联网置标结构语言SLIM (Structured Language for Internet Markup)。

——Extensible Markup Language (XML) 1.0 Specs, The Annotated Version. ”

从对XML的最初命名可以看出,XML的核心归根结底还是置标。不过,XML这个置标语言可比HTML的功能要强大的多了。

“人”如其名,XML的强大功能来自于“X”。也就是说,XML不但是置标语言,而且是可扩展的(eXtensible)置标语言。XML并非象HTML那样,提供了一组事先已经定义好了的标签,而是提供了一个标准,利用这个标准,你可以根据实际需要定义自己的新的置标语言,并为你的这个置标语言规定它特有的一套标签。准确的说,XML是一种源置标语言,它允许你根据它所提供的规则,制定各种各样的置标语言。这也正是XML语言制定之初的目标所在。

“XML的制定目标为:
  1. XML应该可以在互联网上直接使用(*就象HTML那样好用)。
  2. XML应该支持各种不同的应用方式(*不但包括浏览,还包括对内容的分析)。
  3. XML应该与SGML兼容(*子承父业嘛,后面我们会讲到,SGML是XML的直接先驱)。
  4. 处理XML文件的应用程序应该容易编写(*计算机系的研究生花上两周的工夫就该差不多了)。
  5. XML中的可选特性的数量应该减到最小,最好减至没有(*可选特性经常造成混淆)。
  6. XML文件应该具有良好的可读性,并且比较清晰(*别象HTML那样,如果不借助浏览器,要想读它简直就是对你意志力和耐心的考验)。
  7. 用XML设计新的置标语言应该方便快捷(你不必再去经历标准制定的繁琐程序了)。
  8. XML设计的置标语言应该正式、简洁(不然怎么易写易读?)。
  9. XML文件应该容易编制(想想要用“记事本”写个HTML是一件多么可怕的工作)。
  10. XML标记的简洁性并不重要(你不必再去费尽心机减少标记)。

——Extensible Markup Language (XML) 1.0 Specs, The Annotated Version.”

让我们来考虑一个非常简单的例子。如果我们需要定义一个新的置标语言,叫做FCLML(F_company s Client List Markup Language)——F公司的客户列表置标语言。这个语言应该定义一些标签来代表可联系的客户和有关他们的信息。这组标签很简单,它们的优点是代表了一定的语意。让我们回想一下上一节中这些信息在HTML中是如何用标签〈UL〉和〈LI〉表示的。与之相比,下面这一段代码,显然更加清晰易读:

<联系人列表>
    <联系人>
        <姓名>张三</姓名>
        <ID>001</ID>
        <公司>A公司</公司>
        <EMAIL>zhang@aaa.com</EMAIL>
        <电话>(010)62345678</电话>
        <地址>
            <街道>五街1234号</街道>
            <城市>北京市</城市>
            <省份>北京</省份>
            <ZIP>100001</ZIP>
        </地址>
    </联系人>

    <联系人>
        <姓名>李四</姓名>
        <ID>002</ID>
        <公司>B公司</公司>
        <EMAIL>li@bbb.org</EMAIL>
        <电话>(021)87654321</电话>
        <地址>
            <街道>南京路9876号</街道>
            <城市>上海</城市>
            <省份>上海</省份>
            <ZIP>200002</ZIP>
        </地址>
    </联系人>
</联系人列表>

这一段代码是一个非常简单的XML文件。看上去它和HTML非常相象,但细心的人会发现这里的标签代表的不再是显示格式,而是对于客户信息数据的语意解释。

事实上,用XML定义的置标语言可以根据标记描述的侧重点不同分为两大类。一类偏重于语意描述,正如上面这个例子。还有一类偏重于显示方式的描述,象现在已经出炉的XHTML、SVG、SMIL,后面我们还会详细讲解。值得一提的是,这里对于显示方式的描述不仅限于对文本的描述,还可以包括矢量图形、图象、声音。比如,一个形如〈EMPHASIZE〉的标签在描述文本时可能是要求将文本加粗,而在描述声音时则要求将音量加大。

不过,正如我们上节所述,仅仅将数据置标还不够。为了让别人读懂这些数据,置标语言中的置标标准还需包括:

  • 置标的语法
  • 每个置标的含义

换句话说,如果想让计算机应用程序读懂并能处理这段数据,它还必须知道什么是一个有效的置标(如标签),如何处理一个有效的置标。具体地说,Netscape浏览器如何知道怎样显示上面的这段XML文件?标签〈电话〉是什么含义?它究竟是不是一个合法的标签?它又应该以什么方式表现?因此,我们的置标语言必须能够告诉应用程序它所采用的置标的语法,以便于应用程序对其处理。

在XML中,置标的语法是通过文件类型定义DTD(Document Type Definition)来描述的。也就是说,我们通过DTD来描述什么是有效的标签,从而进一步定义置标语言的结构。在用XML定义的置标语言中,DTD与数据文件是分离的部分。第三章我们将详细讨论DTD的定义方法。这里我们先给出关于上例的DTD描述,让大家先睹为快:

fclml.dtd:
<?xml version="1.0" encoding="GB2312"?>

<!ELEMENT 联系人列表 (联系人)*>
<!ELEMENT 联系人 (姓名,ID,公司,EMAIL,电话,地址)>
<!ELEMENT 地址 (街道,城市,省份)>
<!ELEMENT 姓名 (#PCDATA)>
<!ELEMENT ID (#PCDATA)>
<!ELEMENT 公司 (#PCDATA)>
<!ELEMENT EMAIL (#PCDATA)>
<!ELEMENT 电话 (#PCDATA)>
<!ELEMENT 街道 (#PCDATA)>
<!ELEMENT 城市 (#PCDATA)>
<!ELEMENT 省份 (#PCDATA)>

同样,除了定义置标的语法外,我们还需定义置标的具体含义。为了明确各个标签的意义,XML使用与之相连的样式单(style sheet),由它来向应用程序,比如浏览器,提供如何处理显示的指示说明。一个样式单的具体格式我们在第四章再具体描述,现在我们只需知道,样式单所作的规定可能是这样的:

  1. 每当看到一个〈联系人〉标签,用一个〈UL〉标签显示它。同样,〈/联系人〉转换为一个〈/UL〉标签。
  2. 所有的〈姓名〉标签被转换为〈LI〉标签加以显示。同样,〈/姓名〉转换?LI〉标签。
  3. 所有的〈EMAIL〉标签被转换为〈LI〉标签加以显示。同样,〈/EMAIL〉转换为〈/LI〉标签。

等等...

在这个样式单的例子中,我们使用HTML的标签功能来定义我们的FCLML的显示格式。但如果XML文件不是由浏览器,而是由其它应用程序来进行处理,我们可能采用其它相应的标签。

于是乎,我们的应用处理程序要综合DTD,样式单以及FCLML文件数据三方面要素,根据这些数据和规定来显示它。

看到这里,你可能会长叹一声:这不是越来越复杂了吗?原先只要一个HTML就能把数据和显示方式都包括进去,现在我们需要FCLML文件,DTD,样式单——总共三个文件!这还不算,我们需要一个处理工具把DTD、样式单、FCLML三者合一。别忘了,浏览器只是用来处理一种特定的置标语言(比如HTML)的,而不是用来处理所有置标语言的。这说明我们不但要把三个文件合一,还要制作或购买一个新的应用处理程序。太恐怖了!

“一个被称作XML处理器的软件模型应该能够读入一个XML文件,并解释其内容和结构。XML处理器是基于另一个称作应用的模型来进行这种处理的。

——Extensible Markup Language (XML) 1.0 Specs, The Annotated Version”

的确,对于初学者而言,在使用XML时确实要克服一些障碍,不过在下面一节中,你将看到,这是非常值得的。

XML的第二大优势——超越于格式之上


XML的最大能量来源于它不仅允许你定义自己的一套标记,而且这些标记不必仅限于对于显示格式的描述。XML允许你根据各种不同的规则来制定标记,比如根据商业规则,根据数据描述甚至根据数据关系来制定标记。
可能你还没有觉得这有什么好处。那好,还记得前面两节中那个关于F公司的客户列表的例子吗?现在,我们再来一起对两个不同的文件进行一个详细的比较。

当这个文件使用HTML语言写时,文件的样子如下:

<UL>
<LI>张三</LI>
<UL>
<LI>用户ID: 001</LI>
<LI>公司: A公司</LI>
<LI>EMAIL: zhang@aaa.com</LI>
<LI>电话: (010)62345678</LI>
<LI>地址: 五街1234号</LI>
<LI>城市: 北京市</LI>
<LI>省份: 北京</LI>
<LI>ZIP: 100001</LI>
</UL>

<LI>李四</LI>
<UL>
<LI>ID: 002</LI>
<LI>公司: B公司</LI>
<LI>EMAIL: li@bbb.org</LI>
<LI>电话: (021)87654321</LI>
<LI>地址: 南京路9876号</LI>
<LI>城市: 上海市</LI>
<LI>省份: 上海</LI>
<LI>ZIP: 200002</LI>
</UL>
</UL>


尽管这也是一个存储、显示数据的可行的方法,它的效率和能力却非常有限。不知你是否已有同感,使用偏重于表现的HTML来置标你的数据有很多潜在的问题。我们至少可以看到以下三个严重的问题:

  1. 显示方式内嵌于数据之中
    可以看到,现在这些数据是用列表的形式来表示的。如果突然有一天,你的老板要求你用表格来表示这些数据,那么你不得不重新编码所有这样的HTML文件!天啊,这可能意味着几十页几百页要推翻重来啊!
  2. 在这些数据中寻找信息非常困难
    如果有一天,你需要从这个网页中找到所有北京市客户的信息,你该怎么办?显然,如果你不打算手工寻找的话,你要编一个脚本程序,譬如JavaScript,VBScript。那么,你怎么编写这个程序呢?唯一可行的办法可能就是逐字寻找“北京”这个字符串。即便你找到了所有这些字段,恐怕你也还没有解决所有麻烦。这个“北京”是指城市还是指省份呢?(别忘了北京地区的周边郊县哦。)
  3. 数据自身的逻辑不得不屈服于HTML语言规范的逻辑
    如果你想用Java Applet来处理你的数据,你又遇到了另一个麻烦。你的Java Applet将不得不遍历整个HTML文件,把所有的HTML标记剔除掉,再把剥离出来的有用的数据重新组织。同样,任何一个不是单纯为了显示HTML文件的应用程序,在处理一个HTML文件中的数据时,都不得不做大量额外的工作。

当使用XML时,以上的问题迎刃而解。此时,这段信息的表示是这样的:

<联系人列表>
    <联系人>
        <姓名>张三</姓名>
        <ID>001</ID>
        <公司>A公司</公司>
        <EMAIL>zhang@aaa.com</EMAIL>
        <电话>(010)62345678</电话>
        <地址>
            <街道>五街1234号</街道>
            <城市>北京市</城市>
            <省份>北京</省份>
            <ZIP>100001</ZIP>
        </地址>
    </联系人>

    <联系人>
        <姓名>李四</姓名>
        <ID>002</ID>
        <公司>B公司</公司>
        <EMAIL>li@bbb.org</EMAIL>
        <电话>(021)87654321</电话>
        <地址>
            <街道>南京路9876号</街道>
            <城市>上海</城市>
            <省份>上海</省份>
            <ZIP>200002</ZIP>
        </地址>
    </联系人>
</联系人列表>

可以看出,现在标记为要表现的数据赋予了一定的含义。用这种形式存储时,数据非常地简单明晰,因为它所携带的信息不是显示上的描述,而是信息的语意。就象我们后面将要看到的那样,信息的显示方式已经从信息本身中抽取出来,放在了“样式单”中。

好,我们现在逐条看一下上面所说的XML的三个问题是如何被一一解决的。

  1. 在XML中,显示样式从数据信息中抽取出来,放在样式单文件中。这样,如果需要改动信息的表现方式,无须改动信息本身,只要改动样式单文件就够了。如果这时候老板又让你把列表的数据改用表格显示,你无须再去修改那几十几百个数据信息文件,因为它们和同一个样式单文件相关联,只要改动这个样式单文件就足够了。
  2. 在XML中数据搜索可以简单高效地进行。搜索引擎没必要再去遍访整个XML文件,它只须去找一找相关标记下的内容就够了。也就是说,要想找“北京”,只要看看<城市〉这个标记下的字符串数据是不是匹配就行了。毫不夸张地说,XML的标记为搜索引擎赋予了智慧!
  3. XML是自我描述语言。即便对于一个预先对我们的FCLML一无所知的人,这个文件也是清晰可读的。显然,<ID>002</ID>代表了一个客户的客户身份标识,可是如果面对一个<LI>002,他可能就丈二和尚——摸不着头脑了。再有,看看上面文件中严格的层次结构,你就会发现,信息之间的某些复杂关系,比如树状结构、继承关系,在这里也都得到了绝好的体现。这样一来,那些XML的应用处理程序也会感到轻松多了。

看到这里,你可能已经对XML心悦诚服了。不过,XML的优点还远不止这些哦。

XML的其它优点


上面讲到的XML的两大优势是XML最突出的优点,除此以外,XML至少还有下面三个优点。

  1. XML遵循严格的语法要求

    前面讲过,HTML的语法要求并不严格,浏览器可以显示有文法错误的HTML文件。但XML就不同了,它不但要求标记配对、嵌套,而且还要求严格遵守DTD的规定,比如在前面的client.xml中,你决不能在<联系人></联系人>这对标记外面,再套上一层<地址></地址>标记。

    “和HTML不同,XML非常非常注重准确性。如果语法有丝毫差错,分析器都会停止对它的进一步处理,相应地,除了错误提示外,你看不到任何的显示信息。

    举例来说,对于任何一个XML文件,处理指示都是必须的。而如果一个HTML文件没有开始标记〈HTML〉,在大多数浏览器中仍能通过。因为浏览器通常具备一个内置的修改功能去猜测HTML文件中漏掉了什么,并试图修改这个有误的文件。XML分析器,无论是内嵌于浏览器还是作为独立的处理器,绝对不允许修改。就象我们编译一个程序一样,一个XML文件或者被判别为‘正确’而被接受,或者被判别为‘错误’不予运行。这看上去可能有些武断,不过想想XML的宗旨在于通过非标准的标记传递结构化的数据,一个分析器无法象处理一个已有了一套固定DTD的HTML文件那样猜出到底有什么,又缺什么。

    ——Ken Sall”

    一听说编写XML文件时要遵循严格的语法要求,那些被HTML宠坏了的网页制作者可能会叫苦不迭。其实仔细想想,一个具有良好语法结构的网页文件可以提供较好的可读性和可维护性,从长远来看还是大有好处的。何况这大大减轻了浏览器开发人员的负担,也提高了浏览器的时间空间效率。再有,以后随着XML的自动生成工具和所见即所得的编辑器的问世,XML的编写者也就不用再操心XML的源码是什么样子,更不用去想XML的一些琐碎的语法规定。当然,这对于这类XML的开发工具提出的要求可就比较高了。

  2. XML便于不同系统之间信息的传输

    当今的计算机世界中,不同企业、不同部门中存在着许多不同的系统。操作系统有NT、UNIX,数据库系统有SQL Server、Oracle,...,要想在这些不同的平台、不同的数据库软件之间传输信息,不得不使用一些特殊的软件,非常之不便。而不同的显示界面,从工作站、个人微机、到手机,使这些信息的个性化显示也变得很困难。

    现在有了XML,各种不同的系统之间可以采用XML作为交流媒介。XML不但简单易读,而且可以标注各种文字、图像甚至二进制文件,只要有XML处理工具,就可以轻松地读取并利用这些数据,使得XML成为一种非常理想的网际语言。

  3. XML具有较好的保值性

    XML的保值性来自它的先驱之一——SGML语言。SGML是一套有着十几年历史的国际标准,它最初设计的一大目标就是要为文件提供50年以上的寿命。不要小看文件的寿命问题,想想我们是如何知道我们祖先的悠久而辉煌的历史的。如果不是流传至今的大量历史文献,我们恐怕对“唐宋元明清”没有一点概念;同样,我们的后代也要靠我们留下的文字资料来了解我们。可是现在大部分资料都是电子文档的形式了,有些人已经不屑于把它们打印下来单独存档,而只留一份拷贝就觉得万事大吉了。祸患的种子就是这样埋下的,假定五十年以后,你的子孙面对你留下的一大堆用Word97写的文档,苦于没有软件工具能够打开(你现在还能打开当初用WordStar1.0写的文件吗?),那么这一段历史岂不被抹煞了?如果没有XML,恐怕只有两个办法:要不返朴归真继续使用纸介质,要不不辞劳苦随着软件的更新换代来大规模地转换你的文档到最新的格式。

    幸好,20世纪末的科技先知对这一问题给出了圆满的解决,这就是SGML和XML的设计。它们不但能够长期作为一个通用的标准,而且很容易向其它格式的文件转化。想留下逝去岁月的印迹吗?XML是你明智的选择。

到现在为止,我们已经详细阐述了XML的五大优点。不过,任何事物都不是完美无缺的,XML也有一些固有的缺陷,虽然这些缺陷不是不可弥补的,但它在XML的阳光大道上,还是投下了一些小小的阴影。

XML文件的整体结构   


XML文件的结构包括逻辑结构和物理结构。在这一节里,我们首先来看一看XML文件的逻辑结构。

下面是一个例子,它是有关专有名词解释的XML文件:

[1] <?xml version="1.0" encoding="GB2312" standalone="no"?>
[2] <?xml-stylesheet type="text/xsl" href="mystyle.xsl"?>

[3] <专有名词列表>
[4]     <专有名词>
[5]         <名词>XML</名词>        
[6]         <解释>XML是一种可扩展的源置标语言,它可用以规定新的置标规则,并根据这个规则组织数据</解释>
[7]         <示例>
[8]             <!-- 一个XML的例子 -->
[9]             <![CDATA[
[10]                <联系人>
[11]                <姓名>张三</姓名>
[12]                <EMAIL>zhang@aaa.com</EMAIL>
[13]                </联系人>
[14]            ]]>
[15]        </示例>
[16]    </专有名词>
[17]</专有名词列表>

一个XML文件最基本的构成是

    XML声明
    处理指示(可选)
    XML元素

在本例中,[1] 是一个XML声明[3]——[17] 是文件中的各个元素

除此以外,上面例子中出现的其它逻辑要素还有:

   [1][2] 处理指示
    [8] 注释
    [9]——[14] CDATA
    在
[5]行的“<名词>XML</名词>”中,“<名词>”“</名词>”是标记,“XML”是字符数据

用XML声明作为开头   


当你开始着手写一个XML文件时,最好以一个XML声明作为开始。之所以说“最好”,是因为XML声明在文件中是可选内容,可加可不加,但W3C推荐加入这一行声明。因此,作为一个良好的习惯,我们通常把XML声明作为XML文件的第一行。

XML声明是处理指示的一种,处理指示比较复杂,我们将在2.2.6节中再详细讲述。不过,XML声明相对简单一些,形象地说,它的作用就是告诉XML处理程序:“下面这个文件是按照XML文件的标准对数据进行置标的”。

一个最简单的XML声明是这样的:

<?xml version = "1.0"?>

象所有处理指示一样,XML声明也是由“<?”开始,“?>”结束。在“<?”后面紧跟着处理指示的名称,在这里是“xml”。

XML声明中要求必须指定“version”的属性值。同时,声明中还有两个可选属性,分别是“standalone”和“encoding”。因此,一个完整的XML声明是这样的:

<?xml version  = "1.0"
standalone     = "no"
encoding       = "GB2312"?>

下面,就让我们来看看这几个属性的具体含义:

  • version属性
    刚才我们提到,在一个XML的处理指示中必须包括version属性指明所采用的XML的版本号,而且,它必须在属性列表中排在第一位。由于当前的XML最新版本是1.0,所以我们看到的无一例外的都是:version = "1.0"。
  • standalone属性
    这个属性表明该XML文件是否和一个独立的置标声明文件配套使用。因此,如果该属性置为“yes”,说明没有另外一个配套的DTD文件来进行置标声明。相反,如果这个属性置为“no”,则有可能有这样一个文件。(注意,也可能没有。)
  • encoding属性
    所有的XML语法分析器都要支持8位和16位的编码标准。不过,XML可能支持一个更庞大的编码集合。在XML规范的4.3.3节中,列出了一大堆编码类型。但一般我们用不到这么多编码,只要知道下面几个常见的编码就可以了:
        简体中文码:GB2312
        繁体中文码:BIG5
        西欧字符: UTF-8
    采用哪种编码取决于你文件中用到的字符集。尤其要注意的是,在前面的例子中,我们看到标签是可以用中文来写的,这时你务必要在声明中加上encoding = "GB2312"的属性噢。

    2.2.3.2 字符数据

      一对标记之间出现的字符数据可以是任何合法的UNICODE字符,但不能包含字符“〈”。这是因为,字符“〈”被预留用作标记的开始符。

    在XML中,起始和结束标记之间出现的所有合法字符都被忠实地传给XML处理程序。比方说

    〈格式>一段文字〈/格式>

    〈格式>
    一段文字
    〈/格式>

    是不同的,因为后者的文本数据比前者多了两个换行符。

    为了避免把字符数据和标记中需要用到的一些特殊符号相混淆,XML还提供了一些有用的实体引用。我们会在后面详细介绍有关“实体引用”的概念,现在,我们只须了解,当在字符数据中需要使用这些特殊符号时,我们采用它的实体引用来代替。这些特殊的XML实体引用包括:

    字符实体引用
    >&gt;
    <&lt;
    &&amp;
    "&quot;
    &apos;

    这样,如果我们需要在“示例”这个标记中出现文本

    “<姓名>张三</姓名>”

    正确的写法应该是:

    〈示例〉&lt;姓名&gt;张三&lt;/姓名&gt;〈/示例〉

    容易理解,字符“〈”的实体引用是必不可少的,为“〉”设立实体引用同样是为了避免与标记混淆,而字符“&”的实体引用则防止它与实体引用中开头所用的“&”相混淆。那么,我们什么时候需要用到剩下两个字符的实体引用呢?在标记中可以为标记设立属性,而XML规定属性值必须用“"”括起来。因此,当属性值中出现字符“"”时,需要将它用实体引用代替。请看下面的例子:

    <STATEMENT VALUE = "She said, "Don t go there!"">

    正确的写法应该是:

    <STATEMENT VALUE = "She said, &quot;Don&apos;t go there!&quot;">

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值