用於資料的 XML: XSL 樣式表:推還是拉? (轉)

worldblog發表於2007-12-13
用於資料的 XML: XSL 樣式表:推還是拉? (轉)[@more@]

 
用於資料的 : 樣式表:推還是拉? 
英文原文 
 
 
 
內容:
 
推樣式表
 
拉樣式表
 
因此,拉總是比推好,對嗎?
 
結束語
 
參考資料
 
關於作者
 
對本文的評價
 
 
 
相關內容:
 
訂閱 developerWorks 時事通訊
 
 
 
 
在 XML 專區還有:
 
教程
 
工具和產品
 
程式碼與
 
文章
 
 
 
 
 
 
 
檢視兩種 XSL 樣式表的製作技術以及如何將其綜合用於資料

Kevin Williams(to:kevin@blueox.com">kevin@blueoxide.com)
CEO,Blue Oxide Technologies,LLC
2002 年 5 月

專欄作家 Kevin Williams 研究了用於建立 XSL 樣式表的兩種最常見的製作樣式:推(push)和拉(pull)。他研究了一些簡單的 XML 和 XSL 示例,並討論了每種方法的優缺點。
當製作 XSL 樣式表時,可以使用這兩種主要製作樣式中的任何一種:

推 樣式是由在輸出文件中建立輸出的處理構造的。輸出基於源文件中遇到的元素型別。元素內容被推 給適當的處理程式。
另一方面,拉 樣式根據需要透過拉出 源文件中的內容來構建輸出文件。

您所選擇的樣式對樣式表的程式碼複雜性和可維護性具有重要的影響。

推樣式表
推樣式表是樣式表的經典形式。所有主要的 XSL 生成工具都可以生成推樣式表,它們是 XSL 參考資料中通常討論的形式。這種格式的樣式表由一系列 xsl:template 元素組成,每個元素處理文件中的一個特定元素型別。例如,假設您有下列源文件:

清單 1. 樣本資料文件


 
  Kevin Williams
 

100 Nowhere Lane

  Nowheresville
  VA
  24182
 
  E38-19273
  3-inch Grommets
  37
  37.00
 

 
  E22-18272
  2-inch Widgets
  22
  11.00
 

 
 
  John Public
 
200 Anywhere Street

  Anytown
  VA
  24177
 
  E22-18272
  2-inch Widgets
  27
  13.50
 

 
  E19-28376
  1-inch Bolts
  16
  4.00
 

 

 


現在,假設您要將其轉換成下面的 文件:

清單 2. 樣本資料輸出

 


 

Kevin Williams


 

100 Nowhere Lane

  Nowheresville, VA 24182


 
 
 
 
 
 
 
 
 
 
 
 
 
 
DescriptionCost
3-inch Grommets37.00
2-inch Widgets11.00

 


 

John Public


 

200 Anywhere Street

  Anytown, VA 24177


 
 
 
 
 
 
 
 
 
 
 
 
 
 
DescriptionCost
2-inch Widgets13.50
1-inch Bolts4.00

 

 


需要在樣式表中建立一系列模板。這些模板處理您要帶入輸出文件的每個不同元素。每個模板還必須建立支援的 XHTML 元素結構,例如表標題和行。使用推方法從源文件(清單 1)建立清單 2 中所示的輸出的樣式表類似於下面的樣子:

清單 3. 用於資料的樣本推樣式表
  version="1.0">
 
 
 
 
 
 
 
 
 
 
 
 

 


請注意:有兩個令人感興趣的新增項,您應當將它們包括在樣式表中:

最後的空模板確保從輸出文件中省去多餘內容(如發票上專案的單價)。
以文件次序處理其所有子元素的模板確保處理自始至終都沿著源樹進行。那樣,您不會僅因為沒有特定的發票模板而丟失任何發票內容。

正如您看到的那樣,這種結構有點臃腫。雖然製作程式碼是非常簡單的,但維護程式碼是棘手的。即使對於這個十分簡單的示例,如果您要查明 XHTML 表是如何填充的,那麼就必須從一個模板跳到另一個模板來發現 td 的建立位置。在更復雜的示例中,可能會有許多頁的模板,許多模板都是從其它模板的。程式碼的維護也更困難。

拉樣式表
另一方面,拉樣式表依靠編碼者的能力來知道接下來期望源文件中的哪些元素出現。透過重複元素、在輸出中建立適當的結構以及根據需要從源文件中拉出值,程式碼可以顯式地進行迴圈處理。這裡是一個與清單 2 相同轉換的樣式表,但它使用拉策略,而不是推策略:

清單 4. 用於資料的樣本拉樣式表
  version="1.0">
 

 


在這種形式的樣式表中,您只有一個模板,它對應於您正在嘗試檢索的資訊的根。嵌在源文件中的巢狀資訊是透過使用 xsl:for-each 元素處理當前特定型別的節點的所有子節點來檢索的。正如您可看到的那樣,這種樣式表非常易於讀取。它比推形式的樣式表短,其佈局與期望的輸出文件佈局非常接近。當用拉形式編碼時,只要採用期望的輸出樣本,將其新增到頂級模板。然後,可以用適當的程式碼替換該樣本中的值來檢索源文件的值。

因此,拉總是比推好,對嗎?
儘管拉格式的確優於推格式(可讀性、簡潔且易於讀取的佈局),但您還是應該根據源文件的特徵來選擇樣式表。請檢視下面的結構示例,它包含描述一個虛構醫療過程的敘述:

清單 5. 樣本敘述文件

 
 

First, the surgeon used the 3-inch
  scalpel
to make a two-inch incision
  in the patient's lower left aben.
  Cautery was then applied to the
  severed blood vessels to stop the
  bleeding.

 
The surgeon then cleaned and
  dressed the incision
, using four two-by-two
  sterile gauze pads
and medium sutures.

 

 


在這個敘述中,資訊可能會以任何次序出現。文件中的一行可能有兩條 tool 子句,後面跟了一條 procedure 子句,或者三條 location 子句。假設您想要產生與下面相似的輸出:

清單 6. 樣本敘述輸出

 


 

Surgery Log


 

13:00:00


 

First, the surgeon used the 3-inch scalpel to make a
  two-inch incision in the patient's
  lower left  abdomen. Cautery was
  then applied to the severed blood vessels to stop the bleeding.


 

13:14:23


 

The surgeon then cleaned and dressed
  the incision
, using four two-by-two sterile gauze pads
  and medium sutures.
 

 


有關樣式表推格式的一件很重要的事,就是資訊的出現次序是沒有關係的。下面的樣式表將清單 5 中的源 XML 處理成期望的 XHTML:

清單 7. 敘述的樣本推樣式表
  version="1.0">
 
 
 
 

 


請注意:因為模板是以正確的次序自動處理的,所以巢狀項是怎麼樣的不是現在主要關心的問題。您可以處理更復雜的情形,如清單 8 中的情形,其中,procedure 元素包含了一個 tool 元素:

清單 8. 帶巢狀元素的樣本敘述

 
 

First, the surgeon used the
  3-inch scalpel to make a two-inch incision

  in the patient's lower left abdomen.
  Cautery was then applied to the
  severed blood vessels to stop the
  bleeding.

 
The surgeon then cleaned and
  dressed the incision
, using four two-by-two
  sterile gauze pads
and medium sutures.

 

 


當將樣式表應用於該源文件時,結果正如期望的那樣:嵌在過程中的工具是斜體並且是橙色的。現在,請看一下用拉樣式建立的相同樣式表:

清單 9. 敘述的樣本拉樣式表
  version="1.0">
 

 


請注意這個拉樣式表多麼臃腫。您不得不檢查每個節點,並且 — 如果該節點需要特殊處理 — 為其新增適當的格式。這個樣式表甚至不能處理清單 8 中引述的複雜情形。該程式碼忽略了過程(procedure)標記內的工具(tool)標記。如果您擴充套件了樣式表以正確處理所有可能的工具、目標、過程等巢狀,那麼樣式表會迅速膨脹至一個難以控制的(且不可維護的)大小。

結束語
這些示例演示了我在我的大多數專欄中得出的要點:資料文件與敘述有本質區別,因為:

資料文件中的資訊以可在程式碼中預料的次序出現。
資料文件中不包含鬆散文字,因此,將該文字轉換成輸出文件無需專門的程式碼。

比起重新命名元素、對它們進行重新排序並在目標樹中將它們向上聚合一個級別(或將它們向下推至一個更詳細的級別),將源資料文件對映為輸出文件並不複雜。如果您使用拉模型,對映很簡單且易於維護。

另一方面,基於敘述的文件則完全相反。

資訊以不能輕易預見的次序出現。
一些文字遊離於元素的上下文之外,所以需要將它正確地移到輸出文件。

為了在輸出文件中準確地重現敘述,不管元素出現在哪裡,樣式表都必須處理它們,而推模型在這一方面比較擅長。

簡而言之,當設計資料文件的樣式表時,首先考慮使用拉模型。對於敘述文件,如果可能,請使用推模型。精通於編寫這兩種樣式表 — 並知道它們各自的優點和缺點 — 將使您能夠處理您將來可能會遇到的任何樣式表設計工作。

參考資料

 

透過單擊本文頂部或底部的討論,參與有關本文的論壇。
從 學習 XSLT 和 技術的良好基礎知識。


請閱讀 Kevin 以前的專欄和文章:
XML for Data #1:使用 XML Schema 原型(developerWorks,2001 年 6 月)
XML for Data #2:用樣式化(developerWorks,2001 年 7 月)
XML for Data #3:XLink 和資料(developerWorks,2001 年 7 月)
XML for Data #4:靈活體系結構的四點技巧(developerWorks,2001 年 8 月)
XML for Data #5:Native-XML :一個關於資料的壞主意?(developerWorks,2001 年 10 月)
XML for Data #6:多對多關係的建模(developerWorks,2002 年 1 月)
XML for Data #7:對 XQuery 的前瞻(developerWorks,2002 年 2 月)
pbox:Kevin 講述了他提倡為什麼在資料方面,XML Schema 不費吹灰之力擊敗了 DTD(developerWorks,2001 年 6 月)的原因。

 

請閱讀 XML structures for existing databases,摘自 Wrox 出版的書籍 Professional XML Databases中的一個章節(developerWorks,2001 年 1 月)。


獲取 IBM sphere Studio Site Developer,它是構建、測試和部署 Server Pages、 和與 XML 相關的應用程式和網站的一種易於使用的整合開發環境。


查明如何才能成為一名 XML 和相關技術領域的 IBM 開發人員。


請在 developerWorks XML 專區上查詢更多有關 XML 的參考資料。

關於作者
Kevin Williams 是 Blue Oxide Technologies, LLC 的 CEO,這是一家從事設計 XML 和 Web 服務創作的公司。請訪問該公司的網站 。可以透過 與他聯絡。 
 


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752043/viewspace-992771/,如需轉載,請註明出處,否則將追究法律責任。

相關文章