共享社区

首页 » 编程技巧共享 » WEB编程相关文章 » 潜心学习XML
abc - 2008-5-28 11:47:00
XML的全称是Extensible Markup Language,意思是可扩展的标识语言,是SGML(Standard Generalized Markup Language)的一个子集。1998年2月,W3C组织发布了XML1.0标准,其目的是为了在Web上能以现有的超文本标识语言(HTML)的使用提供,接收和处理通用的SGML。XML以一种开放的,自我描述的方式定义了数据结构,在描述数据内容的同事能突出对结构的描述,从而体现出数据与数据之间的关系。XML的最新版本是1.1,于2004年2月4日发布。目前大多数的应用还是基于XML1.0的推荐标准。1.0版本的规范在下面网址中定义:
http://www.w3.org/TR/2004/REC-xml-20040204/

    XML不是(X)HTML的扩展,两者之所以看起来很像,是因为它们都是SGML发展而来的标识语言,语法很相似,标识的使用也很相似。HTML只是SGML的一个子应用,它的DTD(Document Type Definition)被固定下来,所以不能用来定义新的应用。而XML不同,我们可以根据自己的需要,随意定义我们自己的DTD,所以,利用XML,可以定义出新的应用,比如,RDF(Resource Description Framework,资源描述框架,blog中经常看见的RSS1.0就是RDF Site Summary,RDF网站摘要,关于RSS,我将在潜心学习RSS中去认识它),CDF(Channel Definition Format,通道定义格式,微软在IE4.0中引入的一个新功能。基于CDF,网站可以通过活动通道将数据聚合到设置为活动桌面的用户桌面上)。

    XML规范的制定者之一Tim Bray说,XML的设计出发点是取SGML的优点,去除复杂的部分,使其保持轻巧,可以在Web上工作。

  XML的应用非常广泛,计算机和网络的世界里,处处活跃着它矫健轻快的身影,或为配置文件,或为数据存储,或为数据传输使用的格式。XML已经成为事实上的数据交换格式的标准,使用XML,意味着所有设备,比如手机,PDA,信息家电等等,都可以轻松的读取,解析你的数据。
   
    XML很重要的两个特性:
    一:XML文档仅仅描述数据,它不关心数据是如何表现外观的,比如字体大小,颜色,间距之类的,所以它能将数据和数据的表现方式完全的分离开,这个特性很重要,HTML就万万做不到这种完全的分离,所以W3C组织不得不推出一个XHTML,作为HTML向XML过度的产物。

    二:XML对文档的格式要求非常严格,符合标准的XML文档就是格式良好的XML文档(Well-Formed XML Documents)。这是使得XML文档能被普遍认可的一个特点。严格的文档格式,减轻了解析的复杂性。相对来说,HTML的文档格式就非常松散,解析起来就比较复杂,也造成了浏览器兼容的问题。XML文档格式的要求有下面几点:
    1、所有的标签都必须关闭,开始标签有对应的结束标签,空标签必须被关闭。
    2、所有的标签都区分大小写
    3、所有的标签都必须合理嵌套
    4、所有的标签的属性值必须用收引号("")或单引号('')括起来
    5、XML文档有且只能有一个根元素
    6、(还有其他的嘛?)

