在 XML 中添加实体
?http://www.ibm.com/developerworks/cn/xml/x-entities/?S_TACT=105AGX52&S_CMP=tec-csdn
簡介
常用縮寫詞
- ASCII:美國信息交換標準碼
- DOM:文檔對象模型
- DTD:文檔類型定義
- HTML:超文本標記語言
- W3C:萬維網聯盟
- XHTML:可擴展超文本標記語言
- XML:可擴展標記語言
XML 是一種受到良好支持的 Internet 標準,用于以一種特殊方式編碼結構化數據:XML 編碼的數據幾乎能夠用所有編程語言輕松解碼,甚至可以使用標準文本編輯器由人類閱讀或編寫。許多應用程序,特別是遵循現代標準的 Web 瀏覽器,都可以直接處理 XML 數據。
XML 中的實體用于表示特殊字符(通常難以或不可能在標準鍵盤上輸入),重用 XML 代碼段,將文檔組織為幾個文件,以及簡化 DTD 的編寫。
回頁首
什么是實體?
實體是對數據的引用;根據實體種類的不同,XML 解析器將使用實體的替代文本或者外部文檔的內容來替代實體引用。本文中要介紹以下幾種實體,了解它們的工作方式,以及如何在我們自己的 XML 文檔中利用它們的優勢。
- 字符實體
- 命名實體
- 外部實體
- 參數實體
所有實體(除參數實體外)都以一個與字符(&)開始,以一個分號(;)結束。XML 標準定義了所有 XML 解析器都必須實現的 5 種標準實體,盡管它們還支持其他實體。
- ' 是一個撇號:'
- & 是一個與字符:&
- " 是一個引號:"
- < 是一個小于號:<
- > 是一個大于號:>
我們經常會在 XHTML 和 XML 文檔中看到和用到 &、< 和 > 實體,特別是那些通過展示示例來歸檔標記的文檔。
回頁首
字符實體
對于字符實體,我們可以用十進制格式(&#nnn;,其中 nnn 是字符的十進制值)或十六進制格式(&#xhhh;,其中 hhh 是字符的十六進制值)來指定任意 Unicode 字符。
例如,大寫字母 A 是 Unicode 字符 U+0065。如果想將其表示為一個字符實體,可以輸入 A(十進制值)或 A(十六進制值)。另一個更有用的字符也許是 ? —— 版權符號。這個版權符號的字符實體是 © 或 ©,因為它是 Unicode 字符 U+0169。
在進行其他實體相關的解析之前,將首先替代字符實體。對 XML 解析器而言,字符實體與直接輸入指定字符的效果完全相同。字符實體類似于 C 編程語言中的三聯符(trigraphs):只是特定字符的替代表示。
還應該注意到,盡管 XML 解析器可以毫不費力地處理 “任何” 字符實體,但這些字符實體可能對處理應用程序和顯示系統毫無益處。確保能夠訪問適當的字體和編碼支持系統,以便在文檔中顯示任何稀奇古怪的字符。當前字體中找不到某個適當的字符時,多數系統會顯示一個某種占位符。
回頁首
命名實體
命名實體(在 XML 規范中也稱為內部實體)就是我們在談論 “實體” 時所指的實體。命名實體在 DTD 或內部子集(即文檔中 <!DOCTYPE> 語句的一部分)中聲明,在文檔中用作引用。在 XML 文檔解析過程中,實體引用將由它的表示替代。
簡單來說,實體就是宏,它們在我們處理文檔時得到擴展。
XHTML 規范使用命名實體來表示 ISO 8859-1 (Latin 1) 字符集中包含的、但在多數鍵盤上沒有的特殊字符。其他實體用于指定特殊字符和符號。這些標準實體受到 Web 瀏覽器的良好支持,甚至允許我們在只支持 7 位 ASCII 字符集的系統(是的,還有人在使用古老的大型機系統)上使用純文本編輯器來編寫 XHTML 文檔。清單 1 提供了 XHTML 1.0 的特殊字符的簡要列表。
清單 1. XHTML 1.0 的幾個特殊字符
| <!ENTITY ndash "–"> <!-- en dash, U+2013 ISOpub --> <!ENTITY mdash "—"> <!-- em dash, U+2014 ISOpub --> <!ENTITY lsquo "‘"> <!-- left single quotation mark,U+2018 ISOnum --> <!ENTITY rsquo "’"> <!-- right single quotation mark,U+2019 ISOnum --> <!ENTITY sbquo "‚"> <!-- single low-9 quotation mark, U+201A NEW --> <!ENTITY ldquo "amp;“"> <!-- left double quotation mark,U+201C ISOnum --> <!ENTITY rdquo "”"> <!-- right double quotation mark,U+201D ISOnum --> |
如 清單 1(它是一塊 XHTML 1.0 Special Characters 聲明)所示,命名實體由字符實體替代。如 上一小節 所述,字符實體等同于在文檔中直接輸入的引用字符。
我們在文檔中使用 – 時,它由 Unicode 字符 U+2013(短橫線 - 字符)替代。由于 – 的替代文本是一個字符引用,因此它等同于輸入一個短橫線字符。
命名實體在整個文檔被讀取后進行解析。這樣,一些命名實體完全可以引用其他命名實體,其原因是所有實體都將在它們被擴展之前聲明。例如,清單 2 展示了兩個實體,其中一個實體引用另一個實體。
清單 2. 引用實體的實體
| <!ENTITY c "Chris"> <!ENTITY ch "&c; Herborth"> |
在一個文檔中使用 &c; 將擴展為 Chris,&ch; 將擴展為完整的 Chris Herborth。
循環引用是實體中的錯誤。因創建了循環引用而使文檔無效時,解析器會報告錯誤。
使用 Firefox、Safari 和 Chrome 時,這些實體引用的效果與在存儲為 XML 文件的 XHTML 文檔中的效果一樣,但使用 Microsoft? Internet Explorer? 8 時效果不一樣。我將在 在文檔中定義實體 小節中介紹如何聲明命名實體。
回頁首
外部實體
外部實體表示外部文件的內容。外部實體在有些情況下很有用,比如說,您在創建一本圖書并且想將每一章存儲為一個單獨的文件。您可能會創建一組如 清單 3 所示的實體。
清單 3. 外部實體引用其他文件
| <!ENTITY chap1 SYSTEM "chapter-1.xml"> <!ENTITY chap2 SYSTEM "chapter-2.xml"> <!ENTITY chap3 SYSTEM "chapter-3.xml"> |
現在,當您在主圖書 XML 文件(參見 清單 4)中將這些實體放到一起時,這些文件的內容將插入在引用點。
清單 4. 將各章放到一起
| <?xml version="1.0" encoding="utf-8"?> <!-- Pull in the chapter content: --> &chap1; &chap2; &chap3; |
由于這些文件的內容被插入到 XML 文檔中,因此它們也必須是有效的 XML,而且它們必須是平衡的。也就是說,在一個外部實體的引用文件中開始的任何元素也必須在那個文件中結束。當 清單 4 中的 XML 文檔被解析時,它將被讀取為一個大文檔,包含 chapter-1.xml、chapter-2.xml 和 chapter-3.xml 文件的內容;XML 處理應用程序并不介意文檔寫入到 4 個單獨的文件中。
回頁首
參數實體
參數實體只用于 DTD 和文檔的內部子集中。它們使用百分號(%)而不是與字符,可以是命名實體或外部實體。
在 XHTML DTD 中,參數實體用于引用在外部文件中聲明的 Latin 1, Special Characters and Symbols 實體集,以及用作快捷方式以重用 DTD 的某些部分,比如每個 XHTML 元素都支持的標準屬性集(參見 清單 5)。
清單 5. XHTML 1 DTD 中的一個參數實體
| <!ENTITY % attrs "%coreattrs; %i18n; %events;"> <!ENTITY % coreattrs"id ID #IMPLIEDclass CDATA #IMPLIEDstyle %StyleSheet; #IMPLIEDtitle %Text; #IMPLIED"> <!ENTITY % i18n"lang %LanguageCode; #IMPLIEDxml:lang %LanguageCode; #IMPLIEDdir (ltr|rtl) #IMPLIED"> |
如 清單 5 所示,參數實體可以引用其他參數實體。與命名實體一樣,參數實體在整個文檔被讀取之后才被擴展。
回頁首
在文檔中定義實體
您也許已經注意到,實體使用 ENTITY 聲明進行定義,既可以作為外部 DTD 的一部分(參見 清單 6),也可以作為文檔的外部子集的一部分(參見 清單 7)。
清單 6. DTD 中的實體聲明
| <!-- 6.1 Named entity for site name: --> <!ENTITY dw "developerWorks"><!-- 6.2 External entity for re-use: --> <!ENTITY bio SYSTEM "dw-author-bio.xml"><!-- 6.3 Parameter entity for use in DTD --> <!ENTITY % English "en-US|en-CA|en-UK"> |
在聲明命名實體時,指定實體的名稱及其替代文本。替代文本可以包含字符實體、命名實體和元素等,但不包含參數實體。
清單 7. 內部子集中的實體聲明
| <?xml version="1.0" encoding="UTF-8"?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd" [<!ENTITY test-entity "This <em>is</em> an entity."> ]> <html xmlns="http://www.w3.org/1999/xhtml"> <head><meta http-equiv="Content-Type" content="application/xhtml+xml;charset=utf-8"/><title>Entities in XML</title> </head> <body><h1>Entities in XML</h1><p>&test-entity;</p><p>You can use it anywhere you'd use a standard XHTML entity:</p><pre>&test-entity;</pre> </body> </html> |
清單 7 中的 XHTML 文檔(在我的系統上保存為 entities.xml)在其內部子集中聲明了一個名為 test-entity 的新實體。內部子集是 <!DOCTYPE> 聲明的一部分,位于 DTD 的 PUBLIC 和/或 SYSTEM 標識符之后的方括號中。
瀏覽器目前似乎不支持內部子集中的外部實體或參數實體,這也許是一個安全措施。當這兩種類型的實體與 Web 瀏覽器的呈現引擎一起使用時,可能被用于創建拒絕服務攻擊或其他惡意文檔。
回頁首
在文檔中使用實體
現在已經熟悉在文檔中使用實體的機制;DTD 中的參數實體的工作方式與此相同。前面所示的清單展示了如何使用各種實體:
- 字符實體 — 清單 1
- 命名實體 — 清單 2 和 清單 7
- 外部實體 — 在 清單 3 中聲明,在 清單 4 中使用
- 參數實體 — 清單 5
在需要反復輸入相同的文本時,可以嘗試利用實體。以下是一些不錯的實體示例:公司的正式名稱、正在進行文檔記錄的產品的名稱、版權、商標、注冊商標通知,以及電子郵件地址(參見 清單 8)。
清單 8. 通過實體減少輸入
| <!ENTITY co "Father Karass' Olde Tyme Steambots, LLC"> <!ENTITY prod "Semi-Autonomous Security Servant (SASSbot)"> <!ENTITY c "Copyright © 2010 &co; All Rights Reserved."> <!ENTITY author "Chris Herborth (chrish@pobox.com)"> |
可能變化的事物(比如產品名稱)非常適合使用實體,這與在程序源代碼中聲明常量很相似。當產品名稱變化時,我們只需更新實體聲明,不必搜索并替代所有文件(參見 清單 9)。
清單 9. 使用實體輕松更新不斷變化的文檔
| <!-- Current name: --> <!ENTITY prod "Semi-Autonomous Security Servant (SASSbot)"><!-- Old names preserved for posterity: --><!-- Original R&D name: --> <!--ENTITY prod "Security Bot"--><!-- Marketing name v1 --> <!--ENTITY prod "Security Servant Bot"--><!-- Marketing name v2 --> <!--ENTITY prod "Autonomous Security Servant Bot"--> |
回頁首
結束語
基于 XML 的標準(比如 XHTML)定義了一個有用的實體庫,這使得創建包含不能在標準鍵盤上直接輸入的字符的文檔成為可能。命名實體的作用類似于宏,允許您使用實體引用替代重復或難以輸入的文本。盡管 Web 瀏覽器不支持外部實體,但是我們可以通過其他 XML 應用程序來使用它們創建復合文檔,這使得標準化和重用文檔的某些部分變得更容易。參數實體用于將外部聲明拖到 DTD 中,或者用于創建 DTD 內部宏來改善可讀性。
在 XML 文檔的 DOCTYPE 聲明中聲明命名實體很簡單,而且您可能已經知道如何在文檔主體中使用它們。
參考資料
學習
- 使用 jQuery 在瀏覽器中處理 XML(Uche Ogbugi,developerWorks,2009 年 12 月):了解如何通過 JQuery 在瀏覽器中直接處理 XML。
- XML 1.0 Specification(W3C Recommendation,2008 年 11 月 26 日):參閱這個資源,了解關于 XML 特性(比如 CDATA 部分)的具體細節。
- 技巧:使用實體解析器 (Brett McLaughlin,developerWorks,2001 年 6 月):了解如何使用實體解析器來找到外部實體引用的內容。
- 技巧:使用 Unicode 數據庫尋找適用于 XML 文檔的字符(Uche Ogbuji,developerWorks,2006 年 3 月):了解如何使用 Unicode 數據庫來為 XML 文檔找到字符實體。
- 技巧:帶參數實體的靈活的 DTD(Brett McLaughlin,developerWorks,2003 年 1 月):了解如何使用參數實體創建靈活的 DTD。
- The XML FAQ:探索 XML 信息的另一個優秀資源 — Peter Flynn 編輯的 XML FAQ。
- 來自 W3schools.com 的 XML DOM 教程:了解瀏覽器可用的基于 XML 的界面(以及支持這些界面的瀏覽器)。
- XML Entity Definitions for Characters(W3C Working Draft,2009 年 11 月 17 日):了解分配給 Unicode 字符的幾組名稱。
- XHTML? 1.0: The Extensible HyperText Markup Language(World Wide Web Consortium Recommendation,2000 年 1 月 26 日):閱讀關于 XHTML 1.0 的更多信息。XHTML 1.0 是一個 XML 1.0 應用程序、HTML 4 的全新版本,為未來的 XHTML 擴展性奠定了基礎。
- Wikipedia 的 XML 和 HTML 字符實體列表:檢查這個方便的列表,它包含實體名稱及其字符表示、Unicode 值以及定義它的相關 W3C 標準。
- 本文作者的其他文章(Chris Herborth,developerWorks,2006 年 3 月至今):閱讀關于 XML 和其他技術的文章。
- developerWorks XML 專區:在 XML 專區獲取提高您的專業技能所需的資源。
- IBM XML 認證:了解如何才能成為一名 IBM 認證的 XML 和相關技術的開發人員。
- XML 技術庫:訪問 developerWorks XML 專區,獲得廣泛的技術文章和技巧、教程、標準和 IBM 紅皮書。
- developerWorks 技術活動 和 網絡廣播:隨時關注技術的最新進展。
- developerWorks 播客:收聽面向軟件開發人員的有趣訪談和討論。
獲得產品和技術
- 下載 IBM 產品評估試用版軟件 或 IBM SOA Sandbox for People,并開始使用來自 DB2?、Lotus?、Rational?、Tivoli? 和 WebSphere? 的應用程序開發工具和中間件產品。
討論
- XML 專區討論論壇:參與任何一個 XML 相關討論。
- developerWorks 博客:閱讀這些博客并參與討論。
關于作者
Chris Herborth 是一位屢獲殊榮的高級技術作家兼軟件開發人員,擁有超過 15 年的操作系統和編程寫作經驗。當 Chris 不陪伴兒子 Alex 和妻子 Lynette 時,他將業余時間花費在設計、寫作和研究(也就是玩)電子游戲上。但是他不玩魔獸世界(World of Warcraft)。
?
總結
以上是生活随笔為你收集整理的在 XML 中添加实体的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Hibernate配置属性详解
- 下一篇: Hibernate插入、查询、删除操作