科技行者

行者学院 转型私董会 科技行者专题报道 网红大战科技行者

知识库

知识库 安全导航

至顶网软件频道应用软件XML定义及使用实体

XML定义及使用实体

  • 扫一扫
    分享文章到微信

  • 扫一扫
    关注官方公众号
    至顶头条

XML 的实体机制是一种节省大量时间的工具,而且也是将多种不同型态的数据并入XML 文件中的方法。

作者: 来源:中国软件网 2008年6月23日

关键字: 实体 定义 XML 软件

  • 评论
  • 分享微博
  • 分享邮件
 XML 的实体机制是一种节省大量时间的工具,而且也是将多种不同型态的数据并入XML 文件中的方法。在XML 文件中,你可以将经常使用的XML 文字区段定义成实体,可以快速地将XML文字加入到你需要的任何地方,也可以将外部的档案定义成实体,然后将档案的数据附加到文件;这些数据可以由XML 本文或其它的文字或非文字数据所组成。
    你可以使用类似用来在有效的XML 文件中宣告元素或属性的语法,在文件型态定义(DTD)中进行实体的定义。第五章已经讨论过DTD 与文件的型态宣告。
    在本章中,首先你将学到一些使用实体的基本技巧,以及为实体进行分类的方法。接着你将学到如何宣告每一种不同的实体型态,以及如何将实体加到文件中需要的地方。再来你将学习如何使用两种可以让你将任何型态字符加入到各种本文中的XML 特性:字符参照与预先定义实体。最后本章将以实作的练习作为结束,让你对于在有效的XML 文件中运用实体能够有更多的实际经验。

实体的定义与分类

    XML 的规格书中将「实体」这个词汇做了广泛的应用,一般的意思是指与XML 文件相关联的任何下列型式的储存单元。
    有效的XML 文件本身
    外部的DTD 子集(已于第五章的 <使用外部DTD 子集> 中做过讨论)
    定义成DTD 中外部实体的外部档案,以及实体参照的运用
    在DTD 中定义内部实体的引号包围字符串,以及实体参照的运用
    笔者将扼要地定义最后两项。注意列表中的前三类储存单元都是档案,而最后一项则是引号包围的字符串。
    然而,本章将实体用在较狭义的领域:参考最后两项的储存单元-那就是,在文件中的DTD 中定义成外部档案或引号包围字符串,并在文件中以实体参照的方式运作。例如,下面的DTD 将外部档案Topics.xml(一个拥有包含在文件中全部文章所涵盖的标题列表的档案)定义成名为topics 的外部实体,并且将引号包围字符串(「A Short History of XML」)定义成名为title 的内部实体:
<!DOCTYPE ARTICLE
[
<!ELEMENT ARTICLE (TITLEPAGE,INTRODUCTION,SECTION*)>
<!ELEMENT TITLEPAGE (#PCDATA)>
<!ELEMENT INTRODUCTION (#PCDATA)>
<!ELEMENT SECTION (#PCDATA)>
<!ENTITY topics SYSTEM "Topics.xml">
<!ENTITY title "A Short History of XML">
]
>
    你可以借着简单地含括实体参照&topics,来将标题的完整列表放在文章中你需要的任何地方(例如,在摘要、序文或结论)。如下列的元素所示:
<INTRODUCTION>
This article will cover the following topics:
&topics;
</INTRODUCTION>
    接下来你就可以含括实体参照&title 来将文章放在需要的地方;如元素所示:
<TITLEPAGE>
Title:&title;
Author:Michael Young
</TITLEPAGE>
    实体的机制对于储存常用的XML 文字区段特别有用。例如,如果文章标题遍布在文章里多个位置,使用实体(如之前范例中所示)能减少输入,帮助确保一致性,并且让修改标题变得更容易。你也可以借着简单地在DTD 中编辑实体宣告来修改整个标题,大概如下所示:
<!ENTITY title "A Long History of XML"><!--modified entity
declaration -->
    如果你恰巧是个程序设计人员,你将发现XML 实体机制与程序语言中定义的常数之间的相似性(如C 里面那些使用#define 处理器指令进行宣告的常数或函式)。如同你稍后将见到的,实体机制也是将非XML 的数据含括到XML 文件中不可或缺的要项,例如影像的图形数据。

实体的型态

    实体在刚开始可能会让人有点迷惑,因为它们是以这么多种不同的方式出现。虽然在这个章节中出现的范例都有点抽象(在你见到细节部分与范例之前),但是了解这些讯息应该会让你在实体上的学习变得更容易。
    实体利用下面三种方式进行分类:
    一般的vs.参数的 。一般实体(general entity)包含了文件的内容。意即,可以用在文件元素内的XML 文字、其它的文字,或非文字数据。前面章节中所介绍的实体范例(title 与topics)都是一般实体。参数实体(parameter entity)则包含了可以被安插在DTD 中的XML 文字。在XML 的规格书中,无条件限制的实体这个词汇是指一般实体。
    内部的vs.外部的 。内部实体(internal entity)是一个包含在引号包围字符串内的实体(如前面章节中的title 实体)。外部实体(external entity)则是包含在个别档案中的实体(如前面章节中的topic 实体)。
    已解析的vs.未解析的 。已解析的实体(parsed entity)是由XML 文字(字符数据、卷标或两者皆有)所组成的实体。当你把对已解析实体的参照放入文件时,该参照会被换成实体的内容数据(也称为置换本文(replacement text)),变成文件内容的一部份。XML 解析器会以扫描文字的方式对实体的内容进行处理。前面章节中所介绍的两个实体范例(title 与topics)都是已解析的实体。
    而未解析的实体则是包含了各种型态的数据:XML 资料,或占了大多数的非XML资料。非XML 数据可以是文字数据(如标题),或非文字数据(如影像的图形数据)。因为未解析实体通常不包括XML,所以它的内容并不是透过实体参照的方式直接放入文件中。然而,你可以将实体的名称指定成ENTITY 或ENTITIES 型态属性,如此应用程序便可以使用实体的名称与叙述,并对数据进行任意的处理。
    因为实体可以利用这三种方式来进行分类,而且每种方法都有两个类别,所以理论上实体可以分成八种,如下图所示:

    然而,XML 并未提供图形外的三种实体型态,所以XML 只有五种实体类型,你将在本章中学得如何定义及使用这些属性型态:
    一般内部已解析实体
    一般外部已解析实体
    一般内部未解析实体
    参数内部已解析实体
    参数外部已解析实体

宣告一般实体

    你可以借着在文件的DTD 中宣告实体来建立实体。借着使用一种类似用来宣告元素与实体的卷标类型来为实体进行宣告。在接下来的章节中,你将学习如何宣告各种一般实体。

宣告一般内部已解析实体

    对一个一般内部已解析实体的宣告可以利用下列的格式:
<!ENTITY EntityName EntityValue>
    这里的EntityName 是实体的名称。你可以选择遵循下列这些规则而来的任何名称:
    名称必须以字母或底线(_)开始,后面接着零或多个字母、数字、句号(.)、连字号(-),或底线(_)。
    实体可以拥有与位在文件中的参数实体相同的名称(一般实体与参数实体使用不同的命名空间(namespaces))。实体也可以拥有与元素或属性相同的名称。
    记住,字母的大小写在所有的卷标,包括实体名称中的所有文字中,是不同的。因此,一个名为Bowser 的实体与名为bowser 的实体是不同的。
    实体值(EntityValue)就是实体的数值。你指定给一般内部实体的数值是一连串包含在引号内的连续字符,称之为引号包围字符串或literal。你可以为一般内部实体指定任何的值,只要遵循下列的规则即可:
    字符串可以包含在单引号('')或双引号(")内。
    字符串中不能包含用来包围字符串的引号字符。
    字符串中不能包含(&)字符,除了用来作字符引号或实体参照的起始。同样地,字符串中也不能包含百分比字符(%)。(有关例外的状况,请参阅 http://www.w3.org/TR/REC-xml 的XML 规格书中的第四部分。)
    当然,字符串的内容对于你想放置实体的位置必须是正确的。例如,如果你想将实体放置在元素之中,它必须包含一个或多个可以被合法地放置在元素(套迭元素、字符数据,以及其它在第三章 <元素内容的类型> 所介绍的数据等等)中的项目。或者,如果你在属性值内插入一个实体,它必须包含合法属性规格的字符(如同第三章 <合法属性值的规则> 中所介绍的)。本章稍后将介绍你可以放置
一般内部已解析实体的位置。
    例如,下面的DTD 定义了一个名为title 的一般内部已解析实体:
<!DOCTYPE ARTICLE
[
<!ELEMENT ARTICLE (TITLEPAGE,INTRODUCTION,SECTION*)>
<!ELEMENT TITLEPAGE (#PCDATA|SUBTITLE)*>
<!ELEMENT SUBTITLE (#PCDATA)>
<!ELEMENT INTRODUCTION (#PCDATA)>
<!ELEMENT SECTION (#PCDATA)>
<!ENTITY title
"The Story of XML
<SUBTITLE>The Future Language of the
Internet</SUBTITLE>">
]
>
    title 实体包含了字符数据加上一个元素(SUBTITLE)。根据位于DTD 中的宣告部分,该内容只能正确地放置在TITLEPAGE 元素中,如下所示:
<TITLEPAGE>
Title:&title;
Author:Michael Young
</TITLEPAGE>
    XML 解析器将把实体参照(&title;)的部分替换成实体的内容,并且将这些内容如同你将文字输入到文件中相同位置的方式来进行处理,就像这样:
<TITLEPAGE>
Title:The Story of XML
<SUBTITLE>The Future Language of the Internet</SUBTITLE>
Author:Michael Young
</TITLEPAGE>

宣告一般外部已解析实体

    一般外部已解析实体的宣告拥有下列的格式:
<!ENTITY EntityName SYSTEM SystemLiteral>
    这里的EntityName 是属性的名称。只要你遵守一般外部已解析实体的命名规则,你可以选择任何的名称。
    SystemLiteral 则是负责描述包含实体数据文件其地址的系统literal。这些系统literal 可以使用单引号('')或双引号(")来包围,并且可以包含任何的字符,除了被用来作包围字符的引号字符以外。
    系统literal 指定了包含实体数据文件的统一资源识别代号(URI)。目前,URI 在本质上与标准的网络地址相同,一般称为统一资源寻址器,或URL。你可以使用完全符合规定的URL,如:
<!ENTITY abstract SYSTEM "http://bogus.com/documents/Abstract.xml">
    或者你可以使用部分的URI,该URI 指定了相对于包含该URI 的XML 文件位置的相对位置,例如:
<!ENTITY abstract SYSTEM "Abstract.xml">
    在XML 文件中相对的URI 都是利用与位在HTML 网页中相对URL 运作的相同方式来运作。想获得更多URI 的相关信息,请参阅第五章 <使用外部的DTD 子集> 中的介绍。
    外部实体的档案可以只包含那些能够合法地被安插在元素(如第三章的 <元素内容的类型> 中所介绍的字符数据、套迭元素等等)之中的项目。如同你在本章稍后将学到的,最终你只能将一般内部已解析实体放置在元素的内容之中。(你可以将实体含括在内部实体宣告的数值内,但是你接着必须将该内容安插到元素内。)例如,下面的DTD 将外部档案Topics.xml 定义成一般外部已解析实体:
<!DOCTYPE ARTICLE
[
<!ELEMENT ARTICLE (TITLEPAGE,INTRODUCTION,SECTION*)>
<!ELEMENT TITLEPAGE (#PCDATA)>
<!ELEMENT INTRODUCTION ANY>
<!ELEMENT SECTION (#PCDATA)>
<!ENTITY topics SYSTEM "Topics.xml">
]
>
    下面是Topics.xml 档案的内容:
<HEADING>Topics</HEADING>
The Need for XML
The Official Goals of XML
Standard XML Applications
Real-World Uses for XML
    这个特殊的外部实体档案包含了两个你可以含括在XML 元素中的项目:套迭元素与字符数据区块。实体的内容可以正确地被安插在INTRODUCTION 元素中(该元素可以拥有任何型态的内容),如这个范例所示:
<INTRODUCTION>
Here ''s what this article covers:
&topics;
</INTRODUCTION>

宣告一般外部未解析实体

    一般外部未解析实体的宣告是以下面的格式进行:
<!ENTITY EntityName SYSTEM SystemLiteral NDATA NotationName>
    这里的EntityName 是实体的名称。只要遵守本章前面 <宣告一般内部已解析实体> 中所介绍一般实体的命名规则,你可以选择任何名称来当作实体名称。
    SystemLiteral 则是系统literal,用来描述包含了实体数据的档案所在位置。它运作的方式和之前介绍的系统literal 一样,都是用来描述一般外部已解析实体的位置。
注意
    关键词NDATA 代表的是包含解析过数据的实体档案。
    NotationName 是在DTD 中宣告的标签名称。该卷标描述了包含在实体档案中数据的格式,或指定了负责处理该数据的程序所在位置。下一个章节将会讨论标签的宣告。
    未解析外部实体档案包含了任何格式的文字或非文字数据。当然,它应该符合由指定规格所提供的格式叙述。
    例如,下面XML 文件中的DTD 将档案Faun.gif(包含书本封面的影像)定义成一般外部未解析实体,名为faun。该实体卷标名称为GIF,被定义成指向负责以GIF 格式显示图像的程序(ShowGif.exe)的所在位置。DTD 同时也定义了名为COVERIMAGE 的实体元素,以及名为Source 的元素型态属性ENTITY:
<?xml version="1.0"?>
<!DOCTYPE BOOK
[
<!ELEMENT BOOK (TITLE,AUTHOR,COVERIMAGE)>
<!ELEMENT TITLE (#PCDATA)>
<!ELEMENT AUTHOR (#PCDATA)>
<!ELEMENT COVERIMAGE EMPTY>
<!ATTLIST COVERIMAGE Source ENTITY #REQUIRED>
<!NOTATION GIF SYSTEM "ShowGif.exe">
<!ENTITY faun SYSTEM "Faun.gif " NDATA GIF>>
]
>
<BOOK>
<TITLE>The Marble Faun</TITLE>
<AUTHOR>Nathaniel Hawthorne</AUTHOR>
<COVERIMAGE Source="faun" //>
</BOOK>
    在文件的元素中,COVERIMAGE 元素的Source 属性被指定成外部实体的名称,该实体包含即将被显示的封面图像的图形数据。因为Source 拥有ENTITY 型态,所以你可以指定其值为一般外部未解析实体的名称。事实上,你能够使用这种型态的实体的唯一方法就是将其名字指定成ENTITY 或ENTITIES 型态的属性。
    注意
    不像外部已解析实体的档案,一个外部未解析实体档案并不能直接被XML 处理器存取。更确切地说,处理器只是让实体与其卷标能够让应用程序使用,该程序可以对信息进行随意的处理。(例如,它可能会执行与卷标结合的程序并让程序显示实体档案中的数据。)在第九章中,你将学习到如何撰写可以存取实体与卷标的网页script。

宣告标签

    卷标描述了一种特殊的数据格式。它是借着提供该格式描述的位置、可以处理该种格式数据的应用程序位置,或简单的格式叙述等方式来提供数据格式。你可以使用标签来描述一般外部未解析实体(如你在前面章节中所见到的)的格式,或者你可以为拥有NOTATION 列举数据型态(如同第五章中的 <设定列举型态> 所介绍的)属性指定卷标。
标签拥有下列一般格式:
<!NOTATION NotationName SYSTEM SystemLiteral>
    这里的NotationNam 是标签的名称。你可以选择任何你想要的名称,只要是以字母或底线(_)起始,后面接着零或多个字母、数字、句点(.)、连字号(-),或底线(_)。你应该选择一个有意义的名称来代表该格式。例如,如果你想定义卷标来描述图形文件,你可以将它命名为BMP。
    SystemLiteral 则是系统literal,可以使用单引号('')或双引号(")来包围,而且可以包含任何的字符,除了用来作包围用的引号以外。你可以将任何可能对负责显示或处理XML 文件的应用程序有意义的格式叙述含括在系统literal 中。(记住,XML 处理器本身并不会使用这些信息;它只是单纯地将它传送给应用程序,而应用程序可能是网页中的script。)例如,你可以含括下列系统literal 的任何一个:
    可以处理或显示的数据格式应用程序的URI,如下面范例中所介绍的:
<!NOTATION BMP SYSTEM "Pbrush.exe">
<!NOTATION GIF SYSTEM "http://bogus.com/ShowGif.exe">
    描述格式的在线文件的URI,如:
<!NOTATION STRANGEFORMAT SYSTEM
"http://bogus.com/StrangeFormat.htm">
    格式的简单描述,如:
<!NOTATION GIF SYSTEM "Graphic Interchange Format">
    请参阅第五章中的 <使用外部的DTD 子集> 以取得更多URI 的信息与范例。

宣告参数实体

    你可以使用类似用在一般实体上的卷标宣告来宣告一个参数实体。在下面的章节中,你将学到如何宣告两种参数实体。

宣告内部已解析参数实体

    内部已解析参数实体的宣告拥有下列的格式:
<!ENTITY %EntityName EntityValue >
    这里的EntityName 是实体的名称。你可以选择任何的名字,只要遵守下面这些规则:
    实体的名称必须由字母或底线开头(_),后面接着零个或多个字母、数字、句点(.)、连字号(-)、或底线(_)。
    实体可以拥有和文件中一般实体一样的名字。(参数实体与一般实体使用不同的命名空间。)实体也可以拥有和元素或属性相同的名称。
    字母的大小写在卷标的所有文字中都是不同的,包括实体名称。因此,名为Spot的实体当然与名为spot 的实体是不同。
    EntityValue 是实体的值。你赋予参数实体的值是一连串被引号包围的字符串,称为引号包围字符串(quoted string)或literal。你可以将任何的literal 值指定给参数实体,只要遵守下面的规则即可:
    字符串可以用单引号('')或双引号来包围(")。
    字符串中不能包含与用来包围字符串相同的引号字符。
    字符串不能包含百分比(%)字符,也不能包含(&)符号字符,除非使用字符参照或一般实体参照才行。
    你只能将参数实体加到DTD 中卷标宣告可以出现的地方,而不是放在标签宣告中。因此,EntityValue 字符串必须包含一个或多个DTD 允许型态的完整卷标宣告。第五章的 <建构一个DTD> 中已介绍过标签宣告的格式。
    尤其是,参数实体可以包含元素型态宣告、属性列表宣告、一般实体宣告、卷标宣告、处理指令,或批注(参数实体宣告与参照并不被允许)。
    注意
    在这里规定的实体值规则,可以适用在任何状况下,这些规则是XML 规格的简化版本。这些规格-在某些情况下-允许你包含额外的项目于属性值中,并且在卷标以及卷标宣告中含括实体参照。详细的内容,请参阅 http://www.w3.org/TR/REC-xml 的XML 规格的第四部分。
    例如,下面的DTD 宣告了一个名为author 的内部已解析实体参数,该实体包括三个卷标宣告:批注、元素型态宣告,与属性列表宣告。实体的内容(意即,它的替换文字)会借着数种参数实体参照(%author;),被加入DTD 的底部:
<!DOCTYPE BOOK
[
<!ENTITY %author
"<!--author information -->
<!ELEMENT AUTHOR (#PCDATA)>
<!ATTLIST AUTHOR Nationality CDATA ''American''>"
>
<!ELEMENT BOOK (TITLE,AUTHOR)>
<!ELEMENT TITLE (#PCDATA)>
%author;
]
>
    注意,包含在实体宣告中的预设属性值是利用单引号包围(''American''),以避免使用那些被用来包围整个实体值的相同引号。上面的DTD 与下面这个是相等的:
<!DOCTYPE BOOK
[
<!ELEMENT BOOK (TITLE,AUTHOR)>
<!ELEMENT TITLE (#PCDATA)>
<!--author information -->
<!ELEMENT AUTHOR (#PCDATA)>
<!ATTLIST AUTHOR Nationality CDATA ''American''>
]
>

宣告参数外部已解析实体

    参数外部已解析实体的宣告拥有下列的一般格式:
<!ENTITY % EntityName SYSTEM SystemLiteral>
    这里的EntityName 是实体的名称。你可以选用任何遵守前面章节中介绍的参数实体命名规则的名称。
    SystemLiteral 是一个描述包含实体数据文件位置的系统literal。这个系统literal 可以使用单引号('')或双引号(")来包围,而且它可以包含任何字符,除了被用作包围的引号字符外。
    系统literal 指定了包含参数实体数据文件的URI,URI 在本质上与标准因特网的统一资源定位器(URL)是相同的。你可以使用完整的URL,例如:
<!ENTITY %declarations
SYSTEM "http://bogus.com/documents/Declarations.dtd">
    或者,你可以使用部分的URI,该URL 指定了一个相对于包含XML 文件位置的相对位置,例如:
<!ENTITY %declarations SYSTEM "Declarations.dtd">
    如同稍早提到的,在XML 文件中相对的URI 的运作就像HTML 网页中的URL 一样。想获得更多URI 的信息,请参阅第五章中的 <仅仅使用外部的DTD 子集> 。
    参数外部实体的档案必须包含DTD 中允许型态的有效卷标宣告。特别是,它可以包含元素型态宣告、属性列表宣告、实体宣告、标记宣告、处理指令或批注。(第五章的<建构一个DTD>中已描述过这些卷标宣告的型态。)你也可以包含参数实体参照与IGNORE 与INCLUDE 区段(第五章的<外部DTD 子集中的条件式忽略区段>中亦介绍过IGNORE 与INCLUDE 区段。)你可以使用参数外部已解析实体来储存相关宣告的群组。举个例子来说,假设你的企业是贩卖书籍、CD、邮票等。你可以将每一种项目的宣告放在个别档案。你被允许用不同的方式来结合这些宣告的群组。例如,你可能想要建立一份只描述书籍与CD 库存的XML 文件。要做到这点,你可以藉由使用参数外部已解析实体,将书籍与CD 宣告包含在文件的DTD 中,就像这个范例XML 文件中所示:
<?xml version="1.0"?>
<!DOCTYPE INVENTORY
[
<!ELEMENT INVENTORY (BOOK |CD)*>
<!ENTITY %book_decls SYSTEM "Book.dtd">
<!ENTITY %cd_decls SYSTEM "CD.dtd">
%book_decls;
%cd_decls;
]
>
<INVENTORY>
<BOOK>
<BOOKTITLE>The Marble Faun</BOOKTITLE>
<AUTHOR>Nathaniel Hawthorne</AUTHOR>
<PAGES>473</PAGES>
</BOOK>
<CD>
<CDTITLE>Concerti Grossi Opus 3</CDTITLE>
<COMPOSER>Handel</COMPOSER>
<LENGTH>72 minutes</LENGTH>
</CD>
<BOOK>
<BOOKTITLE>Leaves of Grass</BOOKTITLE>
<AUTHOR>Walt Whitman</AUTHOR>
<PAGES>462</PAGES>
</BOOK>
<!--additional items...-->
</INVENTORY>
这里是实体档案Book.dtd 的内容:
<!ELEMENT BOOK (BOOKTITLE,AUTHOR,PAGES)>
<!ELEMENT BOOKTITLE (#PCDATA)>
<!ELEMENT AUTHOR (#PCDATA)>
<!ELEMENT PAGES (#PCDATA)>
    而这里是实体档案CD.dtd 的内容:
<!ELEMENT CD (CDTITLE,COMPOSER,LENGTH)>
<!ELEMENT CDTITLE (#PCDATA)>
<!ELEMENT COMPOSER (#PCDATA)>
<!ELEMENT LENGTH (#PCDATA)>
    注意,参数外部已解析实体的运作模式非常类似外部DTD 的子集。然而,参数外部实体较具弹性-它们允许你包含数个外部宣告档案并将之依顺序含括。(外部DTD子集总是在整个内部DTD子集已经被处理过之后才会被处理)。

加入实体参照

    如同你所学到的,你借着使用实体参照来将实体的内容(替换文字)插入文件中。你已经看到少部分实体参照的范例。要复习并作个总结,一般的实体是以下面的方式被参照:
&EntityName ;
    而参数实体则是以下面方式被参照:
%EntityName ;
    其中EntityName 是在宣告区中指定给实体的名称。例外的情况是一般外部未解析实体,你不能借着使用参照来将实体加入文件中。要使用这类实体的唯一方法就是将实体的名称指定到拥有ENTITY 或ENTITIES 型态的属性中。(参阅第五章中的 <设定Tokenized 型态> 。)
    实体的宣告必须放在实体被参照之前。对于每一种实体型态,下面的表格提供了实体参照的格式,并列出加入实体参照的位置。在每一个插入位置叙述的尾端,表格提供了在本章中被参考的区段,你可以在范例中找到这些区段。本章稍后将讨论字符参照,此表中先包括字符参照的叙述以求完整性。
实体型式 实体参照的格式其中EntityName 是实体的名称 你可以加入实体参照(范例)的位置
一般内部已解析 &EntityName; 在元素的内容中(参阅 <宣告一般内部解析实体> )     在属性的值中(在属性宣告中,或元素的起始卷标中当作默认值)(参阅 <实体参照范例1> )     在内部实体宣告的值中(参阅 <实体参照范例2> ) 一般外部已解析 &EntityName; 在元素的内容中(参阅 <宣告一般外部已解析实体> )     在内部实体宣告的值中(参阅 <实体参照范例2> ) 一般内部未解析 EntAttr=''EntityName 其中EntAttr 是ENTITY 或ENTITIES 型态的属性 你不能加入任何参照到这类型的实体,但是你可以将实体的名称指定ENTITIES 型态的 到拥有NTITY 或属性中(参阅 <宣告一般外部未解析实体> ) 参数内部已解析 %EntityName; 在标签宣告可以发生的DTD 中,而不是在标签宣告中(有关例外的部分,请参阅http://www.w3.org/TR/ REC-xml 的XML 规格的第四部分)(参考 <宣告参数内部已解析实体> ) 参数内部未解析 %EntityName; 在标签宣告可以发生的DTD 中,而不是在标签宣告中(有关例外的部分,请参阅 http://www.w3.org/TR/REC-xml 的XML规格的第四部分)(参考 <宣告参数外部已解析实体> ) 字符参照 & #9; 或 & #xh; 其中9 是字符 在元素的内容中(参阅 <加入字符参照> )   以十进制表示的数值码而h是字符以十六进制表示的数值码 在属性值中(在属性列表宣告中或元素的起始卷标中当作默认值)(参阅 <加入字符参照> )     在内部实体宣告的值中(参阅 <加入字符参照> ) 
实体参照范例1

    下面的XML 文件宣告了两个一般内部已解析实体,am 与en。这份文件使用对am 的参照来为Nationality 属性指定值,并且利用对en 的参照来指定值给AUTHOR 元素中的Nationality 属性。这里使用实体的好处是借着简单地编辑实体的定义(例如,将en 的值从"English"改变成"British"),你可以改变遍布整个文章中的值(假设文章拥有许多个元素)。
<!DOCTYPE INVENTORY
[
<!ENTITY am "American">
<!ENTITY en "English">
<!ELEMENT INVENTORY (BOOK*)>
<!ELEMENT BOOK (TITLE,AUTHOR)>
<!ELEMENT TITLE (#PCDATA)>
<!ELEMENT AUTHOR (#PCDATA)>
<!ATTLIST AUTHOR Nationality CDATA "&am;">
]
>
<INVENTORY>
<BOOK>
<TITLE>David Copperfield</TITLE>
<AUTHOR Nationality="&en;">Charles Dickens</AUTHOR>
</BOOK>
<!--other elements...-->
</INVENTORY>

实体参照范例2

    下面的DTD 定义了一个一般内部已解析实体(int_entity)与一般外部已解析实体(ext_entity)。接着它会定义另一个一般内部已解析实体,combo_entity,并将前面两个属性加入到combo_entity 属性的值中。
<!DOCTYPE INVENTORY
[
<!ENTITY int_entity "internal entity value">
<!ENTITY ext_entity SYSTEM "Entity.xml">
<!ENTITY combo_entity
"value composed of &ext_entity;plus &int_entity;">
<!--other markup declarations...-->
]
>

加入字符参照

    你可以使用字符参照来加入不在键盘上的字符(例如,a),或者是那种加到目前文字中可能会造成违法的字符(例如,在元素字符数据中的「<」或「&」字符)。你不需要定义任何东西便能使用字符参照-你可以简单地将它加到你需要的地方。
    字符参照拥有两种不同的格式。第一种格式是:
& #9;
    其中9 是一个或多个十进制数(0 到9),代表字符在ISO/IEC 10646 字符集中的数值码。
    第二种字符参照的格式是:
& #xh;
    其中h 是一个或多个十六进制数字(0 到f 或F),它也代表字符在ISO/IEC 10646 字符集中的数值码。例如,& #65;与& #x41;都是加入大写字母A。(在十进制中A 的数值码是65,在十六进制中则是41。)
    ISO/IEC 10646 是一种为了表达几乎属于任何程序语言的字符而设定的国际字符集。(ISO 是国际标准组织,而IEC 则是国际电子委员会。)前128 的字符码与众所皆知用在大多数计算机的的ASCII 字符相同。下图显示了在ISO/IEC 10646 字符集的前256 的字符。图中的每一个项目,初始的数字(1:、2:、3:等等)是字符的十进制码,而接在字段后面的字符则是真正的字符-若有的话-如Microsoft Internet Explorer 5 显示。

    例如,你可以看到在图中 ? 的十进制数值码是228。因此借着输入下面的字符参照,你可以将这个字符加入到你的文件中:
& #228;
注意
    参阅前面章节 <加入实体参照> 中的表格,内含你可以将字符参照加到文件位置的列表。每一个位置的后面接着一个范例。
    在下面的元素中,借着使用字符参照& #60;(60 是「<」的十进制字符码),「<」字符被加入元素字符数据。如前所述,将「<」照字面直接加入字符数据是不合法的。
    <TITLE><The Legend of Sleepy Hollow></TITLE>
    在下面的元素中,& #228;字符参照被用来加入 ? (该字符你无法以普通的键盘输入)到属性值中:
<RESIDENT Address="Seilerst?tte 30,Wien">Mike Young</RESIDENT>
    最后,在下面DTD 中一般内部已解析实体的宣告里,& #37;字符参照被用来加入百分比(%)字符(37 是「%」的十进制码),该字符不能照字面直接被输入到内部实体的值中:
<!ENTITY heading1 "& #37;Complete">

使用预先定义的实体

    在XML 文件中,你可以使用预先定义实体的参照,将列在下面表格中五个字符的任何一个,加到某个这类字符被加入时可能会造成违法的位置。
预先定义 实体加入的字符 相等的字符参照
& amp;   &               & #38;
& lt;   <                & #60;
& gt;   >                & #62;
& apos; ''                & #39;
& quot; "                & #34;
    加入这些预先定义实体的参照相当于加入相对应字符的参照。当你在文件中看到预先定义实体的参照,将更容易记忆与了解。这些预先定义的实体就像其它一般内部已解析实体,除了你可以使用对这些实体的参照而不必定义实体-你还可以将它们加入相同的位置,如同这种型态的实体,即:
    在元素的内容中
    在属性的值中(当作属性宣告或元素起始卷标的默认值)
    在内部实体宣告的值中
    在下面的三个范例中,预先定义实体的参照被用来加入某些字符,这些字符若照字面加入可能会造成不合法的情况。
    在这个范例中,& lt;被用来加入「<」字符到元素的内容中:
<TITLE><The Legend of Sleepy Hollow></TITLE>
    在第二个范例中,& amp;被用来加入(&)符号到属性值中:
<PRODUCT Company="Ongaro &Sons">3/4" T fitting<</PRODUCT>
    在第三个范例中,& quot;被用来加入一个双引号(")到实体的值中(照字面直接加入可能造成不合法,因为双引号字符是用来包围字符串的):
<!ENTITY heading "Christopher "Kit"Carson">

独立的文件宣告

    如同你在第三章中学到的,你可以随意地含括一个位于XML 文件中的独立文件宣告。这个独立的宣告会告诉处理器是否需要外部宣告以处理文件。
    如果XML 文件拥有外部标签宣告(可能是在外部的DTD 子集中或在参数外部已解析实体中),但是没有一个宣告能够影响从XML 处理器传送到应用程序的文件内容,你可以将standalone 设定成''yes''或"yes",如下面的文件宣告一样:
<?xml version="1.0" standalone="yes"?>
    将standalone 设定成"yes"可能防止对外部档案的不必要处理。将standalone 设定成''no''或"no",或省略standalone 宣告,会告诉处理器它必须处理文件的外部标签宣告,因为它们之中一个或多个标签的宣告将会影响到文件的内容。
    会影响文件内容的外部卷标型态的列表(因此禁止将standalone 设定成"yes"),请参阅 http://www.w3.org/TR/REC-xml 的XML 规格的第2.9 节。

加入实体到文件中

    在下面的练习中,你将借着加入数个一般实体到第五章所建立的 Inventory Valid.xml 范例文件中,得到某些使用实体的经验。

将实体加到范例文件中

    1. 在你的文字编辑器中,开启你在第五章的 <将格式正确的文件转换成完整有效的文件> 中所建立的 Inventory Valid.xml 文件。(可在列表5-1 以及随书光盘中找到该程序代码。)
    2. 在文件的DTD 的起始部分(在靠近文件的顶端以[ ]字符包围的文字区块),加入下面的实体与卷标宣告:
3. <!--entities for assigning to the BINDING element:-->
4. <!ENTITY mass "mass market paperback">
5. <!ENTITY trade "trade paperback">
6. <!ENTITY hard "hardcover">
7.
8. <!--external entities containing reviews -->
9. <!--to be assigned to Review attribute of BOOK elements
-->
10. <!NOTATION DOC SYSTEM "Microsoft Word document">
11. <!NOTATION TXT SYSTEM "plain text file">
12. <!ENTITY rev_leaves
13. SYSTEM "Review Leaves of Grass.doc"
14. NDATA DOC>
15. <!ENTITY rev_faun1
16. SYSTEM "Review 01 of The Marble Faun.doc"
17. NDATA DOC>
18. <!ENTITY rev_faun2
19. SYSTEM "Review 02 of The Marble Faun.txt"
20. NDATA TXT>
21.
22. <!ENTITY rev_screw
23. SYSTEM "Review of The Turn of the Screw.txt"
NDATA TXT>
    前三个实体是一般内部已解析实体,让你可以加入BINDING 元素而不是输入真正的连结叙述到每一个元素中。使用实体可以帮助你确定给定链接型态的叙述在书籍与书籍之间是一致的。同时,实体让修改叙述变得更容易。(例如,你只需借着简单地编辑hard 属性,即可在每一个BINDING 元素中将「hardcover」 改成「hardback」。)接下来的(也是最后的)四个实体都是一般外部未解析实体,允许你将包含书籍评论的外部档案附加到BOOK 元素中。
    24. 为BOOK 元素加入Reviews 属性到属性列表宣告中,在DTD 后面部分中,它看起来像这样:
25. <!ATTLIST BOOK InStock (yes|no)#REQUIREDReviews ENTITIES #IMPLIED>
    Reviews 是一个选择性属性(#IMPLIED),你可以将一个或多个一般外部未解析实体的名称指定到Reviews 属性中。(Reviews 拥有ENTITIES 型态)。
    26. 在每一个BINDING 元素中,利用相对的实体参照来替换连结叙述。例如,你可以为The Adventures of Huckleberry Finn 改变BINDING 元素,从
<BINDING>mass market paperback</BINDING>
    变成
<BINDING>&mass;</BINDING>
    27. 将Reviews 属性加入BOOK 元素中,如下所示:
    对Leaves of Grass 来说:
<BOOK InStock="no" Reviews="rev_leaves">
    对The Marble Faun 来说:
<BOOK InStock="yes" Reviews="rev_faun1 rev_faun2">
    对The Turn of the Screw 来说:
<BOOK InStock="no" Reviews="rev_screw">
    28. 为了反应出你指定的新档名,将位于文件起始部分的批注从
<!--File Name:Inventory Valid.xml -->
    改成
<!--File Name:Inventory Valid Entity.xml -->
    29. 使用文字编辑器的 另存新文件 指令将修改过的文件储存为 Inventory ValidEntity.xml 。列表6-1 显示完整的XML 文件。(你可以在随书光盘的 InventoryValid Entity.xml 档案中找到。)
Inventory Valid Entity.xml
<?xml version="1.0"?>
<!--File Name:Inventory Valid Entity.xml -->
<!DOCTYPE INVENTORY
[
<!--entities for assigning to the BINDING element:-->
<!ENTITY mass "mass market paperback">
<!ENTITY trade "trade paperback">
<!ENTITY hard "hardcover">
<!--external entities containing reviews -->
<!--to be assigned to Review attribute of
BOOK elements -->
<!NOTATION DOC SYSTEM "Microsoft Word document">
<!NOTATION TXT SYSTEM "plain text file">
<!ENTITY rev_leaves
SYSTEM "Review Leaves of Grass.doc"
NDATA DOC>
<!ENTITY rev_faun1
SYSTEM "Review 01 of The Marble Faun.doc"
NDATA DOC>
<!ENTITY rev_faun2
SYSTEM "Review 02 of The Marble Faun.txt"
NDATA TXT>
<!ENTITY rev_screw
SYSTEM "Review of The Turn of the Screw.txt"
NDATA TXT>
<!ELEMENT INVENTORY (BOOK)*>
<!ELEMENT BOOK (TITLE,AUTHOR,BINDING,PAGES,PRICE)>
<!ATTLIST BOOK InStock (yes|no)#REQUIRED
Reviews ENTITIES
#IMPLIED>
<!ELEMENT TITLE (#PCDATA |SUBTITLE)*>
<!ELEMENT SUBTITLE (#PCDATA)>
<!ELEMENT AUTHOR (#PCDATA)>
<!ATTLIST AUTHOR Born CDATA #IMPLIED>
<!ELEMENT BINDING (#PCDATA)>
<!ELEMENT PAGES (#PCDATA)>
<!ELEMENT PRICE (#PCDATA)>]
]
>
<INVENTORY>
<BOOK InStock="yes">
<TITLE>The Adventures of Huckleberry
Finn</TITLE>
<AUTHOR Born="1835">Mark Twain</AUTHOR>
<BINDING>& mass;</BINDING>
<PAGES>298</PAGES>
<PRICE>$5.49</PRICE>
</BOOK>
<BOOK InStock="no" Reviews="rev_leaves">
<TITLE>Leaves of Grass</TITLE>
<AUTHOR Born="1819">Walt Whitman</AUTHOR>
<BINDING>& hard;</BINDING>
<PAGES>462</PAGES>
<PRICE>$7.75</PRICE>
</BOOK>
<BOOK InStock="yes">
<TITLE>The Legend of Sleepy Hollow</TITLE>
<AUTHOR>Washington Irving</AUTHOR>
<BINDING>& mass;</BINDING>
<PAGES>98</PAGES>
<PRICE>$2.95</PRICE>
</BOOK>
<BOOK InStock="yes " Reviews="rev_faun1 rev_faun2">
<TITLE>The Marble Faun</TITLE>
<AUTHOR Born="1804">Nathaniel
Hawthorne</AUTHOR>
<BINDING>?</BINDING>
<PAGES>473</PAGES>
<PRICE>$10.95</PRICE>
</BOOK>
<BOOK InStock="no">
<TITLE>Moby-Dick
<SUBTITLE>Or,the Whale</SUBTITLE>
</TITLE>
<AUTHOR Born="1819">Herman Melville</AUTHOR>
<BINDING>&hard;</BINDING>
<PAGES>724</PAGES>
<PRICE>$9.95</PRICE>
</BOOK>
<BOOK InStock="yes">
<TITLE>The Portrait of a Lady</TITLE>
<AUTHOR>Henry James</AUTHOR>
<BINDING>& mass;</BINDING>
<PAGES>256</PAGES>
<PRICE>$4.95</PRICE>
</BOOK>
<BOOK InStock="yes">
<TITLE>The Scarlet Letter</TITLE>
<AUTHOR>Nathaniel Hawthorne</AUTHOR>
<BINDING>& trade;</BINDING>
<PAGES>253</PAGES>
<PRICE>$4.25</PRICE>
</BOOK>
<BOOK InStock="no" Reviews="rev_screw">
<TITLE>The Turn of the Screw</TITLE>
<AUTHOR>Henry James</AUTHOR>
<BINDING>& trade;</BINDING>
<PAGES>384</PAGES>
<PRICE>$3.35</PRICE>
</BOOK>
</INVENTORY>
    30. 如果你想测试这份XML 文件,请使用第九章 <检查XML 文件的有效性> 中所介绍的XML 有效性验证script。

    • 评论
    • 分享微博
    • 分享邮件
    邮件订阅

    如果您非常迫切的想了解IT领域最新产品与技术信息,那么订阅至顶网技术邮件将是您的最佳途径之一。

    重磅专题
    往期文章
    最新文章