本章到此结束,重点掌握XML与HTML的异同点,XML的两个特性。


    推荐一个XML编辑工具,强大的XMLSpy,我用的是2008版。


    XML文档的结构可以从物理和逻辑两方面来看。

        一、从物理上而言,文档由称为实体(entities)的存储单元组成,实体都是具有内容并且都通过实体的名字进行标识(文档实体和外部DTD子集除外)。实体可以是一段文本,一个文件,一个数据库记录或者其他包含数据的项目,一个实体可以引用其它的实体,从而将它们包含在文档中。文档开始于“根(root)”或者文档实体(document entity)。格式良好的XML文档形成了一种层次树结构,这个树结构的树根就是文档实体,与其它实体不同,文档实体没有名字,只是用于表示文档树的根。XML文档的根元素被称位文档元素(document element),它和在其外部出现的处理指令,注释等作为文档实体的子节点,而根元素本身和其内部的子元素也是一棵树。

        实体可以包含已分析(parsed)的或未分析的(unparsed)数据。已分析的数据由字符组成,其中一些字符组成字符数据,另一些字符组成标记。已分析的实体(parsed entity)内容被成为它的代替文本,这个文本被看称是文档整体的一部分,在XML处理器分析XML文档时,凡是文档中出现引用已分析实体的地方,都将被该实体的内容所替换。未分析的实体(unparsed entity)是一种资源,它的内容可以是也可以不是文本,并且,如果是文本的话,可以不是XML文本,每一个未分析的实体有一个相关联的用名字标识的记号(notation)。除了要求XML处理器能向应用程序提供可用的实体和记号的标志符之外,XML对未分析的的实体内容不做任何限制。已分析的实体以实体引用的方式通过名字来调用,未分析的实体通过ENTITY或ENTITIES属性中给出的名字来调用。

        二、逻辑上而言,文档由声明,元素,注释,字符引用和处理指令组成,在文档中,所有这些都是通过显式的标记(markup)来指明的。XML标记(markup)包括开始标签(tag)、结束标签、空元素标签、实体引用、字符引用、注释、CDATA 段定界符、文档类型声明、处理指令、XML声明、文本声明以及任何在文档实体顶层的空白(即,在文档元素之外,且不在任何其它的标记内部)。
    其它所有非标记的文本组成文档的字符数据。
        XML文档在逻辑上主要由以下五个部分组成:
        1、XML声明
        2、文档类型声明
        3、元素
        4、注释
        5、处理指令

    下面具体介绍XML文档逻辑上的五个部分。

    1、XML声明
    XML文档总是以一个XML声明开始的,其格式如下
        <?xml 版本信息 [编码信息] [文档独立性信息]?>
    其中,编码信息和文档独立性信息可以不写,而使用默认值。

    需要注意的是,XML声明总是在XML文档的最前面,其前面不能出现任何字符。

    下面是几个例子:

    <?xml version="1.0"?>
    <!--版本信息声明-->

    <?xml version="1.0" encoding="ISO-8859-1"?>
    <!--编码信息声明.默认值是"UTF-8"-->

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <!--文档独立性信息声明,如果文档依赖于外部文档,则需要将standalone属性设置为"no"-->


    2、文档类型声明

    DTD(Document Type Definition),文档类型定义。

    首先提一个问题,如果你的一个XML文档给别人使用,别人怎么才能正确地定义XML文档中的元素,属性呢?就好像我们用Struts时,我们需要配置struts-config.xml,但是怎么保证我们的配置是正确的?答案就是用DTD来验证。

    一个遵循XML语法规则,并遵守相应DTD文件约束的XML文档称为有效的XML文档。

    XML从SGML继承了用于定义语法规则的DTD机制,DTD文件本身是不需要遵循XML规则的。大部分的XML应用都是使用DTD来定义的(还有一部分是用XML Schema来定义的,XML Schema在其专题中学习)。HTML就有一个标准的DTD文件,所以其组织结构和所有的标签都是固定的,DTD文件本身也是一个文本文件,通常用 ".DTD"为其扩展名。

    文档类型声明的作用就是指出XML文档所用的DTD,文档类型声明有两种形式。

    一种是在XML文档中给出DTD,如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE OrganizationChart [
        <!ELEMENT OrganizationChart (Name,Office)>
        <!ELEMENT Name (#PCDATA)>
        <!ELEMENT Office (#PCDATA)>
        ]>

    <OrganizationChart>
    <!--OrganizationChart是该XML文档的document element-->
        <Name>Toone,INC.</Name>
        <Office>zhuhai</Office>
        <!--因为DTD中定义了Name,Office两个元素的顺序,Office元素不能放在Name元素的前面,否则不是有效的XML文档-->
    </OrganizationChart>

    另一种是在一个外部文件定义的DTD文件,如下:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE OrganizationChart SYSTEM "dtdTest.dtd" >
    <OrganizationChart>
        <Name>Toone,INC.</Name>
        <Office>zhuhai</Office>
    </OrganizationChart>
    对应DTD文件dtdTest.dtd内容为:
    <?xml version="1.0" encoding="UTF-8"?>
    <!ELEMENT OrganizationChart (Name,Office)>
    <!ELEMENT Name (#PCDATA)>
    <!ELEMENT Office (#PCDATA)>


    3、元素

    在XML中,元素由开始标签、元素内容和结束标签构成,对于空元素,由空元素标签构成。
    每一个元素都有一个用名字标识的类型,同时它可以由一个属性说明集,每一个属性说明有一个名字和一个值。
    在给元素命名的时候要注意,以"xml"或其他任何匹配(('X'|'x')  ('M'|'m' )('L'|'l' ))的字符串开头的名字,被保留用于XML规范的当前版本或者后续版本的标准化。此外,在给元素命名时,还要遵循下列规范:
        1、名字只能以字母、下划线(_)或者冒号(:)开头;
        2、名字中可以包含字母、数字、下划线以及其他在XML标准中允许的字符;
        3、名字中不能包含空格;
        4、名字中尽可能不要使用冒号(:),因为冒号在名字空间中被用于分隔名字空间前缀和本地部分。

    元素的四种形式:
        1、空元素
        2、带有属性的空元素
        3、带有内容的元素
        4、带有内容和属性的元素

    在一个元素的内容中,字符数据可以是不包含任何标记的起始定界符和CDATA段的定界符的任意字符串,也就是会所在元素的内容中,字符数据不能有和号(&)和小于号( <),也不能有字符串"]]>"。那么如果我们要用这些字符的话,必须用他们对应的字符引用和实体引用来表示,见下表:

    元素内容的字符引用和实体引用
    字符          字符引用
    (十进制代码)
            字符引用
    (十六进制代码)
            预定义实体引用
    <        <
            <
            <
    >
            >
            >
            >
    "
            
           
            "
    '
           
           
            '
    &
           
           
            &

    CDATA段中包含的都是纯字符数据,在字符数据可以出现的任何地方都可以使用CDATA段。
    CDATA段主要用于需要将整个文本解释为字符数据而不是标记的情况下。CDATA段中的内容不被XML处理器分析,所以可以在其中包含任意的字符。


    4、注释

    注释用于对文档中的内容起到一个说明作用。
    在XML文档中,注释可以出现在文档中其它表ijizhiwai的任何闻之,另外,它们还可以在人当类型声明中语法(grammar)允许的地方出现。
    XML的注释和HTML的注释类似,都是以<!--开始,以-->结束。位于<!--和-->之间的数据将被XML处理器忽略。
    使用XML注释需要注意一下五点:
        1、注释不能出现在XML声明之前,XML声明必须是文档最前面的部分。下面的情况是不允许的:
    <!--Author:Jason Chen-->
    <?xml version="1.0"?>

        2、注释不能出现在标记中,下面的例子是非法的:
    <author<!--This document author-->>Jason Chen</author>

        3、注释可以包围和隐藏标记,但是要注意,在注释掉标记以后,要保持文档的完整结构。
        4、字符串"--"(双连字符)不能出现在注释中。

    5、处理指令

    处理指令(Processing Instructions)允许文档中包含由应用程序来处理的指令。在XML文档中,有可能会包含一些非XML格式的数据,这些数据XML处理器无法处理,我们可以通过处理指令来通知其它应用程序来处理这些数据。
    处理指令的语法和XML声明类似,以<?开始, 以?>结束。一个常见的使用样式表单的处理指令如下所示:
    <?xml-stylesheet href="style.css" type="text/css"?>

    在开始标记<?后的第一个字符"xml-stylesheet"叫做处理指令的目标,它必须标识要用到的应用程序,要注意的是对于其它的非W3C定义的处理指令不能以字符串"XML"和"xml"开头;其余的部分是传递给应用程序的字符数据。应用程序从处理指令中取得目标和数据,执行要求的动作。

    处理指令的目标可以是要使用的程序的名字,或者是一个类似于xml-stylesheet这样的很多程序可以识别的通用标识符。不同的应用程序支持不同的处理指令,对于不认识的处理指令,大多数应用程序采取忽略的方式进行处理。

    xml-stylesheet处理指令总是放在XML声明之后,第一个元素之前。其它的处理指令可以放在除了标记的内部和XML声明之前的任何位置。
    要注意,虽然XML声明和处理指令的语法形式相似,但XML声明并不是处理指令,XML处理程序对XML声明和处理指令采取的是不同的处理方式。


    本章学习到此为止,下一章学习如何编写DTD。

    本章大概内容:
    1、为什么需要DTD
    2、XML文档如何使用DTD
        1)内部定义DTD
        2)关联外部DTD
    3、DTD的结构
        1)元素类型声明
        2)属性列表声明
        3)实体声明
        4)记号声明


        对于一个格式良好的XML文档,我们只能保证这个文档的格式符合XML规范,但是元素与元素的关系,元素与属性的关系,属性的取值,我们就无法保证了。对于一个格式良好的文档,如果只是在有限的应用中使用,或者是用于存储和传输,那么它也能能够很好的满足我们的应用,但是如果要其它的用户了解你所写的 XML文档,或者与其它应用进行数据的交换,那么就有必要提供一种机制,来保证我们写的XML文档和别人所写的XML文档在结构上是相同的,元素与元素之间的关系是正确的,属性的取值也是符合要求的,那么这种机制在XML规范中已经为我们提供了,那就是前一章中介绍过的文档类型声明中提到的DTD。

    DTD(Document Type Definition),文档类型定义。

        在XML标准中,描述了如何创建DTD,以及如何将它与根据它的规范所编写的XML文档相关联,并且还定义了XML处理器应该如何对DTD进行处理。有了DTD就可以检测XML文档的结构是否正确。
    DTD为XML文档的编写者与处理者提供了共同遵循的原则,使得与文档相关的各种工作有了统一的标准。

    如何在XML文档中引入DTD

    通过在XML文档中包含文档类型声明,来建立当前文档和DTD的关联。当进行有效性验证的XML处理器读到该声明时,它获取DTD,并根据其中定义的规则对文档进行检验。文档类型声明必须位于XML声明之后,且在根元素(文档元素)之前。不过,在XML声明和文档类型声明之间可以插入注释和处理指令。
    我们可以直接在XML文档中定义DTD,也可以通过URI引用外部的DTD文件,或者同时采用这两种方式。
    上一章中,已经学习过如何通过包含文档类型声明来建立与DTD的关联。现在来分析一下这两种包含方式。

    在XML文档内部给出DTD的方式:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE OrganizationChart [
        <!ELEMENT OrganizationChart (Name,Office)>
        <!ELEMENT Name (#PCDATA)>
        <!ELEMENT Office (#PCDATA)>
        ]>

    <OrganizationChart>
    <!--OrganizationChart是该XML文档的document element-->
        <Name>Toone,INC.</Name>
        <Office>zhuhai</Office>
        <!--因为DTD中定义了Name,Office两个元素的顺序,Office元素不能放在Name元素的前面,否则不是有效的XML文档-->
    </OrganizationChart>

        文档类型声明由<!开始,后面紧跟一个关键字DOCTYPE,然后是文档根元素的名字,接下来是标记声明块,标记声明块放在中括号[]之间,由一个或者多个标记声明构成,最后由>结束。

        在DTD中,所有的关键字都是大写的。不过,在DTD中定义的元素和属性的大小写是可以任意制定的,但是要注意,因为XML文档是大小写相关的,所以一旦给一个元素命名,那么在整个文档中要使用相同的大小写。例如,organizationchart和OrganizationChart是不同的两个元素名。

        在XML文档中定义DTD,比较直观,修改也比较方便,而且不用担心XML处理器找不到DTD,但是它也有一些缺点:

        1、在文档中定义DTD会导致文档本身的长度增加,在传输数据时,即使不需要验证文档的有效性,这些声明也要一起传输。

        2、如果多个XML文档要共用同一个DTD,我们就需要在每一个文档中加入DTD。


        引进外部DTD方式:
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE OrganizationChart SYSTEM "dtdTest.dtd" >
    <OrganizationChart>
        <Name>Toone,INC.</Name>
        <Office>zhuhai</Office>
    </OrganizationChart>
        对应DTD内容为:
    <?xml version="1.0" encoding="UTF-8"?>
    <!ELEMENT OrganizationChart (Name,Office)>
    <!ELEMENT Name (#PCDATA)>
    <!ELEMENT Office (#PCDATA)>

    在文档类型声明时,用管间质SYSTEM或PUBLIC来指出外部DTD文件的位置,使用SYSTEM关键字的声明语法如下:

    <!DOCTYPE 根元素的名字 SYSTEM "外部DTD文件的URI">

    SYSTEM关键字表示文档使用的是私有的DTD文件,“外部DTD文件的URI”可以是相对URI或者绝对URI。例如上面的例子使用的就是相对URI:

    <!DOCTYPE OrganizationChart SYSTEM "dtdTest.dtd" >

    使用PUBLIC关键字的声明语法如下:

    <!DOCTYPE 根元素的名字 PUBLIC "DTD的名字" "外部DTD文件的URI">

    PUBLIC关键字用于声明公共的DTD,并且这个DTD还有一个名称,"DTD的名称"也称为公共标识符(public identifier)。这个DTD可以存放在某个公共的地方,XML处理程序会根据名称按照某种方式去检索DTD,如果XML处理器不能根据名称检索到 DTD,就会使用"外部DTD文件的URI"来查找该DTD。例如Java web开发的web.xml中的DTD声明(版本不同会稍有不同,我们只关注它的结构):

    <!DOCTYPE web-app PUBLIC '-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN'
    'http://java.sun.com/dtd/web-app_2_3.dtd'>


    DTD名称与XML名称略有不同,他们只能包含ASCII字母和数字符号、空格、回车符、换行符和一些标点符号:-'()+,/:=?;!#@*$_%.

    公共DTD名称要遵守一些约定。如果一项DTD是ISO标准,它的名称要以字符串"ISO"开始。如果是一个非ISO的标准组织批准的DTD,它的名字以加号(+)开始。如果不是标准组织批准的DTD,它的名称以连字符(-)开始。这些开始字符或字符串后接双斜杠(//)和DTD所有者的名字(比如上面例子的Sun Microsystems,Inc.),之后是另一个双斜杠和DTD描述的文档类型,接着优势一个双斜杠后接ISO 639语言标识符,如EN表示英语,ZH表示中文。例如:

    <!DOCTYPE OrganizationChart PUBLIC "-//Jason Chen//DTD organization chart 1.0//ZH" "dtdTest.dtd">

    在上一章我们提到,如果我们的文档不依赖于外部文档,在XML声明中,可以通过standalone="yes"来声明这个文档是独立的文档。如果文档依赖于外部文档,可以通过standalone="no"来声明。当我们使用外部DTD文件时,就需要将属性standalone的值设置为"no"。
    在实际应用中,很少使用standalone属性,它的主要用途是作为XML处理器行业其他应用程序的标志,表示是否需要获取外部内容。如果文档依赖于外部文档,即使我们不使用standalone属性,XML处理器也能很好地进行处理。

    DTD的结构:

    DTD的结构一般由以下四种声明构成:
        1、元素类型声明
        2、属性列表声明
        3、实体声明
        4、记号声明
    一个典型的文档类型定义文件会吧所要创建的XML文档的元素结构、属性类型、实体引用等预先进行定义。
    下面分别介绍这四种声明。

    1、元素类型声明:

    一个DTD不仅要告诉XML处理器它所对应的文档根元素,而且还要告知处理器,文档的内容和结构,描述清楚文档结构中的每一个细节。
    元素类型声明不但说明了每一个文档中可能存在的元素,给出了元素的名称,而且给出了元素的具体类型。
    一个XML元素可以为空,也可以只包含字符数据,还可以有若干个子元素,而这些子元素同时又可以拥有它们的子元素。
    元素类型声明采用如下的语法格式:
    <!ELEMENT 元素名称 元素内容说明>
    元素内容说明可以指明五种可能的元素内容形式:#PCDATA、子元素、混合内容、EMPTY和ANY。
    下面详细说明每一种元素内容说明。

    #PCDATA:

    关键字#PCDATA说明元素包含字符数据。
    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE OrganizationChart [
        <!ELEMENT OrganizationChart (Name,Office)>
        <!ELEMENT Name (#PCDATA)>
        <!ELEMENT Office (#PCDATA)>
        ]>
    <OrganizationChart>
        <Name>Toone,INC.</Name>
        <Office>ZhuHai</Office>
    </OrganizationChart>

    子元素:

    当一个元素只包含子元素,而没有字符数据时,则称此元素类型具有元素型内容(element content)。
    在该类型的元素声明时,通过内容模型来指定在其内容上的约束。内容模型是决定子元素类型和子元素出现顺序的一种简单语法。

原文出处:http://www.blogjava.net/asenyifei/
1
查看完整版本: 潜心学习XML