DIV CSS 佈局教程網

 DIV+CSS佈局教程網 >> 網頁腳本 >> XML學習教程 >> XML詳解 >> 利用XSLT 2.0成批處理XML
利用XSLT 2.0成批處理XML
編輯:XML詳解     

大多數人都希望 Saxon 這樣的 XSLT 處理程序能使用多個輸入文件。常常會遇到這樣的問題,需要將一個目錄中的 XML 文件轉換成 HTML。可以對這些文件分別使用 Saxon,但是如果最後希望生成一個文件包含所有那些 Html 文件的索引,那該怎麼辦呢?

  您需要的是目錄列表的 XML 版本。這樣就可以將這個 XML 文件作為 XSLT 的惟一輸入文件,並用 XSLT 處理每個文件。如果 XSLT 能夠直接進行目錄處理就很完美了。不幸的是,盡管 XSLT 很強大,特別是 XSLT 2.0,但這種語言卻沒有目錄操作。

  HXDLG 來幫忙!

  在網上沖浪的時候,我從 SourceForge 上發現了一個不起眼的小 Java 程序,HTML/XML Directory List Generator (HXDLG)(請參閱 參考資料)。HXDLG 的一項功能就是創建目錄列表的 Html 或 XML 表示。我下載了該工具,並從命令行運行清單 1 所示的語句。

  清單 1. 使用 HXDLG 創建 XML 目錄的代碼

Java -jar hdlg.jar XML
  /Users/jherr/Projects/ibm_XML_tips/filelist/testfiles/
  /Users/jherr/Projects/ibm_xml_tips/filelist/files.XML

  這個程序有三個參數。第一個參數是輸出類型,即 XML 或者 Html。第二個是目錄路徑,第三個是輸出 XML 文件的路徑。結果如清單 2 所示。

  清單 2. XML 格式的目錄

<?XML version="1.0" encoding="UTF-8"?>
<!DOCTYPE hdlg:filesystem SYSTEM
 "http://www.hdlg.info/XML/filesystem.dtd">
<hdlg:filesystem
xmlns:hdlg="http://www.hdlg.info/XML/filesystem">
  <hdlg:folder name="testfiles"
   url="file:/Users/jherr/Projects/ibm_XML_tips/filelist/testfiles/">
   <hdlg:file name="test1.XML" size="179"
     type="unknown"
 url="file:/ibm_xml_tips/filelist/testfiles/test1.XML">
   </hdlg:file>
   <hdlg:file name="test2.XML" size="181"
     type="unknown"
 url="file:/ibm_xml_tips/filelist/testfiles/test2.XML">
   </hdlg:file>
   <hdlg:file name="test3.XML" size="181"
     type="unknown"
 url="file:/ibm_xml_tips/filelist/testfiles/test3.XML">
   </hdlg:file>
  </hdlg:folder>
</hdlg:filesystem>

裡面的內容很周到。有文檔類型定義(DTD),並使用了名稱空間,還有需要的文件名和 URL。而且給出了絕對路徑!

  測試

  為了測試該系統,我使用了三個不同的 XML 文件作為測試示例:test1.xml、test2.xml 和 test3.XML。我希望讀入這些文件並創建相應的 Html 文件。清單 3 顯示了一個示例測試文件。

  清單 3. XML 格式的測試文件

<?XML version="1.0" encoding="UTF-8"?>
<testrun run="test1">
  <test name="foo" pass="true" />
  <test name="bar" pass="true" />
  <test name="baz" pass="true" />
</testrun>

  第一步是運行 HXDLG 獲得 XML 格式的目錄列表。目錄列表中包含測試文件的 URL,並將作為 XSL 樣式表的輸入。

  將多個文件讀入 XSL 中

  第一遍只讀入文件並打印測試名(如清單 4 所示)。這樣做是為了保證能夠正確地解析目錄結構並讀取目標文件。

  清單 4. 打印測試名

<?XML version="1.0" encoding="UTF-8"?>
<xsl:stylesheet XMLns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0">
  
<xsl:output method="text" indent="no"/>
  
<xsl:template match="/">
<xsl:for-each select="//*:file">
<xsl:variable select="document(@url)" name="contents" />
<xsl:value-of select="$contents/testrun/@run" /><xsl:text>
</xsl:text>
</xsl:for-each>
</xsl:template>
 
</xsl:stylesheet>

 XSLT 引擎對目錄列表(即輸入)所做的第一件事就是匹配模板。模板使用 for-each XSL 標簽遍歷每個文件標簽。其中的關鍵是使用 XSL variable 標簽調用 document,後者把指定 XML 文件的內容讀入變量。XSL 使得讀取 XML 文檔輕而易舉。

  現在得到了 XML 測試文件的內容,我使用 value-of 標簽打印運行的測試名,後面通過 xsl:text 標簽增加了回車換行符(如清單 5 所示)。

  清單 5. 第一個 XSL 模板的輸出

test1
test2
test3

  輸出顯示了三個文件和三個測試。因此,該工具到目前為止運行正常。現在需要為每個測試結果創建 Html。為此我將使用 XSLT 2.0 中新增的 xsl:result-document 標簽。(因此,清單 6 中 stylesheet 標簽的 version 屬性成了 2.0。)

  清單 6. 用於創建 Html 文件的樣式表

<?XML version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
  XMLns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="2.0">
  
<xsl:output method="text" indent="no"/>
<xsl:output method="html" indent="yes" name="Html"/>
<xsl:template match="/">
<xsl:for-each select="//*:file">
<xsl:variable select="document(@url)" name="contents" />
<xsl:variable select="replace(@url,'[.]XML','.Html')"
 name="newfile" />
Creating <xsl:value-of select="$newfile" />
<xsl:result-document href="{$newfile}" format="Html">
<Html><body>
Test run: <xsl:value-of select="$contents/testrun/@run" />
</body></Html>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
 
</xsl:stylesheet>

  打印測試名的地方,現在改為使用 variable 標簽創建新的 HTML 文件名。使用 XPath 函數 replace,我獲得原來的 URL 並用 .Html 擴展名代替 .XML 作為新的文件名。

  然後打印文件名,讓用戶知道我在創建什麼。這是一種好辦法,否則什麼也看不到也就不清楚樣式表在做什麼了。

  打印完這些消息之後,我使用 xsl:result-document 標簽創建新文件,用 HTML 說明運行的測試名。有必要指出,這裡必須使用格式語句規定輸出文件是 HTML 格式。如果不這樣做,則創建的文件將變成文本格式,所有的 Html 標簽都被忽略。

  結束語

  如果有導出 XML 的目錄列表工具,並知道如何使用 xsl:result-document 標簽重定向引擎的輸出,那麼 XSLT 2.0 中的成批處理很簡單。只要有這些工具,就不用再擔心將 XML 文件目錄合並成一個大文件來簡化處理了。



XML學習教程| jQuery入門知識| AJAX入門| Dreamweaver教程| Fireworks入門知識| SEO技巧| SEO優化集錦|
Copyright © DIV+CSS佈局教程網 All Rights Reserved