CTO, Blue Oxide Technologies,LLC
2003 年 1 月
Kevin Williams 研究了 XPath 2.0 規(guī)范的最新?tīng)顟B(tài),并且提供了一些 XPath 2.0 特性的特定示例,這些特性會(huì)使 XML 開(kāi)發(fā)人員的工作更加輕松。示例是用 XML 和 XPath 的形式提供的。
XSLT 1.0 和 XPath 1.0 最初是打算為 XML 文檔提供簡(jiǎn)單的樣式語(yǔ)言支持,主要是將這些文檔轉(zhuǎn)換成 HTML 以呈現(xiàn)在瀏覽器中。但是,自從 XSLT 和 XPath 可以使用之后,它們就被強(qiáng)行用于各種任務(wù)中,而這些任務(wù) ― 從 XML 文檔中復(fù)雜的數(shù)據(jù)操作(聚合、單值選擇和關(guān)系旋轉(zhuǎn))到一種 XML 形式向另一種形式的 XSLT 轉(zhuǎn)換 ― 并不是它們的設(shè)計(jì)初衷。在這些規(guī)范的版本 2.0 中,W3C 試圖使 XSLT 和 XPath 更加靈活和健壯,以便于處理這些技術(shù)的新用法。
在上一篇專(zhuān)欄文章中,我研究了 XSLT 的一些新特性。在本篇專(zhuān)欄文章中,我只研究 XPath2.0 的幾個(gè)要點(diǎn) ― 由于要點(diǎn)太多,因而無(wú)法在一篇專(zhuān)欄文章中全部研究。
對(duì)于本專(zhuān)欄而言,特定前綴的映射含義如下:
xf:
前綴被認(rèn)為映射到 XPath 2.0 函數(shù)名稱(chēng)空間(http://www.w3.org/2002/08/xquery-functions)。 xsl:
前綴映射到 XSLT 2.0 名稱(chēng)空間。 xs:
前綴映射到 XML 模式名稱(chēng)空間。 xf:distinct-values 函數(shù)
在使用 XSLT 1.0 樣式表時(shí),開(kāi)發(fā)人員面臨的最重大的挑戰(zhàn)之一就是編寫(xiě)與 SQL 中 SELECT DISTINCT 等同功能的 XML 代碼 ― 即一個(gè)獲取節(jié)點(diǎn)集并返回那些節(jié)點(diǎn)唯一值列表的表達(dá)式。在 XSLT 1.0 和 XPath 1.0 中這不是不可能實(shí)現(xiàn)的,但都是極其困難的?;旧?,您都必須寫(xiě)一條 xsl:for-each
語(yǔ)句以特殊的排序順序?qū)γ總€(gè)節(jié)點(diǎn)求值,然后不斷回頭查看節(jié)點(diǎn)列表,以了解是否所有匹配特定值的任何其它節(jié)點(diǎn)都被處理了。有了 XSLT 2.0 ,以及引入了 xf:distinct-values
函數(shù),這個(gè)問(wèn)題就迎刃而解了。下面 清單 1中是一個(gè) XML 文檔的快速示例:
|
假定您想要標(biāo)準(zhǔn)化輸出作者信息,并創(chuàng)建一個(gè)類(lèi)似 清單 2的文檔:
清單 2. 帶有書(shū)名的 authors
|
要做到這一點(diǎn),使用 XPath 和 XSLT 1.0 時(shí),需要做類(lèi)似于 清單 3的工作:
清單 3. XPath 1.0 中的 SELECT DISTINCT
|
記錄文檔的過(guò)程稍微有點(diǎn)凌亂和困難,但是使用 xf:distinct
,這會(huì)變的很容易,如 清單 4所示:
|
這與 xsl:for-each-group
有什么區(qū)別呢?任何實(shí)現(xiàn) XPath 的地方都可以使用 xf:distinct
― 因此,它可以作為 XQuery 1.0 的一部分及專(zhuān)門(mén)的 XPath 處理器使用。利用 xf:distinct
,可以在值集合上執(zhí)行其它操作,這與 xsl:for-each-group
相反,后者強(qiáng)制對(duì)不同的值單獨(dú)進(jìn)行操作。
這一變化解決了 XSLT 作者在試圖樣式化文檔時(shí)遇到的許多問(wèn)題。XSLT 還有許多其它變化,樣式表程序員會(huì)發(fā)現(xiàn)它們非常有用。
xf:document 函數(shù)
在 XSLT 1.0 中使用多個(gè)文檔是有問(wèn)題的。XPath 2.0 的設(shè)計(jì)人員明智地選擇了通過(guò) xf:document
機(jī)制來(lái)包括額外的文檔處理能力。該函數(shù)允許從 URL 裝入一個(gè)或多個(gè)文檔,并進(jìn)行處理。例如,假定您在資源庫(kù)中擁有 清單 5、6 和 7中所示的文檔類(lèi)型:
|
|
|
假定您現(xiàn)在在一個(gè)目錄中有 500 個(gè)這樣的文檔,您希望創(chuàng)建您所擁有的所有藍(lán)色零件的列表。無(wú)需利用中間層語(yǔ)言(如 Java)編寫(xiě)代碼以裝入所有這些文檔并查找顏色為藍(lán)色的零件,可以編寫(xiě)一個(gè)列出在哪可以找到所有零件的索引(請(qǐng)參閱 清單 8):
清單 8. 零件索引文檔
|
您可以編寫(xiě)一個(gè)為您完成這項(xiàng)工作的樣式表,其代碼片段類(lèi)似于 清單 9:
清單 9. 用于跨文檔的 xf:document
|
這種技術(shù)特別適用于分布式網(wǎng)絡(luò)的內(nèi)容,在分布式網(wǎng)絡(luò)中,零件信息可以放在一臺(tái)服務(wù)器上,而客戶(hù)信息可以放在另一臺(tái)服務(wù)器上。通過(guò)利用樣式表(使用 xf:document
從其它 URL“拉”信息),允許該數(shù)據(jù)可以在創(chuàng)建它的地方起作用。
xf:current-dateTime 函數(shù)
將樣式表應(yīng)用于 XML 文檔時(shí),在輸出中包含已轉(zhuǎn)換結(jié)果的創(chuàng)建日期通常都很有用。當(dāng)創(chuàng)建 HTML 文檔以驅(qū)動(dòng)用戶(hù)界面時(shí),這特別重要;此類(lèi)信息可以幫助高速緩存系統(tǒng)知道什么時(shí)候信息的副本失效了。使用 XPath 2.0 中的 xf:current-dateTime
函數(shù)可以獲得當(dāng)前日期和時(shí)間(請(qǐng)參閱 清單 10):
|
這可能會(huì)返回 清單 11中所示的字符串:
清單 11. xf:current-dateTime 樣本結(jié)果
|
然后,可以“按現(xiàn)狀”使用該字符串,或者將其轉(zhuǎn)換成不同的日期格式,以便于在生成的文檔中使用。
更佳的 XML 模式兼容性
因?yàn)?XPath 2.0 目前在 XSLT 2.0 和 XQuery 1.0 之間共享,因此,XPath 需要更健壯的 XML 模式支持。實(shí)際上,XPath 2.0 中的整個(gè)數(shù)據(jù)模型目前都是強(qiáng)類(lèi)型的:而不是簡(jiǎn)單的字符串、數(shù)字和布爾類(lèi)型,值目前使用了作為 XML 模式規(guī)范一部分定義的原語(yǔ)。提供了完整的函數(shù)集,因此可以把這些值顯式地從一種類(lèi)型轉(zhuǎn)換為另一種類(lèi)型,將這種轉(zhuǎn)換作為它們?cè)?XPath 2.0 中操作的一部分。例如,通過(guò)使用類(lèi)型名稱(chēng)可以將一個(gè)值強(qiáng)制轉(zhuǎn)換為另一種類(lèi)型,就象是一個(gè)函數(shù)一樣。因此,使用 清單 12中的代碼片段,可以將值強(qiáng)制轉(zhuǎn)換為無(wú)符號(hào)整數(shù):
|
XPath 2.0 中的強(qiáng)類(lèi)型確保由 XSLT 樣式表創(chuàng)建的文檔能夠依據(jù)強(qiáng)類(lèi)型的 XML 模式進(jìn)行驗(yàn)證。在 XSLT 2.0 之前,沒(méi)有方法可以保證這一點(diǎn)(例如,保證數(shù)字是無(wú)符號(hào)整數(shù))― 為了確保樣式表不提供錯(cuò)誤值,XML 模式驗(yàn)證步驟是必需的。
在本文中,我只是略微談及了 XPath 2.0 必須提供的一些要點(diǎn)。雖然距離這項(xiàng)技術(shù)提升為建議書(shū)狀態(tài)還有一段時(shí)日(至少 6 個(gè)月),但是,熟悉 XPath 2.0 的特性和功能將有助于您在開(kāi)始實(shí)現(xiàn)時(shí)能夠充分利用它。
關(guān)于作者 Kevin Williams Blue Oxide Technologies,LLC 的技術(shù)主管(CTO),該公司從事 XML 和 XML Web 服務(wù)設(shè)計(jì)軟件的設(shè)計(jì)業(yè)務(wù)。請(qǐng)?jiān)L問(wèn)該公司的網(wǎng)站 http://www.blueoxide.com。可以通過(guò) kevin@blueoxide.com向 Kevin 提出意見(jiàn)。 |
聯(lián)系客服