XML 程式設計思想: 研讀XML Hacks(轉)

amyz發表於2007-08-12
XML 程式設計思想: 研讀XML Hacks(轉)[@more@]

  XML Hacks是一本介紹 XML 技巧和竅門的書籍。這是一本很有用的參考資料,其內容十分廣泛,但如果某些材料能夠進一步展開或者改寫的話,可能會更好。Uche Ogbuji 提供了該書的應用報告。

  在 上一期文章中,我評論了 Elliotte Rusty Harold 所著的 Effective XML,所有 XML 專業人員都應該讀一讀這本很棒的著作。在本期文章中,我把目光投向了另一本實用 XML 書籍,Michael Fitzgerald 編纂的 XML Hacks(O'Reilly and Associates,2004 年)。這本書涉及的範圍很廣,包括入門性的基礎知識、中階和高階的設計與實現技術,以及一些工具的使用技巧。本專欄和其他 developerWorks文章的讀者,可能更希望我能專注於 XML 設計和 XML 詞彙表的問題。 XML Hacks論述更多的是實現細節和工具使用,但是這些知識也很重要,在本期文章中,我將介紹我自己應用書中內容的一些實際觀察。與關於 Effective XML的文章一樣,本文並不是書評,而是受該書啟發想到的一些東西,本書是為不具備這些知識的讀者編寫的。

  使用 XInclude 包含外部文字文件

  在這本書的第 26 章“Include External Documents with XInclude”中,說明了如何以類似 XML 內建外部已解析實體的方式使用 XInclude(請參閱 Resources)。書中給出了一個示例文件,其中插入了由 HTTP URL 指定的外部 XML 文件。XInclude 確實為這種混合增加了為數不多的一些技巧,比如後退支援(出現錯誤時提供替代內容),以及處理程式發出 HTTP 請求時指定內容協商方式的機制。但是我認為與已解析實體機制相比,XInclude 的兩個最主要優點是:

  • 能夠使用 XPointer 從目標文件中選擇要包含的部分。
  • 能夠改變解析機制,將外部文件作為完全轉移的文字檔案而不是 XML 文件插入。

  如果正在撰寫包含程式碼清單或者示例的 XML 文件,第二點尤其方便。比方說,假設您撰寫的文件中要包含清單 1 所示的 Python 語言程式碼。

  清單 1. 作為清單插入 XML 文件的 Python 例項程式碼

  def game_show(contestant_guess, prices):  if prices[contestant_guess] < 1000:    print "you win!"  else:    print "you lose!" 

  您應該在單獨的檔案中開發這些程式碼,這樣,就可以在將它們放入文件之前對其進行測試,以確保它們能像您期望的那樣工作。首先您可以把這些程式碼剪下並貼上到 XML 檔案中,如清單 2 所示。

  清單 2. 直接剪下貼上示例程式碼的插入文件

  "-//W3C//DTD XHTML 1.0 Transitional//EN" ""> On-line game show programming in Python 

  

A simple example

  

Examine the following code:  

  
   
example 1
<!-- paste Python code here --&gt  
 
 

  這樣會造成錯誤,因為 if prices[contestant_guess] < 1000: 這一行包含沒有轉義的小於號(

  清單 3. 透過剪下貼上到 CDATA 節插入示例程式碼的文件

  "-//W3C//DTD XHTML 1.0 Transitional//EN" ""> On-line game show programming in Python 

  

A simple example

  

Examine the following code:  

  
   
example 1
  
 
 

  這種方法無疑能夠避免了轉義錯誤,但是您必須注意那些估計可能很少出現的字串“]]>”,如清單 4 中所示。

  清單 4. 作為清單插入 XML 文件的 Python 示例程式碼

  def game_show(guesses, contestant, prices):  if prices[guesses[contestant]]>1000:    print "you win!"  else:    print "you lose!" 

  為了在 CDATA 部分中正確轉義這一行,您至少需要像 if prices[guesses[contestant]]]]>1000: 這樣複雜的程式碼。還要注意的是,我使用的是 Python 程式碼,多數情況下,Python 需要轉義的地方相對較少。如果編寫的是關於 XML 的文件,手工轉義可能就無法勝任了。而且出現“]]>”這個字串組合的機會也多得多(比如 XML 清單可能本身包含 CDATA 部分)。

  當然,您可以選擇自己的方法繞開這個障礙,但是我發現,處理文章中所包含程式碼的最簡單的方法就是使用 XInclude 的 parse="text" 功能。只要在 xi:include 元素中新增該屬性,就能自動將程式碼作為 XML CDATA 解析,從而自動轉義包含的內容。清單 5 就是以這種方式使用 XInlude 的一個例子:

  清單 5. 使用文字行 XInclude 插入示例程式碼的文件

  "-//W3C//DTD XHTML 1.0 Transitional//EN" ""> On-line game show programming in Python 

  

A simple example

  

Examine the following code:  

  
   
example 1
  
 
 

  xi:include 元素被替換為完全轉義的 gameshow1.py (比如 清單 1)的內容,該檔案是相對於元素的基 URL 進行解析的。感謝 parse="text" ,轉義是自動完成的。我總是使用 encoding 屬性(如果使用 parse="xml" ,偶爾可以忽略它)。在我的應用中,Python 檔案通常使用“iso-8859-1”編碼,而 XML 檔案使用“utf-8”編碼,當然,您的環境中可能使用不同的編碼。

  我在為 developerWorks(它要求作者以精心設計的 XML 格式提供文稿)撰寫這些文章時,使用的就是已解析文字 XInclude 技術,並發現這樣極大提高了編輯速度。

  另一個注意事項是:該書使用的是當時正在開發之中的 XInclude 名稱空間 ,但是現在,這個名稱空間已經不存在了。在 2004 年 4 月 13 日釋出的 Candidate Recommendation 中,W3C 工作組又回到了原來的名稱空間 。據我瞭解,多數工具只支援後一種(2001)名稱空間形式,這可能是 W3C 決定回到原來的名稱空間的原因,但這種名稱空間的變化和撤銷確實帶來了一些混亂。該書作者就成了這種變化的無辜的犧牲品,我已經就此向出版商提供了一份刊誤表。

  更簡單的恆等轉換

  第 37 章“Generate an XSLT Identity Stylesheet with Relaxer”討論一種相當複雜的生成 恆等轉換的方法,即輸出和源文件等價的 XML 的 XSLT 轉換。在以這種方法得到的轉換中,對應詞彙表中的每個元素都有一個模板,這的確很複雜。這樣做可能是為了提供一個樣本,以便用於建立更專門的轉換,但我認為它沒有給出一種簡單得多的恆等轉換,甚至 XSLT 規範中都作為例子給出了這樣的一個轉換。在後一章(38)“Pretty-Print XML Using a Generic Identity Stylesheet and Xalan”中,討論了這種更簡單的恆等轉換,其中包括為了獲得整齊的列印效果而經常採用的 。我建議您首先閱讀第 38 章,熟悉簡單的恆等轉換之後,再來研究 37 章中那種複雜的方法。這樣做的還有一種好處,理解這種簡單的恆等變換是熟悉和掌握幾種 XSLT 短語的關鍵,包括將源節點複製到輸出中的 xsl:copy-of 與常見 XPath 節點測試的細微差別: * 、 @* 和 node() 。

  不使用 XSLT 2.0 生成多個輸出文件

  第 45 章“Generate Multiple Output Documents with XSLT 2.0”討論瞭如何使用 XSLT 2.0 xsl:result-document 在一次轉換中序列化多個結果樹。整章都寫得不錯,除了最後出現的一句:


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

相關文章