XML

可擴展標記語言（Extensible Markup Language，簡稱：XML）是一種標記語言和用於存儲、傳輸和重構鬆散數據的文件格式。它定義了一系列編碼文檔的規則以使其在人類可讀的同時機器可讀。全球資訊網聯盟於1998年發布的 XML 1.0 規範和其他相關開源標準共同定義了 XML。

XML 的設計目標是注重簡潔、通用和網際網路可用性。它是一種通過 Unicode 編碼實現對多種語言有強大支持的文本數據格式。儘管 XML 的設計重心在於文檔，它被廣泛應用於網路服務中鬆散數據結構的表示。

## 總覽

XML 的主要目的是序列化（如存儲、傳輸和重構鬆散數據）。對於兩個需要傳輸資訊的不同系統，它們也需要在文件格式上達成一致。XML 規範了這個流程，因此其類似於用於表示資訊的通用語言。

作為一個標記語言，XML 標記，分類和在結構方面組織數據。XML 標籤代表結構且包含元數據，標籤內是照 XML 標準編碼的數據。一個附加的 XML 結構（XSD）定義了用於解釋和驗證 XML 的必要的元數據（這也被稱為結構典範）。一個符合 XML 基本語法的文檔是「結構良好」的（well-formed），一個符合其附加結構的是「有效」（valid）的。

網際網路工程任務組的 RFC 7303（取代了舊的 RFC 3023）提供了用於構造 XML 中媒體類型的規則。它定義了三種媒體類型：

```mime
application/xml                             (text/xml是一个别名)
application/xml-external-parsed-entity      (text/xml-external-parsed-entity是一个别名)
application/xml-dtd
```

它們被用於在不暴露內容的同時傳輸未經處理的 XML 文件。RFC 7303 還建議基於 XML 的語言的媒體類型應以 +xml 結尾（如 SVG 的 image/svg+xml）。

對於 XML 在網路中的進一步使用指南於 RFC 3470 （也被稱為 IETF BCP 70，包含設計部署基於 XML 的語言的各個方面）提出。

## 應用

<image>

XML 在網際網路資訊交換中已經被廣泛應用。數以百計使用 XML 語法的文檔格式（包括 RSS、Atom、Office Open XML、OpenDocument、SVG、COLLADA 和 XHTML）被開發出來。XML 還為多種通信協議（如 SOAP 和 XMPP）提供了基礎語言。它還是AJAX使用的資訊交換格式之一。

許多工業數據標準，如Health Level 7、OpenTravel Alliance、FpML、MISMO和National Information Exchange Model，基於 XML 和 XML 附加結構豐富的特性。在出版領域，Darwin Information Typing Architecture 是一個 XML 行業數據標準。XML 被廣泛應用與支持各種出版格式。

## 關鍵術語

該部分內容基於 XML 規範。注意這並不是一個詳盡的列出所有結構的列表，而是提供 XML 中常見組成的介紹。

### 字符（ Character ）

XML 1.0 規範允許的（轉義後的最終解碼值）合法字符： #x9（水平制表符）、#xA（回車符）、#xD（換行符）、#x20-#xD7FF、#xE000-#xFFFD、#x10000-#x10FFFF。即任何Unicode字符，不包含 surrogate blocks, FFFE, FFFF。

XML 規範定義了5個"預定義實體"來表示特殊字符. XML也允許在每個文檔定義任意數量的其它命名實體.

下表列出了5個XML預定義實體. 通過名字引用這些實體的格式為`&amp;name;`，例如, `&amp;amp;` 將繪製為&.

名字｜字符｜Unicode碼位(十進位)｜標準｜描述

quot｜"｜U+0022 (34)｜XML 1.0｜雙引號

amp｜&｜U+0026 (38)｜XML 1.0｜&

apos｜'｜U+0027 (39)｜XML 1.0｜撇號

lt｜U+003E (62)｜XML 1.0｜大於號

### 處理器（ Processor ）與應用（ Application ）

XML 處理器（Processor，也稱作XML parser）分析標記語言並傳遞結構化資訊給應用（application）。

XML 規範規定了處理器要做什麼不能做什麼，但是應用並不在其討論範圍內。規範稱之為處理器的東西一般被通俗的稱為 XML 解析器。

### 標記（ Markup ）與內容（ Content ）

