4.3. SGML/XML语法基础

4.3.1. 标记
4.3.2. 实体引用
4.3.3. 注释
4.3.4. 处理指令
4.3.5. 文件类型声明
4.3.6. CDATA片段

SGML/XML文件由字符数据和标记组成,下面就是SGML/XML所支持的几种不同的标记:

4.3.1. 标记

标记(Tag)用来描述元素,是语法中最显而易见的组成部分。例如:在DocBook中段落元素由标记<para>和标记</para>构成。

元素(Elements),这一术语,和标记的概念密不可分。它指的是SGML/XML文档中的具有一定结构的文字片断,大多数元素的开头和结尾分别由一对相匹配的起始标签和结束标签构成,也有一些元素可以是空标签,没有结束标签和它相匹配,就像HTML中的断行标签“<br>”。

SGML和XML对于标记的规范略有不同。

  • SGML是大小写不敏感的,XML大小写敏感

    对于SGML,标签<para>和<PAra>是同一个标签,而对于XML则是不同的标签。DocBook中的标签都应该是小写的,因此我们无论在XML还是在SGML中,都应该养成用小写字母书写元素标签的习惯。

  • SGML允许存在不匹配的标签,而XML必须严格匹配

    根本原因是,XML省略了SGML中定义DTD的语法中的一些细节,这在后面讲述DTD时,将要谈到。SGML允许出现不匹配的标签,如: <anchor id="...">用来描述文挡中的内部跳转,可以单独存在。而这样的语法在XML中,是不允许的,即使对于<anchor>这样的空标签,也必须用独特的空标签表示方法表示。如:文内的跳转标志,XML中必须以 <anchor id="..."/>(在大于号的前面加上一个斜杠)表示。

4.3.2. 实体引用

实体(Entities),就是一个被命名了的标记数据块,可以是一个字符串,也可以是一个完整的文件。实体可以包含已析(parsed)数据或未析(unparsed)数据。已析数据由字符组成,其中一些字符组成字符数据,另一些字符组成标记。未析数据则是那些不进行语法解析的数据,如图形文件等。

引用一个已经定义的实体的格式为:&实体名称;,即在实体名称前面加上“&”符号,在实体名称后面加上分号“;”。如HTML中的“&lt;” 即代表小于号“<”。

4.3.3. 注释

注释为文件和数据提供说明,并且被处理程序所忽略。SGML/XML的注释格式和HTML一样,都是以 <!-- 开始,以 --> 结束。对注释的唯一限制就是注释不能嵌套。示例如下:


<!-- 这是一端注释... -->

4.3.4. 处理指令

处理指令是向SGML/XML处理程序传递的特殊指令。例如:xml处理指令,必须作为XML文件的第一行存在。


<?xml version="1.0" ?>

这条命令对于XML这一发展中的标记语言的向下兼容有着非常重要的作用。当前的XML版本为1.0,但为避免给XML的发展设置历史的障碍,用这条处理指令向XML处理的应用程序提供了带兼容性信息的处理指令。

4.3.5. 文件类型声明

文件类型声明位于SGML/XML文件头部,主要有如下作用:

  • 指定文件的根元素。

  • 指出文件的外部DTD。

  • 内部DTD,为文件定义元素、属性和实体等。

如下的例子即是本书的文件类型声明:


<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.2b1//EN"  [
<!ENTITY author "<ulink url='mailto:johnson@worldhello.net'>Johnson</ulink>">
<!ENTITY orgname "<ulink url='http://www.worldhello.net'>worldhello.net</ulink>">
<!ENTITY chap1  system "chap1.sgml">
<!ENTITY chap2  system "chap2.sgml">
<!ENTITY chap3  system "chap3.sgml">
<!ENTITY chap4  system "chap4.sgml">
<!ENTITY chap5  system "chap5.sgml">
<!ENTITY chap6  system "chap6.sgml">
<!ENTITY chap7  system "chap7.sgml">
<!ENTITY chap8  system "chap8.sgml">
<!ENTITY chap9  system "chap9.sgml">
<!ENTITY chap10 system "chap10.sgml">
<!ENTITY appendix system "appendix.sgml">
]>

该文件类型声明指定了文件的根元素是 article 元素,文件的外部DTD是 PUBLIC "-//OASIS//DTD DocBook V4.2b1//EN" 。而且通过内部DTD,定义了诸如作者姓名、各个章节的外部实体等。

4.3.6. CDATA片段

CDATA片段,即是未解析字符数据片段。扩在CDATA片段中的内容,将不被XML解析器处理,而直接提供给应用程序。

如果不用CDATA片段,想在文中显示上例中的文件类型声名,需要用如下方法表示,非常的不直观。


<screen>
&lt;!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.2b1//EN"  [
&lt;!ENTITY author "&lt;ulink url='mailto:johnson@worldhello.net'&gt;Johnson&lt;/ulink&gt;"&gt;
&lt;!ENTITY orgname "&lt;ulink url='http://www.worldhello.net'&gt;worldhello.net&lt;/ulink&gt;"&gt;
&lt;!ENTITY chap1  system "chap1.sgml"&gt;
&lt;!ENTITY chap2  system "chap2.sgml"&gt;
&lt;!ENTITY chap3  system "chap3.sgml"&gt;
&lt;!ENTITY chap4  system "chap4.sgml"&gt;
&lt;!ENTITY chap5  system "chap5.sgml"&gt;
&lt;!ENTITY chap6  system "chap6.sgml"&gt;
&lt;!ENTITY chap7  system "chap7.sgml"&gt;
&lt;!ENTITY chap8  system "chap8.sgml"&gt;
&lt;!ENTITY chap9  system "chap9.sgml"&gt;
&lt;!ENTITY chap10 system "chap10.sgml"&gt;
&lt;!ENTITY appendix system "appendix.sgml"&gt;
]&gt;
</screen>

但是采用CDATA段,就非常的简单而直观。


<screen>
<![CDATA[
<!DOCTYPE article PUBLIC "-//OASIS//DTD DocBook V4.2b1//EN"  [
<!ENTITY author "<ulink url='mailto:johnson@worldhello.net'>Johnson</ulink>">
<!ENTITY orgname "<ulink url='http://www.worldhello.net'>worldhello.net</ulink>">
<!ENTITY chap1  system "chap1.sgml">
<!ENTITY chap2  system "chap2.sgml">
<!ENTITY chap3  system "chap3.sgml">
<!ENTITY chap4  system "chap4.sgml">
<!ENTITY chap5  system "chap5.sgml">
<!ENTITY chap6  system "chap6.sgml">
<!ENTITY chap7  system "chap7.sgml">
<!ENTITY chap8  system "chap8.sgml">
<!ENTITY chap9  system "chap9.sgml">
<!ENTITY chap10 system "chap10.sgml">
<!ENTITY appendix system "appendix.sgml">
]>

]]>
</screen>