Elliotte Rusty Harold, 副教授, Polytechnic University
2006 年 5 月 15 日
惟一標(biāo)識(shí)符
用于 blog 和其他連鎖提要的 Atom XML 格式要求每個(gè)記錄都有一個(gè)惟一的 ID,該 ID 放在 id 元素中。Atom 要求這個(gè) ID 必須是語(yǔ)法正確的 URI。它還要求,這個(gè) ID 不僅在出現(xiàn)的文檔中是惟一的,而且在任何時(shí)候、在所有文檔、所有服務(wù)器上都必須是全局惟一的。這是非常高的要求。但這是必須的,因?yàn)?Atom 提要經(jīng)常被分成片然后被其他網(wǎng)站如 Bloglines 重新發(fā)布,通過(guò)聚合程序和 Vienna 填充來(lái)自其他站點(diǎn)的內(nèi)容。比如,在這個(gè)實(shí)際的記錄中,ID 值是非常笨拙的 http://www.cafeaulait.org/?tag=http___eclipse.org_aspectj#news2005December21:
清單 1. Atom 條目的例子
<entry>
<title>The Eclipse Project has released AspectJ 5.0.</title>
<content type="xhtml">
<div xmlns="http://www.w3.org/1999/xhtml">
<p>
The Eclipse Project has released
<a href="http://eclipse.org/aspectj">AspectJ</a> 5.0.
AspectJ is a derivative of Java that allows
programmers to write code that applies across multiple classes.
The AspectJ compiler requires Java 1.3, but can generate code for Java
1.1 and later. "This release constitutes a full-upgrade of AspectJ to
support Java 5, while also delivering a large number of quality
improvements that will benefit users running on JDK 1.4 or below. In
addition to the Java 5 related language changes, AspectJ 5 also
supports an @AspectJ style of aspect declaration, greatly enhanced
load-time weaving capabilities, a full reflection API, and tools APIs
for parts of the weaver."
</p>
</div>
</content>
<link href="#news2005December21"/>
<id>http://www.cafeaulait.org/?tag=
http___eclipse.org_aspectj#news2005December21</id>
<updated>2005-12-21T09:00:01-05:00</updated>
</entry>
|
(實(shí)際上,真正的 ID 更長(zhǎng)更難看,為了適應(yīng)本頁(yè),需要對(duì)其寬度進(jìn)行裁減。)
其中一開(kāi)始是提取 Atom 提要的網(wǎng)頁(yè) URL http://www.cafeaulait.org/。接下來(lái)的查詢(xún)字符串增加了一個(gè)參數(shù) tag。首先要將記錄中引用的所有 URL 連接起來(lái),然后用下劃線替換全部 URL 保留字符(如冒號(hào)),這樣就形成了參數(shù)的值,從而可以區(qū)分同一頁(yè)面中不同條目。最后,再增加上日期作為片段標(biāo)識(shí)符,以便在包含同一組 URL 的情況下加以區(qū)分。盡管這種 ID 又臭又長(zhǎng)而且難以閱讀,但確實(shí)可以保證惟一性。
Atom 并不是要求使用全球惟一 URI 標(biāo)識(shí)符的惟一一種協(xié)議。RDF、OWL 和語(yǔ)義 Web 都假設(shè)可以將 URI 賦予任何項(xiàng) —— 不僅僅是網(wǎng)頁(yè),還可以包括人、寵物、星球、草履蟲(chóng)、DNA 序列、醫(yī)療診斷、日期以及您能夠想象的任何東西。要讓語(yǔ)義 Web 有效,就必須保證不能用同一個(gè) URI 標(biāo)識(shí)布魯托(迪斯尼動(dòng)畫(huà)中的寵物狗)和冥王星(Pluto)。
您會(huì)發(fā)現(xiàn)很多上下文中都使用 URI 作為標(biāo)識(shí)符,包括 SAX 特性和屬性名、XML 名稱(chēng)空間、RDDL 性質(zhì)和目標(biāo)、XML 數(shù)字簽名算法、SVG 特性字符串,等等。
所有 URL 都是 URI,前面例子中所示的 HTTP URL 完全可以作為標(biāo)識(shí)符。使用 URL 作為標(biāo)識(shí)符的問(wèn)題在于用戶認(rèn)為能夠打開(kāi) HTTP URL。即便出現(xiàn)在 Atom 提要文檔中的 URL 不是供人類(lèi)使用的,人們?nèi)匀粫?huì)將其輸入到 Web 瀏覽器中。用 XML 大師 Claude L. Bullard 的不朽名言來(lái)說(shuō):
對(duì) URN/URI/URL 的所有吹捧都無(wú)法避免一個(gè)簡(jiǎn)單的事實(shí),如果有人將 http:// 放到瀏覽器顯示區(qū)域的某個(gè)地方,系統(tǒng)用藍(lán)色顯示它,并且當(dāng)鼠標(biāo)移到上面時(shí)指針會(huì)變成手的形狀。人們希望查看某個(gè)資源,如果沒(méi)有找到,人們就會(huì)手足無(wú)措。人們沒(méi)有閱讀規(guī)范來(lái)發(fā)現(xiàn)為何會(huì)受到震驚,他們只是漲紅了臉,把手放在臉上。
除了讓用戶感到討厭以外,在文檔中加入不能解析的 HTTP URL 時(shí),常常因?yàn)槟J(rèn)為沒(méi)有人會(huì)注意到的 URL 而導(dǎo)致服務(wù)器日志中寫(xiě)滿了 404 錯(cuò)誤。即使用戶沒(méi)有發(fā)現(xiàn)它們,某個(gè)斷鏈機(jī)器人也會(huì)發(fā)現(xiàn)它們。因此,建立與 HTTP URL 不同的純粹用于標(biāo)識(shí)的 URI 方案很有必要。于是就出現(xiàn)了標(biāo)簽 URI。
標(biāo)簽語(yǔ)法
在不使用某種形式的集中式注冊(cè)系統(tǒng)來(lái)避免沖突的情況下定義全球惟一標(biāo)識(shí)符是不可能的。但是這類(lèi)注冊(cè)系統(tǒng)只要有一個(gè)就行了,而且幸運(yùn)的是,已經(jīng)存在一個(gè)幾乎每個(gè)使用計(jì)算機(jī)的人都參與的注冊(cè)系統(tǒng):域名系統(tǒng)。與 XML 名稱(chēng)空間以及 Java 包名稱(chēng)類(lèi)似,標(biāo)簽 URI 和 DNS 來(lái)確保惟一性。每個(gè)標(biāo)簽 URI 都包括域名或者電子郵件地址。
域名可能出售、過(guò)期、被搶或者盜竊,因此 URI 中還要包含日期。任何時(shí)候應(yīng)該不會(huì)有多個(gè)人或組織同時(shí)擁有給定的域名或電子郵件地址。
最后在 URI 后面添加一個(gè)任意字符串,這樣一個(gè)人在一天之內(nèi)就可以創(chuàng)建任意數(shù)量的標(biāo)簽 URI。下面是少數(shù)標(biāo)簽 URI 的例子:
- tag:elharo@ibiblio.org,2006:javafaq/slides
- tag:elharo@ibiblio.org,2005-12:Elliotte
- tag:elharo.com,2006-01-25:ElliotteHarold:presentations:Javapolis2005-12-14
- tag:elharo.com,2005:double
用 URI 的術(shù)語(yǔ)來(lái)說(shuō),這些都是不透明的 URI,就是說(shuō)沒(méi)有采用 HTTP、HTTPS、文件和 FTP URL 中使用的層次系統(tǒng)。但是它們也有自己明確的結(jié)構(gòu)。具體來(lái)說(shuō),每個(gè) URI 都由用冒號(hào)分隔的三部分組成:
方案:標(biāo)簽實(shí)體:特定標(biāo)識(shí)符
方案必須是 tag。非常簡(jiǎn)單。雖然 URI 方案對(duì)大小寫(xiě)不敏感,但是標(biāo)簽 RFC(請(qǐng)參閱參考資料)建議采用小寫(xiě)形式。
特定標(biāo)識(shí)符是可選的。如果包含特定標(biāo)識(shí)符,則可以包含 URI 語(yǔ)法限制范圍內(nèi)許可的任何內(nèi)容。簡(jiǎn)言之,也就是說(shuō)允許包含 ASCII 字母數(shù)字和少數(shù)標(biāo)點(diǎn)符號(hào),但是不能有空格、保留字符 [如冒號(hào)(:)和反斜杠(/)] 以及非 ASCII 字符。特定標(biāo)識(shí)符沒(méi)有特殊的含義?梢源鎯(chǔ)任何有用的東西,但是應(yīng)該盡量使其富有意義并淺顯易懂。也就是說(shuō)應(yīng)避免使用“sr_8_xs_ap_i2_xgl14”(一個(gè)大型電子商業(yè)網(wǎng)站中實(shí)際使用的 URL)這樣的 URI。標(biāo)簽 RFC 建議用實(shí)際的單詞組成字符串。
關(guān)鍵是標(biāo)簽實(shí)體。這部分保證了惟一性。標(biāo)簽實(shí)體是基于域名的。但是因?yàn)橛蛎锌赡艿故,因此加上了日期成分。比如,?shí)體 macfaq.com,2005 指的是在 2005 年擁有域名 macfaq.com 的個(gè)人或組織。如果 2006 年這個(gè)域換了主人,那么 macfaq.com,2006 指的就是新的所有者,而以前的所有者仍然使用 macfaq.com,2005。如果這一年中域名又換了人,還可以增加月份和日期,中間用連字符分開(kāi)。(這是 ISO 8601 定義并被 W3C 采納的慣用日期格式。)比如, macfaq.com,2005-12-21 指的是 2005 年 12 月 21 日擁有 macfaq.com 的實(shí)體。
 |