XML文檔的字符分為標記（Markup）與內容（content）兩類。可由簡單的語法判斷出來：標記通常以`&lt;`開頭，以`>`結尾；或者以字符`&` 開頭，以`;`結尾。不是標記的字符就是內容。但是CDATA部分，分解符號`&lt;![CDATA[`與`]]>`是標記，二者之間的文本為內容。最外界的空白符是標記。

### 標籤（ Tag ）

一個tag屬於標記結構，以`&lt;`開頭，以`>`結尾。Tag名字是大小寫敏感，不能包括任何字符 !"#$%&'*+,/;?@\^`

- 起始標籤 start-tag，如`&lt;section>`; * 結束標籤 end-tag，如`&lt;/section>`; * 空白標籤 empty-element tag，如`&lt;line-break />`. === 元素（Element） === 元素是文檔邏輯組件，它在起始標籤與匹配的結束標籤之間，或者僅由一個空白標籤組成。例如：`&lt;greeting>Hello, world!&lt;/greeting>`. 另一個例子是： `&lt;line-break&nbsp;/>`.在標籤間的內容可以包含其他元素（稱為子元素） === 屬性（Attribute） === 屬性是由名稱-值對組成的標記結構，存在於開始標籤或空元素標籤內。例如，`<img src="madonna.jpg" alt="Madonna" />`中，屬性的名稱是 "src" 和 "alt"，它們的值分別是 "madonna.jpg" 和 "Madonna"。另一個例子是`<step number="3">Connect A to B.</step>`，其中屬性的名稱是 "number"，其值是 "3"。XML 屬性只能有一個值，每個屬性在每個元素上最多只能出現一次。在常見情況下，如果需要包含多個值的列表，則必須通過將列表編碼為符合良構性的 XML 屬性，其格式超出了 XML 本身的定義。通常，這可以是以逗號或分號分隔的列表，或者如果已知各個值不包含空格ii，則可以使用以空格分隔的列表。例如，`<div class="inner greeting-box">Welcome!</div>`中，屬性 "class" 的值是 "inner greeting-box"，同時表示兩個 CSS 類名 "inner" 和 "greeting-box"。=== XML 聲明（Declaration） === XML文檔如果以XML declaration開始，則表述了文檔的一些資訊。如`&lt;?xml version="1.0" encoding="UTF-8"?>`. == 字符與轉義 == XML 文檔完全由 Unicode 字符庫中的字符組成。除了少數特殊排除的控制字符外，Unicode 定義的任何字符都可以出現在 XML 文檔的內容中。XML 包含用於識別構成文檔的 Unicode 字符編碼的工具，以及用於表達由於某種原因不能直接使用的字符的工具。=== 有效字符 === 以下範圍內的Unicode字碼在 XML 1.0 文檔中是有效的：
- U+0009 ( 水平制表符 ), U+000A ( 換行 ), U+000D ( 回車 ): 這些是在 XML 1.0 中唯一接受的控制字符
- U+0020 - U+D7FF, U+E000 - U+FFFD: 這些排除了BMP中的一些非字符（所有代理項，U+FFFE和U+FFFF是不被允許的）
- U+10000 - U+10FFFF: 這些包含所有在增補計劃中的字碼，包含非字符 XML 1.1 擴充了允許的字符集以包含上述內容和U+0001 - U+001F，但同時，它限制使用 U+0009（水平制表符）、U+000A（換行）、U+000D（回車）和 U+0085（下一行）以外的 C0 和 C1 控制字符），要求它們以轉義形式編寫（例如 U+0001 必須寫為 或其等效形式）。對於 C1 字符，此限制是向後不兼容；引入它是為了檢測常見的編碼錯誤。U+0000 （空）是唯一在任何 XML 1.1 文檔中都不被允許的字碼。=== 編碼檢測 === Unicode 字符集可被編碼為二進位字節以存儲或通過多種方式傳輸，這個過程被稱為編碼。Unicode 本身定義了一個覆蓋全字符集的編碼格式，其中知名的包含 UTF-8（不包含位順序記號，是XML 標準文檔推薦使用的格式）和 UTF-16。還有許多早於 Unicode 的文字編碼，如 ASCII 和多種 ISO/IEC 8859 字符集，但是它們的字符集都是 Unicode 字符集的子集。XML 允許使用任何 Unicode 定義的編碼以及其他字符集是Unicode子集的編碼。XML 還提供了一種機制，使XML 處理器可以在沒有任何先驗知識的情況下可靠地確定正在使用哪種編碼。除 UTF-8 和 UTF-16 之外的編碼不一定能被每個 XML 解析器識別（有些時候甚至不能識別 UTF-16，儘管標準要求它也被識別）。=== 轉義 === XML 提供了轉義工具以包含哪些不能直接引入的字符，例如：
- 字符「<」和「&」是關鍵的語法標記，因此不能出現在 CDATA 部分之外的內容中。雖然被允許但是不建議在 XML 實體值中使用「<」
- 某些字符編碼僅支持 Unicode 字符集中的部分字符（子集）。例如，用 ASCII 編碼 XML 文檔是合法的，但 ASCII 缺少 Unicode 字符（例如「é」）的字碼
- 在作者的機器上可能無法輸入這個字符
- 某些字符的字形無法在視覺上與其他字符區分開來，例如不間斷空格 (&#xa0) " " 和空格 (&#x20) " "，以及西里爾大寫字母 A (&#x410) 「А」和拉丁文大寫字母 A (&#x41)「A」 ~，也不能包含空格，並且不能以「-」、 「.」或數字開頭
- 僅存在一個根元素
- 單個根元素包含所有其他元素。

XML 文檔的定義排除了那些違反了良構性規則的文本；這些文本根本不是 XML。遇到這種違反規則的情況時，XML 處理器需要報告這些錯誤並停止正常處理。這種政策，偶爾被稱為「嚴格錯誤處理」，與處理 HTML 的程序的行為形成了明顯對比，因為這些程序在存在嚴重標記錯誤的情況下，仍然能夠產生合理的結果。這一方面的政策被批評為違反了 Postel 法則（「對發送的內容要保守，對接受的內容要寬容」）。

XML 規範將一個有效的 XML 文檔定義為一個既符合良構性規則，又遵循文檔類型定義（DTD）規則的 XML 文檔。

## 例

XML定義結構、存儲資訊、傳送資訊。下例為小張發送給大元的便條，存儲為XML。

```xml
<?xml version="1.0"?>
  <小紙條>
    <收件人>大元</收件人>
    <發件人>小張</發件人>
    <主題>問候</主題>
    <具體內容>早啊，飯吃了沒？ </具體內容>
  </小紙條>
```

這XML文檔僅是純粹的資訊標籤，這些標籤意義的展開依賴於應用它的程序。

### 結構

每個XML文檔都由XML聲明開始，在上面的代碼中的第一行就是XML聲明。這一行代碼會告訴解析器或瀏覽器，這個文件應該按照XML規則進行解析。

但是，根元素到底叫還是，則是由文檔類型定義（DTD）或XML綱要（XML Schema）定義的。如果DTD規定根元素必須叫，那麼若寫作就不符合要求。這種不符合DTD或XML綱要的要求的XML文檔，被稱作不合法的XML，反之則是合法的XML。

XML文件的第二行並不一定要包含文檔元素；如果有注釋或者其他內容，文檔元素可以遲些出現。

最常見的PI（processing instruction,像XML序言, 卻是不同類型的語法）是用來指定XML文件的樣式表, 這個PI一般會直接放在XML序言之後，通常由Web瀏覽器使用，來將XML數據以特殊的樣式顯示出來。

XML的結構有一個缺陷，那就是不支持分幀（framing）。當多條XML消息在TCP上傳輸的時候，無法基於XML協議來確定一條XML消息是否已經結束。

## 延伸閱讀

- Annex A of ISO 8879:1986 (SGML)

## 基本資料

- 頭銜：XML (標準)
- 車隊名稱：可擴展標記語言
- 狀態：已發布, 全球資訊網聯盟
- 開始年：1996
- 首次出版：1998年2月10日
- 版本：1.1 (第二版)
- version_date：2006年9月29日
- 組織：全球資訊網聯盟
- 編輯：Tim Bray, Jean Paoli, Michael Sperberg-McQueen, Eve Maler, François Yergeau, John W. Cowan
- 基礎標準：SGML
- 有關標準：XML Schema
- 領域：序列化
- 日語原文：XML (文件格式)
- 擴展名：.xml
- mime：application/xml, text/xml
- 統一類型標識：public.xml
- UTI結構：public.text
- magic：<?xml
- 所有者：全球資訊網聯盟
- 格式類型：標記語言
- 擴展自：SGML
- 擴展為：XHTML, RSS, Atom, KML 等等
- 標準： 1.0, 第五版 1.1, 第二版
- 免費在線檔案：是
- 啟用：是