XML新手入門 創(chuàng)建構(gòu)造良好的XML
如果您是 XML 新手,本文將為您介紹 XML 文檔的基礎(chǔ)結(jié)構(gòu),以及創(chuàng)建構(gòu)造良好的 XML 需要遵循的規(guī)則,包括命名約定、正確的標(biāo)記嵌套、屬性規(guī)則、聲明和實(shí)體。您還可以從本文了解到 DTD 和 schema 的驗(yàn)證。
XML 是可擴(kuò)展標(biāo)記語(yǔ)言(Extensible Markup Language)的縮寫,其中的 標(biāo)記(markup)是關(guān)鍵部分。您可以創(chuàng)建內(nèi)容,然后使用限定標(biāo)記標(biāo)記它,從而使每個(gè)單詞、短語(yǔ)或塊成為可識(shí)別、可分類的信息。您創(chuàng)建的文件,或文檔實(shí)例 由元素(標(biāo)記)和內(nèi)容構(gòu)成。當(dāng)從打印輸出讀取或以電子形式處理文檔時(shí),元素能夠幫助更好地理解文檔。元素的描述性越強(qiáng),文檔各部分越容易識(shí)別。自從出現(xiàn)標(biāo)記至今,帶有標(biāo)記的內(nèi)容就有一個(gè)優(yōu)勢(shì),即在計(jì)算機(jī)系統(tǒng)缺失時(shí),仍然可以通過(guò)標(biāo)記理解打印出來(lái)數(shù)據(jù)。
標(biāo)記語(yǔ)言從早期的私有公司和政府制定形式逐漸演變成標(biāo)準(zhǔn)通用標(biāo)記語(yǔ)言(Standard Generalized Markup Language,SGML)、超文本標(biāo)記語(yǔ)言(Hypertext Markup Language,HTML),并且最終演變成 XML。SGML 比較復(fù)雜,HTML(實(shí)際上僅是一組元素集)在識(shí)別信息方面不夠強(qiáng)大。XML 則是一種易于使用和易于擴(kuò)展的標(biāo)記語(yǔ)言。
您可以使用 XML 創(chuàng)建自己的元素,從而能夠更精確地表示自己的信息。您可以在文檔內(nèi)部識(shí)別每個(gè)部分,而不是將文檔看作僅由標(biāo)題和段落組成。為了提高效率,您可能需要定義數(shù)量一定的元素,并統(tǒng)一使用它們。(您可以在文檔類型定義(Document Type Definition, DTD )或模式 (schema)中定義元素,稍后我將對(duì)此進(jìn)行簡(jiǎn)要的描述)。一旦習(xí)慣使用 XML 之后,就可以在構(gòu)建文件時(shí)嘗試處理元素名稱。
構(gòu)建 XML
如前所述,XML 文件由內(nèi)容和標(biāo)記組成。您通過(guò)以標(biāo)記包圍內(nèi)容的方式將大部分內(nèi)容包含在元素中。例如,假設(shè)您需要?jiǎng)?chuàng)建一本 XML 烹飪書。您需要用 XML 編寫名為 Ice Cream Sundae 的食譜。為了標(biāo)記食譜名,您需要將這個(gè)文本包含到元素中,即分別在文本的首末兩端添加開始和結(jié)束標(biāo)記。可以將元素命名為 recipename。要標(biāo)記元素的開始標(biāo)記,像這樣將元素名放到尖括號(hào)中(﹤﹥):﹤recipename﹥。然后輸入文本 Ice Cream Sundae。在文本的后面輸入結(jié)束標(biāo)記,即將元素名放在尖括號(hào)內(nèi),然后在元素名前面加上一個(gè)終止斜杠(/),比如:﹤/recipename﹥。這些標(biāo)記構(gòu)成一個(gè)元素,您可以在元素的內(nèi)部添加內(nèi)容或其他元素。
您可以為某個(gè)文檔或文檔集創(chuàng)建元素名??梢詣?chuàng)建規(guī)則讓元素根據(jù)您的特定需求組合起來(lái)。元素名可以是比較具有針對(duì)性的,也可以是比較通用的。您還可以創(chuàng)建決定添加何種元素的規(guī)則。這些規(guī)則可以是嚴(yán)格的,也可以是松散的,這完全由您決定。一定要為文檔創(chuàng)建元素,以識(shí)別您認(rèn)為重要的部分。
開始創(chuàng)建 XML 文件
XML 文檔的第一行可以是一個(gè) XML 聲明。這是文件的可選部分,它將文件識(shí)別為 XML 文件,有助于工具和人類識(shí)別 XML(不會(huì)誤認(rèn)為是 SGML 或其他標(biāo)記)??梢詫⑦@個(gè)聲明簡(jiǎn)單地寫成 ﹤?xml?﹥,或包含 XML 版本(﹤?xml version="1.0"?﹥),甚至包含字符編碼,比如針對(duì) Unicode 的 ﹤?xml version="1.0" encoding="utf-8"?﹥。因?yàn)檫@個(gè)聲明必須出現(xiàn)在文件的開頭,所以如果打算將多個(gè)小的 XML 文件合并為一個(gè)大 XML 文件,則可以忽略這個(gè)可選信息。
創(chuàng)建根元素
根元素的開始和結(jié)束標(biāo)記用于包圍 XML 文檔的內(nèi)容。一個(gè)文件只能有一個(gè)根元素,并且需要使用 “包裝器” 包含它。清單 1 顯示了經(jīng)過(guò)刪節(jié)的示例,其中的根元素名為 ﹤recipe﹥。(參見(jiàn) 下載 小節(jié)獲得完整的 XML 文件)。
清單 1. 根元素
﹤?xml version="1.0" encoding="UTF-8"?﹥
﹤recipe﹥
﹤/recipe﹥
在構(gòu)建文檔時(shí),內(nèi)容和其他標(biāo)記必須放在 ﹤recipe﹥ 和 ﹤/recipe﹥ 之間。
命名元素
標(biāo)記的大小寫保持一致
創(chuàng)建 XML 時(shí),要確保開始和結(jié)束標(biāo)記的大小寫是一致的。如果大小寫不一致,在使用或查看 XML 時(shí)將出現(xiàn)錯(cuò)誤。例如,如果大小寫不一致,Internet
Explorer 將不能顯示文件的內(nèi)容,但它會(huì)顯示開始和結(jié)束標(biāo)記不一致的消息。
到目前為止,都使用 ﹤recipe﹥ 作為根元素。在 XML 中,先要為元素選擇名稱,然后再根據(jù)這些名稱定義相應(yīng)的 DTD 或 schema。創(chuàng)建名稱時(shí)可以使用英文字母、數(shù)字和特殊字符,比如下劃線(_)。下面給出命名時(shí)需要注意的地方:
元素名中不能出現(xiàn)空格。
名稱只能以英文字母開始,不能是數(shù)字或符號(hào)。(在第一個(gè)字母之后就可以使用字母、數(shù)字或規(guī)定的符號(hào),或它們的混合)。
對(duì)大小寫沒(méi)有限制,但前后要保持一致,以免造成混亂。
我們繼續(xù)以前面的示例為例,如果添加了名為 ﹤recipename﹥ 的元素,它將有一個(gè)開始標(biāo)記 ﹤recipename﹥ 和相應(yīng)的結(jié)束標(biāo)記
﹤/recipename﹥。
清單 2. 更多元素
﹤?xml version="1.0" encoding="UTF-8"?﹥
﹤recipe﹥
﹤recipename﹥Ice Cream Sundae﹤/recipename﹥
﹤preptime﹥5 minutes﹤/preptime﹥
﹤/recipe﹥
XML 文檔可以使用內(nèi)部不包含任何內(nèi)容的空標(biāo)記,這些標(biāo)記可以表示為單個(gè)標(biāo)記,而不是一組開始和結(jié)束標(biāo)記。以類似于 HTML 的文件為例,里面的 ﹤img src="mylogo.gif"﹥ 是一個(gè)獨(dú)立的元素。它不包含任何子元素或文本,因此它是一個(gè)空元素,您可以將它表示為 ﹤img src="mylogo.gif" /﹥(以一個(gè)空格和熟悉的終止斜杠結(jié)束)。
嵌套元素
嵌套 即把某個(gè)元素放到其他元素的內(nèi)部。這些新的元素稱為子 元素,包含它們的元素稱為父 元素。﹤recipe﹥ 根元素中嵌套有幾個(gè)其他元素,如 清單 3 所示。這些嵌套的子元素包括 ﹤recipename﹥、﹤ingredlist﹥ 和 ﹤preptime﹥。﹤ingredlist﹥ 元素內(nèi)部包含多個(gè)子元素 ﹤listitem﹥。XML 文檔可以使用多層嵌套。
一個(gè)常見(jiàn)的語(yǔ)法錯(cuò)誤是父元素和子元素的錯(cuò)誤嵌套。任何子元素都要完全包含在其父元素的開始和結(jié)束標(biāo)記內(nèi)部。每個(gè)同胞(Sibling)元素必須在下一個(gè)同胞元素開始之前結(jié)束。
清單 3 的代碼顯示了正確的嵌套。這些標(biāo)記的開始和結(jié)束沒(méi)有與其他標(biāo)記混合 在一起。
清單 3. 正確嵌套的 XML 元素
﹤?xml version="1.0" encoding="UTF-8"?﹥
﹤recipe﹥
﹤recipename﹥Ice Cream Sundae﹤/recipename﹥
﹤ingredlist﹥
﹤listitem﹥
﹤quantity﹥3﹤/quantity﹥
﹤itemdescription﹥chocolate syrup or chocolate fudge﹤/itemdescription﹥
﹤/listitem﹥
﹤listitem﹥
﹤quantity﹥1﹤/quantity﹥
﹤itemdescription﹥nuts﹤/itemdescription﹥
﹤/listitem﹥
﹤listitem﹥
﹤quantity﹥1﹤/quantity﹥
﹤itemdescription﹥cherry﹤/itemdescription﹥
﹤/listitem﹥
﹤/ingredlist﹥
﹤preptime﹥5 minutes﹤/preptime﹥
﹤/recipe﹥
添加屬性
有時(shí)候要為元素添加屬性。屬性由一個(gè)名稱-值對(duì)構(gòu)成,值包含在雙引號(hào)中("),比如:type="dessert"。屬性是在使用元素時(shí)存儲(chǔ)額外信息的一種方式。在同一個(gè)文檔中,可以根據(jù)需要對(duì)每個(gè)元素的不同實(shí)例采用不同的屬性值。
您可以在元素的開始標(biāo)記內(nèi)部輸入一個(gè)或多個(gè)屬性,比如:﹤recipe type="dessert"﹥。如果要添加多個(gè)屬性,各個(gè)屬性之間使用空格分開,比如:﹤recipename cuisine="american" servings="1"﹥。清單 4 顯示了當(dāng)前的 XML 文件。
清單 4. 帶有元素和屬性的 XML 文件
﹤?xml version="1.0" encoding="UTF-8"?﹥
﹤recipe type="dessert"﹥
﹤recipename cuisine="american" servings="1"﹥Ice
Cream Sundae﹤/recipename﹥
﹤preptime﹥5 minutes﹤/preptime﹥
﹤/recipe﹥
您可以根據(jù)需要使用任意數(shù)量的屬性。要考慮需要添加到文檔的細(xì)節(jié)。如果要對(duì)文檔分類,屬性尤其有用,比如按照菜譜的 type 進(jìn)行分類。屬性名可以包含在元素名中使用的字符,規(guī)則也是類似的,即字符之間不能帶有空格,名稱只能以字母開始。
#p#
構(gòu)造良好并且有效的 XML
如果您根據(jù)結(jié)構(gòu)規(guī)則創(chuàng)建 XML,就很容易實(shí)現(xiàn)構(gòu)造良好的 XML。構(gòu)造良好的 XML 即遵循所有 XML 規(guī)則創(chuàng)建的 XML:正確的元素命名,嵌套,屬性命名等等。
要實(shí)現(xiàn)構(gòu)造良好的 XML 取決于如何處理 XML。但考慮一下前面提到的示例,它要求根據(jù)菜譜類型進(jìn)行分類。您需要確保每個(gè) ﹤recipe﹥ 元素都包含 type 屬性,以對(duì)菜譜進(jìn)行分類。能夠正確驗(yàn)證并確保存在屬性值是非常重要的(避免出現(xiàn)雙關(guān)語(yǔ))。
驗(yàn)證 就是根據(jù)元素規(guī)則檢查文檔的結(jié)構(gòu),以及如何為每個(gè)父元素定義子元素。這些規(guī)則是在 文檔類型定義(Document Type Definition,DTD)或模式(schema )中定義的。驗(yàn)證要求您創(chuàng)建自己的 DTD 或 schema ,然后在 XML 文件中引用 DTD 或 schema 文件。
為了實(shí)現(xiàn)驗(yàn)證,必須在 XML 文檔的頂部附近包含文檔類型(DOCTYPE)。這行代碼將引用用于驗(yàn)證文檔的 DTD 或 schema (元素和規(guī)則列表)。例如,DOCTYPE 可能類似于 清單 5。
清單 5. DOCTYPE
﹤!DOCTYPE MyDocs SYSTEM "filename.dtd"﹥
這個(gè)例子假設(shè)元素列表文件的名稱是 filename.dtd,并且位于您的計(jì)算機(jī)上(如果指向公共文件位置,則 SYSTEM 和 PUBLIC 是相對(duì)的)。
使用實(shí)體
實(shí)體 可以是文本短語(yǔ)或特殊字符。它們可以指向內(nèi)部或外部。必須正確地聲明和表示實(shí)體,以避免錯(cuò)誤和確保正確顯示。
您不能直接在內(nèi)容中輸入特殊字符。如果要在文本中使用符號(hào),必須使用它的字符代碼將它設(shè)置為實(shí)體。您可以將短語(yǔ)(比如公司名)設(shè)置為實(shí)體,然后就可以在內(nèi)容中使用該實(shí)體。為了設(shè)置實(shí)體,必須先為它創(chuàng)建一個(gè)名稱,然后將它輸入到內(nèi)容中,以 and 符號(hào)(&)開始,并以分號(hào)(;)結(jié)束 — 例如,&coname;。然后在 DOCTYPE 的方括號(hào)([])內(nèi)部輸入代碼,如 清單 6 所示。這個(gè)代碼識(shí)別表示實(shí)體的文本。
清單 6. ENTITY
﹤!DOCTYPE MyDocs SYSTEM "filename.dtd" [ ﹤!ENTITY coname
"Rabid Turtle
Industries"
]﹥
使用實(shí)體可以避免反復(fù)輸入相同的短語(yǔ)和信息。在很多情況下它還使得調(diào)整文本更加容易(變更公司名時(shí)),只需對(duì)實(shí)體定義進(jìn)行簡(jiǎn)單調(diào)整。
避免錯(cuò)誤
在學(xué)習(xí)創(chuàng)建 XML 文件時(shí),在 XML 編輯器中打開它,以檢查它的結(jié)構(gòu)是否良好,并且確保您遵循 XML 規(guī)則。例如,如果您使用 Windows® Internet Explorer®,就可以在瀏覽器中打開 XML。如果它能夠顯示 XML 元素、屬性和內(nèi)容,則表明 XML 是構(gòu)造良好的。相反,如果顯示錯(cuò)誤,則很可能是出現(xiàn)語(yǔ)法錯(cuò)誤,您需要小心檢查文檔,看看是不是丟失標(biāo)記和標(biāo)點(diǎn)符號(hào)或輸入錯(cuò)誤。
如在 嵌套元素 小節(jié)中提到的一樣,包含其他元素的元素就是被包含元素的父元素。在下面的示例中,﹤recipe﹥ 是根元素,并且包含文件的完整內(nèi)容。父元素 ﹤recipe﹥ 包含的子元素有 ﹤recipename﹥、﹤ingredlist﹥、﹤directions﹥ 等等。在這種結(jié)構(gòu)中,﹤recipename﹥、﹤ingredlist﹥ 和 ﹤directions﹥ 成了同胞元素。此外,還要正確嵌套同胞 元素。清單 7 給出了構(gòu)造良好并且正確嵌套的 XML。
清單 7. 構(gòu)造良好的 XML
﹤?xml version="1.0" encoding="UTF-8"?﹥
﹤recipe type="dessert"﹥
﹤recipename cuisine="american" servings="1"﹥Ice
Cream Sundae﹤/recipename﹥
﹤ingredlist﹥
﹤listitem﹥﹤quantity units="cups"﹥0.5﹤/quantity﹥
﹤itemdescription﹥vanilla ice cream﹤/itemdescription﹥﹤/listitem﹥
﹤listitem﹥﹤quantity units="tablespoons"﹥3﹤/quantity﹥
﹤itemdescription﹥chocolate syrup or chocolate fudge﹤/itemdescription﹥﹤/listitem﹥
﹤listitem﹥﹤quantity units="tablespoons"﹥1﹤/quantity﹥
﹤itemdescription﹥nuts﹤/itemdescription﹥﹤/listitem﹥
﹤listitem﹥﹤quantity units="each"﹥1﹤/quantity﹥
﹤itemdescription﹥cherry﹤/itemdescription﹥﹤/listitem﹥
﹤/ingredlist﹥
﹤utensils﹥
﹤listitem﹥﹤quantity units="each"﹥1﹤/quantity﹥
﹤utensilname﹥bowl﹤/utensilname﹥﹤/listitem﹥
﹤listitem﹥﹤quantity units="each"﹥1﹤/quantity﹥
﹤utensilname﹥spoons﹤/utensilname﹥﹤/listitem﹥
﹤listitem﹥﹤quantity units="each"﹥1﹤/quantity﹥
﹤utensilname﹥ice cream scoop﹤/utensilname﹥﹤/listitem﹥
﹤/utensils﹥
﹤directions﹥
﹤step﹥Using ice cream scoop, place vanilla ice cream into bowl.﹤/step﹥
﹤step﹥Drizzle chocolate syrup or chocolate fudge over the ice cream.﹤/step﹥
﹤step﹥Sprinkle nuts over the mound of chocolate and ice cream.﹤/step﹥
﹤step﹥Place cherry on top of mound with stem pointing upward.﹤/step﹥
﹤step﹥Serve.﹤/step﹥
﹤/directions﹥
﹤variations﹥
﹤option﹥Replace nuts with raisins.﹤/option﹥
﹤option﹥Use chocolate ice cream instead of vanilla ice cream.﹤/option﹥
﹤/variations﹥
﹤preptime﹥5 minutes﹤/preptime﹥
﹤/recipe﹥
注意:換行符方便您閱讀代碼,它不會(huì)影響 XML。
您可以在測(cè)試文件上進(jìn)行實(shí)踐,去掉開始和結(jié)束標(biāo)記,熟悉因此顯示的錯(cuò)誤消息。
查看 XML
在 圖 1 中,Internet Explorer 清晰顯示了所有元素。內(nèi)容包含在開始和結(jié)束標(biāo)記之間。父元素旁邊有小加號(hào)(+)和小減號(hào)(-),它們?cè)试S您展開或收縮嵌套在內(nèi)部的所有元素(它們的后代)。
圖 1. 收縮了一些同胞元素的示例 XML 實(shí)例(文件)
結(jié)束語(yǔ)
除了一些簡(jiǎn)單的規(guī)則之外,您可以隨意設(shè)計(jì) XML 元素和屬性。XML 的規(guī)則并不難。真正困難的是 根據(jù)可分類性和可搜索性找出文檔中有價(jià)值的內(nèi)容,然后根據(jù)您的需要設(shè)計(jì)元素和屬性。
當(dāng)您有了明確的目標(biāo),并知道如何標(biāo)記內(nèi)容的時(shí)候,您可以構(gòu)建高效的元素和屬性了。從這個(gè)角度看,小心進(jìn)行標(biāo)記是創(chuàng)建構(gòu)造良好并且有效的 XML 的根本條件。
【編輯推薦】