標(biāo)簽的相等比較
一種觀點(diǎn)認(rèn)為,應(yīng)該用一般的 URL 解釋方法來(lái)區(qū)分標(biāo)簽:只有逐個(gè)字符對(duì)應(yīng)相等時(shí)才認(rèn)為兩個(gè)標(biāo)簽相同。即使對(duì)固定的方案部分 tag 也不執(zhí)行大小寫(xiě)轉(zhuǎn)換?梢允褂冒俜?jǐn)?shù)編碼,但是不能解析。比如,tag:elharo@ibiblio.org,2006:javafaq/slides、TAG:elharo@ibiblio.org,2006:javafaq/slides 和 tag:elharo%40ibiblio.org,2006:javafaq/slides 被看作是三個(gè)不同的 URI。
|
|
所有年份都是用四位數(shù),日期和月份使用兩位數(shù)。比如,要?jiǎng)?chuàng)建 2006 年新年這一天的標(biāo)簽 URI,就要用 macfaq.com,2006-01-01 而不是 macfaq.com,06-1-1。日期不一定是創(chuàng)建 URI 的那一天,但通常如此。也可選擇過(guò)去的某一天,只要當(dāng)時(shí)您擁有這個(gè)域。但是不應(yīng)建立包含未來(lái)日期的標(biāo)簽 URI,因?yàn)橛蛎螂娮余]件地址的所有權(quán)有可能意外地發(fā)生改變。
雖然可以在標(biāo)簽實(shí)體中增加時(shí)間成分,但不鼓勵(lì)這么做, 因?yàn)椴煌瑫r(shí)區(qū)可能造成重疊和沖突。如果域名真的換了主人,最好在交割前后 48 小時(shí)以外分配標(biāo)簽 URI,以免出現(xiàn)所有權(quán)的紛爭(zhēng)。
并非每個(gè)人都有個(gè)人域名,但是大部分有電子郵件地址。如果沒(méi)有域名,或者公司很大,在部門(mén)和分支機(jī)構(gòu)中決定 URI 的用戶很難,可以使用完整的電子郵件地址代替,比如:tag:elharo@ibiblio.org,2006:javafaq/slides。這種情況下,標(biāo)簽實(shí)體就是 2006 年電子郵件地址 elharo@ibiblio.org 的所有者,而不是 2006 年擁有 ibiblio.org 域名的人或組織。
結(jié)束語(yǔ)
標(biāo)簽 URI 最終實(shí)現(xiàn)了 URI 要達(dá)到的目標(biāo):標(biāo)識(shí)而不附加要求其本身沒(méi)有的定位或者行為信息。它們?nèi)菀讋?chuàng)建、易于閱讀、能使用現(xiàn)有系統(tǒng)、是開(kāi)放標(biāo)準(zhǔn),并且沒(méi)有任何向后兼容問(wèn)題。有什么不好的地方?
建議使用 HTTP URL 而不是標(biāo)簽 URI 的惟一情況就是就是準(zhǔn)備在 URL 的另一端放上一個(gè)頁(yè)面,無(wú)論現(xiàn)在還是將來(lái)。HTTP URL 都可以做到。標(biāo)簽 URI 則不能。但是,用作標(biāo)識(shí)符(而不是定位符)的大部分 HTTP URL 在插入瀏覽器的時(shí)候會(huì)產(chǎn)生 404 Not Found 錯(cuò)誤。如果不想在 URL 的另一端放上頁(yè)面,則應(yīng)使用標(biāo)簽 URI 而不是 HTTP URL。