打印本文 打印本文 关闭窗口 关闭窗口
定义及使用实体
作者:武汉SEO闵涛  文章来源:敏韬网  点击数3229  更新时间:2009/4/23 11:18:18  文章录入:mintao  责任编辑:mintao
     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。
  
  宣告标签
  
 

[1] [2] [3] [4]  下一页

打印本文 打印本文 关闭窗口 关闭窗口