• 02.XML技术


    一、XML简介

    XML指可扩展标记语言(eXtensible Markup Language),是用来传输和存储数据的,是一种通用的数据交换格式,可以使数据在不同应用程序间交换,具有很强的可扩展性。

     

    • 可扩展,是指用户可以按照XML规则自定义标记,英文、中文皆可。
    • 标记语言,很类似于HTML。XML不是代替HTML的,是对HTML的补充。

    W3C在1998年2月发布1.0版本;W3C在2004年2月发布1.1版本,但因为1.1版本不能向下兼容1.0版本,所以1.1没有人用。同时,在2004年2月W3C又发布了1.0版本的第三版。我们要学习的还是1.0版本!!!

    XML是不作为的,就是说“XML不会做任何事情”。XML被设计用来结构化、存储和传输信息。

    XML的作用:

    • 数据存储:可作为小型关系数据库,表示数据之间的关系,用来当数据库存储数据。
    • 数据交换:不同语言之间、程序之间、系统之间交换数据。
    • 程序的配置文件:这也是大家使用XML最常见的目的。比如,连接数据库时,在xml配置文件中定义数据库连接地址、用户名和密码,如果修改数据库的信息,不需要修改程序源代码,只要修改配置文件就可以了。

    XML与HTML的比较:

    • HTML是用来显示数据,其焦点是数据的外观;XML是用来传输和存储数据,其焦点是数据的内容。
    • HTML是不区分大小写的,而XML是严格区分大小写的。
    • HTML可以有多个根元素,而格式良好的XML有且只能有一个根元素
    • HTML中属性值的引号是可用可不用的,XML中的属性值必须放在引号中。
    • HTML中空格是自动过滤的,而XML中空格则不会自动删除。
    • HTML中的标记是预定义的,而XML中的标记可以根据需要自己定义,并且可扩展。

    我们举个例子来看一下我们身边的XML:

    中国有很多省份,每个省份下又有很多城市,这些省市之间的关联关系可以通过一张树状结构图来描述,如图所示。

     

    图中直观地描述了中国与所辖省、市之间的层次关系。但是对于程序而言,解析图片内容非常困难,这时,采用XML文件保存这种具有树状结构的数据是最好的选择。

    下面的代码就可以描述出上图所示的关系。

    <?xml version="1.0" encoding="UTF-8"?>
    <中国>
        <河北>
            <城市>张家口</城市>
            <城市>石家庄</城市>
        </河北>
        <山西>
            <城市>太原</城市>
            <城市>大同</城市>
        </山西>
    </中国>

    二、XML语法

    一个基本的XML文档通常是由文档声明(序言)文档元素两部分组成。下面我们来分别介绍一下。

    1、文档声明

    在一个XML文档中,必须包含一个XML文档声明,并且必须位于文档的第一行。语法格式:

    <?xml 版本信息 [编码信息] [文档独立性信息]?>

    文档声明以符号“<?”开头,以符号“?>”结束,中间可以声明版本信息、编码信息以及文档独立性信息。

    需要注意的是,在“<”和“?”之间、“?”和“>”之间以及第一个“?”和xml之间不能有空格

    另外,中括号([])括起来的部分是可选的。完整的代码如下:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    • version属性表示XML的版本。目前,最常用的XML版本是1.0。
    • encoding属性用来说明XML文档所使用的编码方式,默认情况下,XML文档使用的是UTF-8编码方式。
    • standalone属性用来声明这个文档是否是独立的文档,默认情况下,standalone属性的值为no,表示文档依赖于外部文档。

    这里提到的依赖,是指文档需要DTD文件验证其中的标识是否有效,或者需要CSS(层叠样式表,HTML样式表)、XSL(可扩展样式表语言,XML样式表)文件来控制显示外观。

    编码详解:

    我们来编写一段代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <note>
        <from>Tom</from>
        <to>Jerry</to>
        <message>你好</message>
    </note>

    在XML文档中不指定任何编码属性时,我们使用Windows记事本保存XML要注意:

    如果XML 中包含非ASCII字符(中文、法文等),我们将文件“另存为”编码ANSI后,使用IE浏览器浏览将会出错。

    ANSI编码是一种对ASCII码的拓展,ASCII能表示128个字符,ANSI能表示256个字符。

     

    如果将文件“另存为”编码UTF-8或Unicode后,使用IE浏览器浏览将不会出错。

     

    如果将文件“另存为”编码UTF-8或Unicode后,而XML的encoding指定为"GB2312",使用IE浏览器浏览汉字将会显示乱码。

     

    所以XML文档的保存编码一定要和文档声明中的encoding一致起来,最好都使用UTF-8。

     

    【补充知识】ASCII、ANSI、GB2312、GBK、Unicode、UTF-8编码:

    ① ASCII:首先明白计算机能识别的都是二进制010101010这种代码,但是这些010101010人是难以看懂的,于是美国人就用ASCII码(American Standard Code for Information Interchange,美国信息交换标准码)制作了一张表,里面包含从a、b、c.......@%$等128个字符。但是,美国用的字母,德国、法国,还有咱们中国汉字几万个,一张表存不下。

     

    ② ANSI:扩展了ASCII,能表示256个字符。

    ③ GB2312、GBK:汉字内码扩展规范(GBK即“国标”、“扩展”汉语拼音的第一个字母)。GBK是在GB2312标准基础上的内码扩展规范。GBK编码规定,计算机不能在每次都只读一个字节(00000000,8位表示一个字节),而是要先看看第一位是不是为0,要是为0的话,就当作ASCII码来读入一个字节,不然的话就读入两个字节(汉字太多一个字节存不下,读入两个字节表示汉字,就查GBK)。

    ④ Unicode:那么每个国家一个编码表,相互通信的时候由于解码方式不同就会导致乱码(用ASCII发邮件,计算机查ASCII表转换成对应0101010二进制发送出去,接收的人用GBK解码,将0101010查GBK表肯定就查不到啊)。于是,国际组织就发明了一套公用的表Unicode编码,将所有国家,所有字符都收进去了,从0一直到100多万(用三个字节表示)。

    由于历史方面的原因,我们经常说的Unicode 通常就是 UTF-16。

    ⑤ UTF-8:虽然有了世界通用的表Unicode,但是有人就发现这有点浪费资源啊。每次让计算机读取三个字节,然后参照Unicode表解码,那么像a、b...0、1、2...这些一个字节就够了的就太浪费了。于是UTF-8、UTF-16、UTF-32这些编码方案就出现了。UTF-16是用两个字节来编码所有的字符,UTF-32则选择用4个字节来编码,UTF-8为了节省资源,采用变长编码,编码长度从1个字节到4个字节不等。由于互联网大部分是1个字节(代码很多英文的),所以最后大家选择用的最多的还是UTF-8。

    2、元素定义

    在XML文档中,主体内容都是由元素(Element)组成的。元素一般是由开始标记、属性、元素内容和结束标记构成,具体示例如下:

    <城市 类型="直辖市">北京</城市>

    上面的示例中,“<城市>”和“</城市>”就是XML文档中的标记,标记的名称也就是元素的名称。在一个元素中可以嵌套若干子元素。

    如果一个元素没有嵌套在其它元素内,则这个元素称为根元素。根元素是XML文档定义的第一个元素。

    如果一个元素中没有嵌套子元素,也没有包含文本内容,则这样的元素称为空元素,空元素可以不使用结束标记,但必须在开始标记的结束符“>”前增加一个正斜杠“/”来说明该元素是个空元素,例如:<img></img>可以简写成<img/>。

    在XML文档中,元素的名称可以包含字母、数字以及其他一些可见的字符,但是在命名XML元素时,应该遵守以下规范。

    (1)XML是强标记语言,区分大小写,例如: <P>和<p>是两个不同的标记。

    (2)元素名称中,不能包含空格、冒号、分号、逗号和尖括号等,元素不能以数字开头,否则XML文档会报错。<7eleven />

    (3)建议不要使用“.”,因为在很多程序语言中,“.”用于引用对象的属性。<user.id />

    (4)建议不要用减号(-),而用下划线(_)代替,以避免与表达式中的减号(-)运算符发生冲突。<user-name />

    (5)建议元素名称不要以字符组合xml(或XML、或Xml等)开头。<xmlfile />

    (6)建议元素名称的大小写尽量采用同一标准,要么全部大写,要么全部小写。

    (7)元素名称可以使用非英文字符,例如中文,但有些软件可能不支持英文字符以外的字符,在使用时应考虑这种情况。

    3、属性定义

    在XML文档中,可以为元素定义属性。属性是对元素的进一步描述和说明。在一个元素中,可以有多个属性,并且每个属性都有自己的名称和取值,具体示例如下:

    <售价 单位="元">68</售价>

    在上面的示例中,<售价>元素中定义了一个属性“单位”。需要注意的是,在XML文档中,属性的命名规范同元素相同,属性值必须要用双引号(")或者单引号(')引起来,否则被视为错误。

    4、注释

    如果想在XML文档中插入一些附加信息,比如作者姓名、地址或电话等信息,或者想暂时屏蔽某些XML语句,这时,可以通过注释的方式来实现,被注释的内容会被程序忽略而不被解析和处理。XML注释和HTML注释写法基本一致,具体语法格式如下所示:

    <!-- 注释信息 -->
    • 注释不能嵌套:  <!--  <!-- -->  -->
    • 注释也不能放到第一行,第一行第一列必须放文档声明。

    5、特殊字符处理(转义字符)

    和HTML类似

    预定义实体

    特殊字符

    含义

    &lt;

    小于

    &gt;

    大于

    &amp;

    &

    和号

    &apos;

    '

    单引号

    &quot;

    "

    引号

    6、CDATA区(格式记住)

    Character Data,字符数据,指一段不想被程序解析的原始数据,这里面的数据会原封不动的显示出来,不会被转义。

    <![CDATA[
        一段代码
    ]]>

    例如,想直接存储以下代码,而不使用转义字符。if(a<b && b<c && d>f) {}

    代码: <![CDATA[ if(a<b && b<c && d>f) {} ]]> 

    把特殊字符,当做文本内容,而不是标签。

    注意:

    ① CDATA 部分不能包含字符串 "]]>",也不允许嵌套的 CDATA 部分。

    ② 标记 CDATA 部分结尾的 "]]>" 不能包含空格或折行。

    三、约束

    在现实生活中,如果一篇文章的语法正确,但内容包含违法言论或逻辑错误,这样的文章是不允许发表的。

    同样,在编写XML文档时,其内容必须满足某些条件的限制,例如以下代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <书架>
        <>
            <书名>JavaWeb程序开发入门</书名>
            <作者>传智播客</作者>
            <售价>60</售价>
            <售价>30</售价>
        </>
    </书架>

    在上面的示例中,尽管这个XML文档结构是正确的,用IE浏览器打开它也不会出现任何问题,但是,由于XML文档中的标记是可以随意定义的,同一本书出现了两种售价,如果仅根据元素名称区分哪个是原价,哪个是会员价,这是很难实现的。为此,在XML文档中,定义了一套规则来对文档中的内容进行约束,这套约束称为XML约束。

    对XML文档进行约束时,同样需要遵守一定的语法规则,这种语法规则就形成了XML约束语言。目前,最常用的两种约束语言是DTD约束Schema约束

    四、DTD约束

    DTD(Document Type Definition,文档类型定义)的作用是定义XML文档的合法构建模块,使用一系列的合法元素来定义文档结构。在一个DTD文件中,可以包含元素的定义、元素之间关系的定义、元素属性的定义以及实体和记号的定义。

    1、DTD定义

    我们来看实例代码book.xml

    <?xml version="1.0" encoding="UTF-8"?>
    <书架>
        <>
            <书名>JavaWeb程序开发入门</书名>
            <作者>传智播客</作者>
            <售价>60</售价>
        </>
        <>
            <书名>JavaWeb从入门到精通</书名>
            <作者>明日科技</作者>
            <售价>80</售价>
        </>
    </书架>

    与之对应的DTD约束文档book.dtd,代码如下:

    <!ELEMENT 书架 (书+)>
    <!ELEMENT 书 (书名,作者,售价)>
    <!ELEMENT 书名 (#PCDATA)>
    <!ELEMENT 作者 (#PCDATA)>
    <!ELEMENT 售价 (#PCDATA)>

    对book.dtd文档所规定的约束详细解释如下:

    (1)在第1行中,使用<!ELEMENT…>语句定义了一个元素,其中“书架”是元素的名称,“(书+)”表示书架元素中有一个或者多个书元素,字符+用来表示它所修饰的成分必须出现一次或者多次。

    (2)在第2行中,“书”是元素名称,“(书名,作者,售价)”表示元素书包含书名、作者、售价这三个子元素,并且这些子元素要按照顺序依次出现

    (3)在第3-5行中,“书名”、“作者”和“售价”都是元素名称,“(#PCDATA)"表示元素的内容是可解析字符数据(Parsed Character Data),就是普通文本字符串。

    那么,创建DTD文件步骤:

    (1)看XML中有几个元素,在DTD中就写几个<!ELEMENT>。

    (2)判断元素是简单元素还是复杂元素:

    • 简单元素:没有子元素,语法如下: <!ELEMENT 元素名称 (#PCDATA)> 
    • 复杂元素:有子元素的元素,语法如下: <!ELEMENT 元素名称 (子元素+)>  或  <!ELEMENT 元素名称 (子元素,子元素,……)> 

    2、DTD的引入

    有了DTD文件,如果想使用DTD文件来约束XML文档,必须在XML文档中引入DTD文件。

    (1)外部引入

    在XML文档中引入外部DTD文件有两种方式,具体如下:

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

    在上述两种引入DTD文件的方式中:

    第一种方式用来引用本地的DTD文件,“外部DTD文件的URI”是指DTD文件的存放位置,它可以是相对于XML文档的相对路径,也可以是一个绝对路径;

    第二种方式用来引用网络上公共的DTD文件,“外部DTD文件的URI”是指,Internet上的一个绝对URL地址。

    如果希望引入一个公共的DTD文件,则需要在DOCTYPE声明语句中使用PUBLIC属性,具体示例如下:

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

    其中"-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"是DTD名称,它用于说明DTD符合的标准、所有者的名称以及对DTD描述的文件进行说明,虽然DTD名称看上去比较复杂,但这完全是由DTD文件发布者去考虑的事情,XML文件的编写者只要把DTD文件发布者事先定义好的DTD标识名称进行复制就可以了。

    我们看看之前学习HTML的时候,HTML文档的第一行:

    <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">

    这里也是一个公共DTD的引入。

    引入DTD的book.xml代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE 书架 SYSTEM "book.dtd">
    <书架>
        ……
    </书架>

    (2)内部嵌入

    在XML中直接嵌入DTD定义语句的完整语法格式如下所示:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <!DOCTYPE 根元素名 [
        DTD定义语句
        ……
    ]>

    上面的book.xml代码可以改写为:

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <!DOCTYPE 书架 [
        <!ELEMENT 书架 (书+)>
        <!ELEMENT 书 (书名,作者,售价)>
        <!ELEMENT 书名 (#PCDATA)>
        <!ELEMENT 作者 (#PCDATA)>
        <!ELEMENT 售价 (#PCDATA)>
    ]>
    <书架>
        ……
    </书架>

    不管是哪种方式,通过IE浏览器浏览,我们发现即使XML不符合DTD约束,浏览时也一样可以浏览出来。因为我们使用浏览器打开XML文件,浏览器只负责校验XML的语法,不负责校验约束。

    如果想要校验约束,我们需要使用工具(Eclipse)。

     

    我们打开Eclipse,然后创建一个Java工程。在src文件夹下编写book.xml和book.dtd文件。这时,如果XML文件的编写不符合DTD约束,Eclipse就会给我们错误提示。

    外部引入和内部嵌入的特点:

    ① 如果一个DTD文件需要被多个XML文件引用,为了避免在每个XML中都添加相同的一段DTD定义语句,我们可以将其放在一个单独的DTD文件中,采用外部引入的方式对XML文档进行管理。这样不仅便于管理和维护DTD定义,还可以使多个XML文档共享使用一个DTD文件。

    ② 内部嵌入比较直观,DTD约束和XML元素使用都在同一个XML文件中,编写代码、编辑DTD约束比较方便。

    3、DTD语法

    DTD的结构一般由元素类型定义、属性定义、实体定义、记号(notation)定义等构成,一个典型的DTD会把将来要创建的XML文档的元素结构、属性类型、实体引用等预先进行定义。

    (1)元素定义

    元素(标记)是XML文档的基本组成部分,在DTD定义中,每一条<!ELEMENT…>语句用于定义一个元素,其基本的语法格式如下所示:

    <!ELEMENT 元素名称 元素内容>

    在上面的语法格式中,包含了“元素名称”和“元素内容”。

    • 元素名称:是自定义的名称,它用于定义被约束XML文档中的元素(标记、标签);
    • 元素内容:是对元素包含内容的声明,包括数据类型和符号两部分。XML的元素分为简单元素和复杂元素两种,DTD中元素的定义共有5种形式,其中前三种是简单元素的类型:

    ① (#PCDATA):普通字符串,PCDATA是可解析字符数据(Parsed Character Data),要有括号()。

    ② EMPTY:空元素,既不包含字符数据,也不包含子元素。如果在文档中元素本身已经表明了明确的含义,就可以在DTD中用关键字EMPTY表明空元素。例如, <!ELEMENT br EMPTY> ,其中br是一个没有内容的空元素。不用括号()。

    ③ ANY:任何元素,表示该元素可以包含任何的字符数据和子元素。例如, <!ELEMENT 联系人 ANY> 表示联系人可以包含任何形式的内容。但在实际开发中,应该尽量避免使用ANY,因为除了根元素外,其他使用ANY的元素都将失去DTD对XML文档的约束效果。不用括号()。

    ④ 子元素:可以包含其他元素。通常用一对括号()将元素中要嵌套的一组子元素括起来,中间使用逗号“,”分隔,表示这些子元素按照这个顺序在XML中出现。例如, <!ELEMENT 书 (书名,作者,售价)> 表示元素书中要嵌套书名、作者、售价子元素,这些子元素只能出现一次,并且按照这个顺序编写。

    如果一个子元素要出现多次,我们可以使用一些符号来表示次数:

    +(一次或者多次),?(零次或者一次)、*(零次、一次或者多次)

    例如, <!ELEMENT 书 (书名+,作者?,售价*)> 

    还有一个符号非常重要----竖线“|”,表示“或”的意思,如果几个子元素之间使用竖线“|”隔开,表示这几个子元素只能出现其中的任意一个。例如,<!ELEMENT 书 (书名|作者|售价)>。

    ⑤ 混合内容:既可以包含字符数据,也可以包含子元素。混合内容必须被定义零个或多个,例如, <!ELEMENT 书 (#PCDATA|书名)*> 表示书中嵌套的子元素书名包含零个或多个,并且书名是字符串文本格式。要有括号()。

    (2)属性定义

    在定义元素的同时,还可以为元素定义属性。DTD属性定义的基本语法格式:

    <!ATTLIST 元素名称
    属性名称1 属性类型 设置说明
    属性名称2 属性类型 设置说明
    ……
    > 

    在上面属性定义的语法格式中,“元素名称”是属性所属元素的名字,“属性名称”是属性的名称,“属性类型”则是用来指定该属性是属于哪种类型,“设置说明”用来说明该属性是否必须出现。关于“属性类型”和“设置说明”的相关讲解,具体如下。

    ① 属性类型

    在DTD中定义元素的属性时,有10种属性类型可以选择,常见的几种属性类型介绍如下。

    序号

    属性类型

    含义

    1

    CDATA

    纯文本字符串。如果出现特殊字符,需要转义。

    2

    枚举类型

    枚举列表中的一个值,用竖线“|”隔开,每次只能选择一个。

    3

    ID

    唯一的id,只能是字母或下划线开始。

    4

    IDREF

    另外一个元素的id,【reference:引用,参考】

    5

    IDREFS

    其他id的列表,中间用空格隔开

    6

    NMTOKEN

    合法的XML名称,Name Token,名称记号,它表示由一个或多个字母、数字、句点、连字号或下划线所组成的一个名称。当encoding编码是中文码时,可以使用中文。

    7

    NMTOKENS

    合法的XML名称的列表,中间用空格隔开

    8

    NOTATION

    记号的名称(后面还有单独讲解)

    9

    ENTITY

    一个已定义的实体,预定义实体/自定义实体(后面还有单独讲解)

    10

    ENTITIES

    一个已定义的实体的列表

    ② 设置说明

    定义元素的属性时,有4种设置说明可以选择,具体如下:

    序号

    设置说明

    含义

    1

    #REQUIRED

    属性必须存在

    2

    #IMPLIED

    属性可有可无

    3

    #FIXED value

    表示一个固定值,#FIXED "ABC",表示属性必须是这个固定值"ABC"

    4

    默认值

    表示一个默认值,如果元素不写该属性,该属性自动被设置为默认值。如果写了该属性,就是用属性的实际值。

    例如:

    ① DTD定义: <!ATTLIST 作者 分类 (AA|BB|CC) #REQUIRED> 

    XML文件: <作者 分类="AA">传智播客</作者> 

    ② DTD定义: <!ATTLIST 书名 编号 ID #REQUIRED> 

    XML文件: <书名 编号="a1">JavaWeb程序开发入门</书名> 

    ③ DTD定义: <!ATTLIST 售价 单位 CDATA #FIXED "元"> 

    XML文件: <售价 单位="元">60</售价> 

    ④ CDATA 案例----“家庭”

    <?xml version="1.0" encoding="UTF-8"?>
    <!--包含两个元素,人至少出现1次,家电可以出现0/1/多次,这两个元素都被定义为空类型 -->
    <!DOCTYPE 家庭 [
        <!ELEMENT 家庭 (人+,家电*)>
        <!ELEMENT 人 EMPTY>
        <!ELEMENT 家电 EMPTY>
        <!--开始定义属性-->
        <!ATTLIST 人
            名字 CDATA #REQUIRED 
            年龄 CDATA #REQUIRED
            爱好 CDATA #IMPLIED>
        <!ATTLIST 家电
            名称 CDATA #REQUIRED 
            数量 CDATA #REQUIRED
            说明 CDATA #IMPLIED>
    ]>
    <!--DTD部分结束 -->
    <家庭>
        <人 名字="张三" 年龄="25" />
        <人 名字="李四" 年龄="38" 爱好="踢足球" />
        <家电 名称="彩电" 数量="三" />
    </家庭>

    ⑤ ID案例----“公司”

    <?xml version="1.0" encoding="UTF-8"?>
    <!--一个内部DTD的示例,首先写根元素“公司” -->
    <!DOCTYPE 公司 [
        <!ELEMENT 公司 ANY>
        <!ELEMENT 公司职员 (#PCDATA)>
        <!ATTLIST 公司职员
            编号 ID #REQUIRED
            姓名 CDATA #REQUIRED
        >
    ]>
    <!--DTD部分结束 -->
    <!--编号被定义为ID,因此是不可重复的 -->
    <公司>
        <公司职员 姓名="张三" 编号="Z001" />
        <公司职员 姓名="李四" 编号="Z002" />
    </公司>

    ⑥ IDREF/IDREFS案例----“家庭”

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE 家庭[
        <!ELEMENT 家庭 (人+)>
        <!ELEMENT 人 EMPTY>
        <!ATTLIST 人
            relID ID #REQUIRED
            parentID IDREFS #IMPLIED
            name CDATA #REQUIRED>
    ]>
    <!--DTD部分结束 -->
    <家庭>
        <人 relID="P_1" name="爸爸" />
        <人 relID="P_2" name="妈妈" />
        <!-- 属性值引用已经定义的ID值,方法是把那个元素的ID标识符作为该元素的取值,不同的引用之间用空格分开 -->
        <人 relID="P_3" parentID="P_1 P_2" name="儿子" />
    </家庭>

    ⑦ NMTOKEN案例----“八阵图”

    <?xml version="1.0" encoding="UTF-8"?>
    <!DOCTYPE poems [
        <!ELEMENT poems (title, content)>
        <!ELEMENT title (#PCDATA)>
        <!--定义属性,NMTOKEN说明该属性由一个或多个字母、数字、句点、连字号或下划线所组成的一个名称,当encoding编码是中文码时,可以使用中文-->
        <!ATTLIST title    author NMTOKEN #REQUIRED>
        <!ELEMENT content (#PCDATA)>
    ]> 
    <poems>
        <title author="杜甫">八阵图</title>
        <content>
              功盖三分国,名成八阵图,
              江流石不转,遗恨失吞吴.
        </content>
    </poems>

    注意,如果是NMTOKENS,属性值能由多个NMTOKEN构成,每个NMTOKEN之间用空格隔开。

    案例二:电视节目表 DTD

    <!DOCTYPE TVSCHEDULE [
        <!ELEMENT TVSCHEDULE (CHANNEL+)>
        <!ELEMENT CHANNEL (BANNER,DAY+)>
        <!ELEMENT BANNER (#PCDATA)>
        <!ELEMENT DAY (DATE,(HOLIDAY|PROGRAMSLOT+)+)>
        <!ELEMENT HOLIDAY (#PCDATA)>
        <!ELEMENT DATE (#PCDATA)>
        <!ELEMENT PROGRAMSLOT (TIME,TITLE,DESCRIPTION?)>
        <!ELEMENT TIME (#PCDATA)>
        <!ELEMENT TITLE (#PCDATA)> 
        <!ELEMENT DESCRIPTION (#PCDATA)>
        
        <!ATTLIST TVSCHEDULE NAME CDATA #REQUIRED>
        <!ATTLIST CHANNEL CHAN CDATA #REQUIRED>
        <!ATTLIST PROGRAMSLOT VTR CDATA #IMPLIED>
        <!ATTLIST TITLE RATING CDATA #IMPLIED>
        <!ATTLIST TITLE LANGUAGE CDATA #IMPLIED>
    ]>

    根据上面提供的DTD文档定义格式,写出XML文件内容。

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <!DOCTYPE TVSCHEDULE [
    ……
    ]>
    <TVSCHEDULE NAME="CCTV">
        <CHANNEL CHAN="CCTV-1">
            <BANNER>XXXX</BANNER>
            <DAY>
                <DATE>2019-03-11</DATE>
                <HOLIDAY>XXXX</HOLIDAY>
            </DAY>
            <DAY>
                <DATE>2019-03-12</DATE>
                <PROGRAMSLOT VTR="XXXX">
                    <TIME>1900</TIME>
                    <TITLE LANGUAGE="TTTT">XXXX</TITLE>
                    <DESCRIPTION>XXXX</DESCRIPTION>
                </PROGRAMSLOT>
            </DAY>
        </CHANNEL>
    </TVSCHEDULE>

    (3)实体定义

    有时候需要在各个文档中调用同样的内容,例如公司名称、版权声明等,为了避免重复输入这些内容。可以通过<!ENTITY……>语句定义一个表示这些内容的实体,然后在各个文档中引用实体名代替它所表示的内容。类似于定义了一个常量,在其他地方多次使用这个常量。

    实体可分为两种类型,分别是引用实体参数实体

    ① 引用实体

    引用实体的定义格式有两种:

    <!ENTITY 实体名称 "实体内容">
    <!ENTITY 实体名称 SYSTEM "外部XML文档的URL">

    使用引用实体的方式为:

    &实体名称;

    写法非常类似于转义字符的使用:空格  &nbsp;

    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <!DOCTYPE 书架 [
        <!ELEMENT 书架 (书+)>
        <!ELEMENT 书 (书名,作者,售价)>
        <!ELEMENT 书名 (#PCDATA)>
        <!ELEMENT 作者 (#PCDATA)>
        <!ELEMENT 售价 (#PCDATA)>
        <!ENTITY zhs "张三">
    ]>
    <书架>
        <>
            <书名>JavaWeb程序开发入门</书名>
            <作者>&zhs;</作者>
            <售价>60</售价>
        </>
        <>
            <书名>JavaWeb从入门到精通</书名>
            <作者>明日科技</作者>
            <售价>80</售价>
        </>
    </书架>

     

    ② 参数实体

    参数实体只能被DTD文件自身使用,语法格式:

    <!ENTITY % 实体名称 "实体内容">

    注意:ENTITY、%、实体名称、"实体内容"之间各有一个空格。

    引用参数实体的方式为:

    %实体名称;

    在实体名称之前增加百分号,在其后增加分号。百分号与实体名称之间没有空格。

    来看一下下面的DTD定义:

    <!ENTITY % na "书名,作者">
    <!ELEMENT 书架 (书+)>
    <!ELEMENT 书 (%na;,售价)>
    <!ELEMENT 书名 (#PCDATA)>
    <!ELEMENT 作者 (#PCDATA)>
    <!ELEMENT 售价 (#PCDATA)>

    在第三行中引用了第一行中定义的参数实体na来表示"书名,作者"。

    注意:内部 DTD 子集中的标记声明内不允许使用参数实体引用,只能在外部DTD文件中使用参数实体。

    参数实体不仅可以简化元素中定义的相同内容,还可以简化属性的定义,具体实例参见课本27页。

    (4)NOTATION记号定义(或符号定义)

    在现实中,很多数据是无法用XML表示的,例如:声音、图像、影像、程序等,对于这些数据,XML处理器通常都不支持。

    我们就需要使用记号声明,为非XML数据描述一种可能的格式,或者指定一个外部的处理程序。

    我们使用<!NOTATION…>语句定义,有两种语法格式,分别定义普通记号和公用记号:

    记号类型

    定义语法

    普通记号

    <!NOTATION 符号名 SYSTEM "记号值">

    公用记号

    <!NOTATION 符号名 PUBLIC "公用符号标识名" "记号值">

    记号值通常有两种形式:

    ① MIME:通用MIME类型的文件总是由相应的程序负责处理。

    <!NOTATION gif SYSTEM "image/gif">

    ② 外部程序所在路径:直接指定某个外部程序负责处理XML文档中的外部数据。

    <!NOTATION gif SYSTEM "iexplore.exe">

    五、Schema约束

    同DTD一样,XML Schema(XML Schema Definition,XSD,XML Schema定义)也是一种用于定义和描述XML文档结构与内容的模式语言,它的出现克服了DTD 的局限性。接下来,通过XML Schema与DTD的比较,将XML Schema所具有的一些显著优点进行列举,具体如下:

    (1)DTD采用的是非XML语法格式,缺乏对文档结构、元素、数据类型等全面的描述。而XML Schema采用的是XML语法格式,而且它本身也是一种XML文档,因此,XML Schema语法格式比DTD更好理解。

    (2)XML有非常高的合法性要求,虽然DTD和XML Schema都用于对XML文档进行描述,都被用作验证XML合法性的基础。但是,DTD本身合法性的验证必须采用另外一套机制,而XML Schema则采用与XML文档相同的合法性验证机制。

    (3)XML Schema对名称空间支持得非常好,而DTD几乎不支持名称空间。

    (4)DTD支持的数据类型非常有限。例如,DTD可以指定元素中必须包含字符文本(PCDATA),但无法指定元素中必须包含非负整数,而XML Schema比DTD支持更多的数据类型,包括用户自定义的数据类型。

    (5)DTD定义约束的能力非常有限,无法对XML实例文档作出更细致的语义限制,例如,无法很好地指定一个元素中的某个子元素必须出现7-12次;而XML Schema定义约束的能力非常强大,可以对XML实例文档作出细致的语义限制。

    通过上面的比较可以发现,XML Schema的功能比DTD强大很多,但相应的语法也比DTD复杂很多。Schema是基于XML编写的,XML Schema约束文件本身就是一个XML文档(文件后缀名为.xsd),文件内的代码要符合XML语法规范。

    【复习】DTD文件语法:

    <!ELEMENT 元素名称 元素内容>
    <!ATTLIST 元素名称
    属性名称1 属性类型 设置说明
    属性名称2 属性类型 设置说明
    ……
    >

    那么,我们使用Eclispe向导新建一个“XML Schema File”,扩展名是.xsd,名为NewXMLSchema.xsd,代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema" 
    targetNamespace="http://www.example.org/NewXMLSchema"
    xmlns:tns="http://www.example.org/NewXMLSchema"
    elementFormDefault="qualified">
    </schema>

    上面的代码中:

    第1行是文档声明,与xml文档声明一样。

    第2行中以<schema>为根元素,表示模式定义的开始。

    • 属性xmlns="http://www.w3.org/2001/XMLSchema"表示使用了标准的命名空间(ns,namespace),与此命名空间相关联的 URI 是 Schema 的语言定义(Schema Language Definition),其标准值是 http://www.w3.org/2001/XMLSchema。表示当前文件是一个XML Schema约束文件;
    • 属性targetNamespace="http://www.example.org/NewXMLSchema"表示的是如果要使用这个Schema约束文件,可以直接通过这个地址引入约束文件;
    • 属性xmlns:tns="http://www.example.org/NewXMLSchema"表示这个Schema约束文件他本身的名称空间;
    • 属性elementFormDefault="qualified"表示是质量良好的。

    一个XML只能引入一个DTD约束文档,但是一个XML中可以有多个Schema约束文档,多个Schema使用名称空间区分(类似于Java 的类是按照Java包名来区分的是一个道理)。

    1、名称空间

    一个XML文档可以引入多个Schema约束文档,但是,由于约束文档中的元素或属性都是自定义的,因此,在XML文档中,极有可能出现代表不同含义的同名元素或属性,导致名称发生冲突。为此,在XML文档中,提供了名称空间,它可以唯一标识一个元素或者属性。这就好比咱们系有两个同名的同学,如果老师要找那个同学,就得给他们的名字前面加个前缀,XXX班的某某某。这个“XXX班”就相当于一个名称空间。

    在使用名称空间时,首先必须声明名称空间。名称空间的声明就是在XML实例文档中为某个模式文档的名称空间指定一个临时的简写名称(起个别名),它通过一系列的保留属性来声明,这种属性的名字必须是以“xmlns”或者以“xmlns:”作为开始。它与其它任何XML属性一样,都可以通过直接或者使用默认的方式给出。

    名称空间声明的语法格式如下所示:

    <元素名称 xmlns:prefixname="URI">

    在上述语法格式中,元素名称指的是在哪一个元素上声明名称空间,在这个元素上声明的名称空间适用于声明它的元素和属性,以及该元素中嵌套的所有元素及其属性。xmlns:prefixname指的是该元素的属性名,它所对应的值是一个URI引用,用来标识该名称空间的名称。

    我们来修改book.xml文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:书架 xmlns:xs="http://www.example.org/book/schema"
    xmlns="http://www.w3.org/2001/XMLSchema-instance">
        <xs:>
            <xs:书名>JavaWeb程序开发入门</xs:书名>
            <xs:作者>传智播客</xs:作者>
            <xs:售价>60</xs:售价>
        </xs:书>
    </xs:书架>

    名称空间的使用就是将一个前缀(xs)绑定到代表某个名称空间的URI(http://www.example.org/book/schema)上。

    然后将前缀添加到元素名称前面来说明该元素属于哪个Schema文档。

    如果一个XML文档有很多元素,而且这些元素都在同一个名称空间,这时,给每个元素名称都添加一个前缀将是一件非常烦琐的事情。

    这时,可以使用默认的名称空间,默认名称空间声明时不需要加“别名”,使用这些元素时,也不用加前缀。

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:书架 xmlns:xs=http://www.example.org/book/schema>
        <xs:>
            <xs:书名>JavaWeb程序开发入门</xs:书名>
            <xs:作者>传智播客</xs:作者>
            <xs:售价>60</xs:售价>
        </xs:>
    </xs:书架>

    2、引入Schema文档

    如果想通过XML Schema文件对某个XML文档进行约束,必须将XML文档与Schema文件进行关联。在XML文档中引入Schema文件有两种方式:

    (1)使用名称空间引入Schema

    上面的书架book.xml文件对应的XML Schema约束文件book.xsd:

    <?xml version="1.0" encoding="UTF-8"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema"
        targetNamespace="http://www.example.org/book" 
        xmlns:tns="http://www.example.org/book"
        elementFormDefault="qualified">
        <element name="书架">
            <complexType>
                <sequence>
                    <element name="书">
                        <complexType>
                            <sequence>
                                <element name="书名" type="string" />
                                <element name="作者" type="string" />
                                <element name="售价" type="string" />
                            </sequence>
                        </complexType>
                    </element>
                </sequence>
            </complexType>
        </element>
    </schema>

    那么,我们需要在XML文档中的根节点中使用schemaLocation属性来指定Schema文件。schemaLocation属性有两个值:

    第一个值是需要使用的名称空间;

    第二个值是供命名空间使用的XML Schema文件的路径;

    两者之间用空格分隔

    我们来创建book.xml文件时,可以使用Eclipse的新建XML文件向导。

     

     

    修改生成的book.xml文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <书架 xmlns="http://www.example.org/book" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.example.org/book book.xsd ">
        <>
            <书名>JavaWeb程序开发入门</书名>
            <作者>传智播客</作者>
            <售价>60</售价>
        </>
    </书架>

    如果要使用名称空间引入多个XML Schema文档。修改book.xml文件:

    <?xml version="1.0" encoding="UTF-8"?>
    <书架 xmlns="http://www.example.org/book" 
        xmlns:demo="http://www.example.org/demo"
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.example.org/book book.xsd
                            http://www.example.org/demo demo.xsd ">
        <>
            <书名>JavaWeb程序开发入门</书名>
            <作者>传智播客</作者>
            <售价 demo:类型="元">60</售价>
        </>
    </书架>

    (2)不使用名称空间引入Schema

    如果book.xsd与引用它的XML文件位于同一个目录中,我们可以不使用名称空间来引入Schema,book.xsd中不需要定义targetNamespace(目标名称空间)和xmlns:tns(所在名称空间)了,book.xsd代码:

    <?xml version="1.0" encoding="UTF-8"?>
    <schema xmlns="http://www.w3.org/2001/XMLSchema" 
        elementFormDefault="qualified">
        <element name="书架">
            <complexType>
                <sequence>
                    <element name="书">
                        <complexType>
                            <sequence>
                                <element name="书名" type="string" />
                                <element name="作者" type="string" />
                                <element name="售价" type="string" />
                            </sequence>
                        </complexType>
                    </element>
                </sequence>
            </complexType>
        </element>
    </schema>

    如果这时再用Eclipse向导来创建基于book.xsd的XML文件,就是如下图所示了。

     

    修改book.xml文件,在book.xml中也不需要指定默认名称空间了。

    <?xml version="1.0" encoding="UTF-8"?>
    <书架 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="book.xsd">
        <>
            <书名>JavaWeb程序开发入门</书名>
            <作者>传智播客</作者>
            <售价>60</售价>
        </>
    </书架>

    noNamespaceSchemaLocation是一个在标准名称空间http://www.w3.org/2001/XMLSchema-instance里面定义好的属性,用于指定book.xsd文档位置。

    3、Schema语法

    (1)元素定义

    Schema和DTD一样,都可以定义XML文档中的元素。在Schema文档中,元素定义的语法格式如下所示:

    <element name="xxx" type="yyy" />

    在上面的语法格式中,element用于声明一个元素,这里使用默认名称空间,所以省去了前缀xs:,xxx指的是元素的名称,yyy指元素的数据类型。在XML Schema中有很多内建的数据类型,其中最常用的有以下几种(数据类型也是,省去了前缀xs:):

    • string:表示字符串类型
    • decimal:表示小数类型
    • integer:表示整数类型
    • boolean:表示布尔类型
    • date:表示日期类型
    • time:表示时间类型
    • positiveInteger:表示正整数。

    接下来看一个XML的示例代码:

    <lastname>Smith</lastname>
    <age>28</age>
    <birthday>1990-03-12</birthday>

    上面的XML示例代码中,定义了三个元素,这三个元素对应的Schema定义如下所示:

    <element name="lastname" type="string" />
    <element name="age" type="integer" />
    <element name="birthday" type="date" />

    (2)属性定义

    在Schema文档中,属性定义的语法格式如下所示:

    <attribute name="xxx" type="yyy" />

    在上面的语法格式中,xxx指的是属性名称,yyy指的是属性的数据类型。其中,属性的常用数据类型与元素相同,都使用的是XML Schema中内建的数据类型。

    了解了属性的定义方式,接下来,看一个XML的简单例子,具体示例如下所示:

    <lastname lang="EN">Smith</lastname>

    在上面的元素定义中,属性名称是lang,属性值的类型是字符串类型,因此,对应的Schema中的属性定义如下:

    <attribute name="lang" type="string" />

    (3)简单类型<simpleType>

    只包含字符数据的元素都是简单类型,使用<simpleType>元素来定义。

    如果想对现有元素内容的类型进行进一步限制,则需要使用<restriction>元素(restriction,限制,限定)

    ① minInclusive和maxInclusive元素对值的限定(最值约束)

    如果要定义一个员工的年龄时,年龄要求在18-58周岁之间,我们需要对年龄age这个元素进行限定,具体Schema代码如下:

    <element name="age">
        <simpleType>
            <restriction base="integer">
                <minInclusive value="18" />
                <maxInclusive value="58" />
            </restriction>
        </simpleType>
    </element>

    上面的代码表示,元素age是integer类型,最小值包括18,最大值包括58。

    正确XML: <age>20</age> 

    另外,类似的还有两个:

    minExclusive:定义数值的下限。所允许的值必须大于此值(不包括此值)。

    maxExclusive:定义数值的上限。所允许的值必须小于此值(不包括此值)。

    ② enumeration元素对于一组值的限定(枚举约束)

    如果希望XML中的某个元素的内容限制在一组值中的一个,我们可以使用枚举约束,例如,要限定一个元素名为car的元素,它可接收的值只有Benz、BMW、Audi,具体Schema代码如下:

    <element name="car">
        <simpleType>
            <restriction base="string">
                <enumeration value="Benz" />
                <enumeration value="BMW" />
                <enumeration value="Audi" />
            </restriction>
        </simpleType>
    </element>

    正确XML:<car>Benz</car>

    ③ pattern元素对于一系列值的限定(模式约束)

    常用正则表达式

    [abc]     a、b 或 c(简单类)

    [^abc]   任何字符,除了 a、b 或 c(否定)

    [a-zA-Z]  a到 z 或 A 到 Z,两头的字母包括在内(范围)

    X?   X,一次或零次

    X*   X,零次或多次

    X+   X,一次或多次

    X{n}    X,恰好 n 次

    X{n,}    X,至少 n 次

    X{n,m}   X,至少 n 次,但是不超过 m 次

    如果希望把XML中的某个元素的内容限制在一系列可使用的数字和字母中,可以使用模式约束。例如,要定义一个带有限定的元素letter,要求可接受的值只能是a-z其中的一个,具体Schema代码如下:

    <element name="letter">
        <simpleType>
            <restriction base="string">
                <pattern value="[a-z]" />
            </restriction>
        </simpleType>
    </element>

    正确XML: <letter>a</letter> 

    ④ whiteSpace元素对空白字符的限定(空格约束)

    在XML文档中,空白字符比较特殊,如果需要对空白字符进行处理,可以使用whiteSpace进行约束。whiteSpace元素有三个属性值:

    • preserve:不对元素中的任何空白字符进行处理(保持原状)
    • replace:移除所有空白字符
    • collapse:将所有空白字符缩减为一个单一字符

    例如,对于地址address元素内容中的空白字符不做任何处理,具体Schema代码如下:

    <element name="address">
        <simpleType>
            <restriction base="string">
                <whiteSpace value="preserve" />
            </restriction>
        </simpleType>
    </element>

    正确XML: <address>abc def ghi</address> 

    (4)复杂类型<complexType>

    除简单类型之外的其他类型都是复杂类型,在定义复杂类型时,需要使用<complexType>元素来定义。复杂类型的元素可以包含子元素和属性,这样的元素称为复合元素。在定义复合元素时,如果元素的开始标记和结束标记之间只包含字符数据内容,那么这样的内容是简易内容,需要使用<simpleContent>元素来定义。反之,元素的内容都是复杂内容,需要使用<complexContent>元素来定义。复合元素有4种基本类型:

    ① 空元素

    这里的空元素指的是不包含内容,只包含属性的元素,具体示例如下:

    <product prodid="1345" />

    在上面的元素定义中,没有定义元素product的内容,这时,空元素在XML Schema文档中对应的定义方式如下所示:

    <element nane="product">
        <complexType>
            <attribute name="prodid" type="positiveInteger" />
        </complexType>
    </element>

    属性类型positiveInteger表示正整数。

    ② 包含其他元素的元素

    XML文档中包含其他元素的元素,例如下面的示例代码:

    <person>
        <firstname>John</firstname>
        <lastname>Smith</lastname>
    </person>

    在上面的示例代码中,元素person 嵌套了两个元素,分别是firstname和lastname。这时,在Schema文档中对应的定义方式如下所示:

    <element name="person">
        <complexType>
            <sequence>
                <element name="firstname" type="string" />
                <element name="lastname" type="string" />
            </sequence>
        </complexType>
    </element>

    ③ 仅包含文本的元素----简易内容

    对于仅包含文本的复合元素,需要使用simpleContent元素来添加内容。在使用简易内容时,必须在simpleContent元素内定义扩展或限定,这时,需要使用extension 或restriction元素来扩展或限制元素的基本简易类型。请看-个XML的简易例子,其中,"shoesize"仅包含文本,具体示例如下:

    <shoesize country="france">35</shoesize>

    在上面的例子中元素shoesize 包含属性以及元素内容,针对这种仅包含文本的元素,需要使用<extension>来对元素的类型进行扩展,在Schema文档中对应的定义方式如下所示:

    <element name="shoesize">
        <complexType>
            <simpleContent>
                <extension base="integer">
                    <attribute name="country" type="string" />
                </extension>
            </simpleContent>
        </complexType>
    </element>

    ④ 包含元素和文本的元素

    在XML文档中,某些元素经常需要包含文本以及其他元素,例如,下面的这段XML文档:

    <letter>
        Dear Mr.<name>John smith</name>.
        Your order<orderid>1032</orderid>
        will be shipped on<shipdate>2001-07-13</shipdate>
    </letter>

    上面的这段XML文档,在Schema文档中对应的定义方式如下所示:

    <element name="letter">
        <complexType mixed="true">
            <sequence>
                <element name="name" type="string" />
                <element name="orderid" type="positiveInteger" />
                <element name="shipdate" type="date" />
            </sequence>
        </complexType>
    </element>

    需要注意的是,为了使字符数据可以出现在letter元素的子元素之间,使用了mixed属性,该属性是用来规定是否允许字符数据出现在复杂类型的子元素之间,默认情况下mixed的值是false。

    最后,整个person.xsd代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema"
        xmlns="http://www.example.org/person/schema"
        targetNamespace="http://www.example.org/person/schema" 
        elementFormDefault="qualified">
        <xs:element name="person">
            <xs:complexType>
                <xs:sequence>
                    <xs:element name="firstname" type="xs:string" />
                    <xs:element name="lastname" type="xs:string" />
                    <xs:element name="age">
                        <xs:simpleType>
                            <xs:restriction base="xs:integer">
                                <xs:minInclusive value="18" />
                                <xs:maxInclusive value="58" />
                            </xs:restriction>
                        </xs:simpleType>
                    </xs:element>
                    <xs:element name="birthday" type="xs:date" />
                </xs:sequence>
            </xs:complexType>
        </xs:element>
    </xs:schema>

    整个person.xml代码如下:

    <?xml version="1.0" encoding="UTF-8"?>
    <person xmlns="http://www.example.org/person/schema" 
        xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:schemaLocation="http://www.example.org/person/schema person.xsd">
        <firstname>John</firstname>
        <lastname>Smith</lastname>
        <age>18</age>
        <birthday>1990-03-12</birthday>
    </person>

    【DTD约束形式】

    <!ELEMENT person (firstname, lastname, age, birthday)>
    <!ELEMENT firstname (#PCDATA)>
    <!ELEMENT lastname (#PCDATA)>
    <!ELEMENT age (#PCDATA)>
    <!ELEMENT birthday (#PCDATA)>
  • 相关阅读:
    mysql--------常用命令
    PHP--------微商城实现微信授权登录
    mysql--------命令来操作表
    PHP--------解决网址URL编码问题
    php-----utf8和gbk相互转换
    javascript遍历json对象数据的方法
    PHP-----------HTTP请求的第三方接口
    PHP------数组和对象相互转化,stdClass Object转array
    include与require的区别
    PHP中exit()与die()的区别
  • 原文地址:https://www.cnblogs.com/lihuawei/p/16637002.html
Copyright © 2020-2023  润新知