XML 和 WebSphere Studio Application Developer: 第 8 部分:探究 XML to XML Mapping Editor

引言
IBM® WebSphere® Studio Application Developer(以下稱爲 WebSphere Studio)是一種應用程序開發產品,它支持使用 JSP、servlet、HTML、XML、Web 服務、數據庫和 EJB 之類的不同技術構建多種應用程序。WebSphere Studio 還特別提供了 XML 和關係數據之間的緊密集成。WebSphere Studio 支持 WebSphere Application Server 支持的所有數據庫,包括 DB2®、Oracle Sybase 以及 Microsoft® SQL Server。

這個系列的文章主要討論 WebSphere Studio 附帶的 XML 工具,本文是其中的第 8 部分。本文探究 XML to XML Mapping Editor,一種讓您以圖形方式定義 XML 文檔或者模式之間轉換的可視化工具。您可以利用該工具生成直接表達語義的 XSLT 樣式表,這些語義是進行映射和轉換的基礎。本文將討論映射工具的一些比較有用的方面並着重討論能夠讓您快速創建和測試高級 XPath 表達式的 XPath 嚮導。

先決條件
爲完成本文中的各步驟,您需要安裝 WebSphere Studio Application Developer 版本 5.0。

XSLT 和 XPath 概述
XSLT(Extensible Stylesheet Language:Transformations,可擴展樣式表語言:轉換)是一種主要爲轉換 XML 文檔結構而設計的語言。這種語言被設計用來作爲 XSL(Extensible Stylesheet Language,可擴展樣式表語言)的一部分。欲瞭解更多有關 XSLT 或者 XSL 的信息,請參考以下內容:

XPath 是一種 XSL 子語言,它被設計用來和 XSLT 一起使用。使用 XPath 來識別或者定位 XML 源文檔一些部分。您可以使用爲 XPath 定義的語法來唯一地識別和定位 XML 文檔中的每一個節點。

欲瞭解更多有關 XPath 的信息,請參閱 W3C 的 XML Path Language (XPath) Version 1.0

樣本概述
本文中所用的樣本將計算大學物理課學生的期末考試成績。它合併兩個源文檔的數據。源文檔和目標文檔都可以是 DTD、XML Schema 或者 XML 文件的任意組合。爲簡單起見,該樣本使用 DTD 文件。第一個源文件包含課程信息,包括一學期中彙總的成績。

圖 1. course.dtdcourse.xml 文件

第二個源文件包含有關學生的信息,包括學生 ID、姓名以及課程量。

圖 2. students.dtdstudents.xml 文件

目標文件包含一張按學生 ID 排序的期末成績列表。 

圖 3. grades.dtd 文件
grades.dtd 文件

除了合併數據並對數據進行排序外,您還需要爲每一位學生計算期末成績。學生的期末成績由該生在學期中獲得的各成績的平均分組成。您將使用一個 XPath 表達式來進行這種計算。這個樣本演示了怎樣一起使用 XPath 嚮導和 XML to XML Mapping 工具。

開始
首先,您需要在 WebSphere Studio 中創建一個項目,然後導入示例文件。 下載下面提供的 CollegeExample.zip 文件,然後將其解壓縮至一個臨時文件夾,例如 C:/temp/College

啓動 WebSphere Studio,然後創建一個 Java™ 項目:

  1. 選擇 File => New => Project => Java => Java Project以啓動 New Project 嚮導。使用這個嚮導來創建一個 Java 項目。
  2. 在 project name 域中輸入 CollegeExample
  3. 單擊 Finish

將示例文件導入項目:

  1. 選擇 File => import
  2. 選擇 File System作爲導入源。單擊 Next
  3. 單擊 Browse來定位 CollegeExample.zip 文件解壓縮後所在的臨時文件夾。
  4. 單擊 Select All。選擇 Create selected folders only選項,然後單擊 Finish

現在 CollegeExample 項目中已創建了兩個新文件夾:包含 Java 和類文件的 javaPhysics 文件夾以及包含 DTD 和 XML 文件的 physics 文件夾。

創建映射會話
在創建任何映射之前,您都需要創建並打開一個 XML to XML 映射會話。這種映射會話的核心是映射會話文件(它的擴展名爲 .xmx )。該文件存儲了在映射會話期間收集的所有相關映射信息,並且還在會話自身之外持久保存這些信息。這使得用戶在日後能再訪問這個會話。

請完成以下步驟來創建並打開初始的 XML to XML 映射會話:

  1. 啓動 New XML to XML Mapping 嚮導
  2. 爲映射會話命名
  3. 選擇源文件
  4. 選擇目標文件
  5. 選擇根元素

1. 啓動 New XML to XML Mapping 嚮導
現在您將在 WebSphere Studio 中創建 XML to XML 映射會話:

  1. 選擇 Perspective => Open => Other => XML以切換到 XML 透視圖。
  2. 從菜單中選擇 File => New => Other。一個標題爲 New 的窗口打開。
  3. 選擇左邊的 XML
  4. 選擇右邊的 XML to XML Mapping
  5. 單擊 NextNew XML to XML Mapping Session頁面打開。

2. 爲映射會話命名
在這張頁面上指定會話文件的名稱以及您想創建它的位置:

  1. 選擇 CollegeExample 項目中的 physics文件夾(該文件夾先前已導入)。
  2. 指定文件名 grades.xmx
  3. 單擊 Next

3. 選擇源文件
在這張頁面上選擇源文件。三種類型的輸入文件可以被接受:XML、XML Schema 以及 DTD。DTD 和 XML Schema 文件包含用來生成較常規或者較普通的 XSLT 樣式表的內容模型信息。XML 文檔可能包含,也可能不包含對相應 DTD 或者 XML Schema 的引用。XML 文檔自身只能提供部分信息。例如,沒有 DTD 或 XML Schema 引用就不可能確定任意一個給定的元素在任意給定的上下文中是可重複的還是不可重複的、是可選的還是必需的。同樣,該工具將會在沒有相應的 DTD 或者 XML Schema 的情況下生成一個更有針對性的樣式表。

對於這個示例,您感興趣的是兩個輸入文件: course.dtdstudents.dtd

  1. 展開 physics 下的目錄樹。
  2. 選擇 course.dtdstudents.dtd
  3. 單擊 >將文件複製到 Selected Files 窗口。 
  4. 單擊 Next

4. 選擇目標文件
您需要指定單個目標文件。同源文件相似,目標文件可以是三種類型的其中之一:XML、XML Schema 或 DTD。對於這個示例,我們使用 grades.dtd 作爲目標文件。

  1. 展開 physics下的目錄樹。
  2. 選擇 grades.dtd
  3. 單擊 Next

5. 選擇根元素
當您將 DTD 或者 XML Schema 裝入 XML to XML Mapping Editor 時,該工具會自動生成相應的 XML 表示,在映射會話期間會用到這些 XML 表示。換言之,無論您是把它們指定作爲源還是目標,用戶始終是把它們從一個 XML 視圖映射到另一個 XML 視圖。

對於該示例,您需要爲源 DTD 文件和目標 DTD 文件的 XML 表示選擇根元素。在 Root Element 對話框中:

  1. 確保選中 course作爲 grades.dtd 的目標根元素。
  2. 確保選中 course作爲 course.dtd 的根元素。
  3. 確保選中 students作爲 students.dtd 的根元素。
  4. 單擊 Finish

圖 4. 選擇根元素

該向導自動創建並打開一個映射會話文件。這就啓動 XML to XML Mapping Editor。

現在,您將使用 XML to XML Mapping Editor 來完成餘下的工作。該編輯器的主窗口有兩個窗格,如下圖 5 所示。在左邊標題爲 Source的窗格中,請注意兩個 XML 源文檔樹 coursestudents 的元素和屬性。在右邊標題爲 Target的窗格中,請注意與 XML 目標文檔樹 grades 相關的節點。除主窗口外,還有兩個視圖可用:Outline 視圖(它顯示所有當前的映射)和 Overview 視圖(它顯示所有基本映射及其增強之處的摘要)。

圖 5. XML to XML Mapping Editor
XML to XML Mapping Editor 的抓屏

初學者轉換指南
首先,您需要創建 XML 源文件和 XML 目標文件之間的基本映射。一旦創建了基本映射,您將增強映射來按學生 ID 升序輸出期末成績列表。

基本映射
檢查源文檔中可以多次出現的元素(這些元素用兩種圖標標識,零個或多個圖標 zero-or-more-elements 的抓屏和一個或多個圖標 one-or-more-elements 的抓屏)。因爲這些元素是在 XSLT 樣式表中用 <xsl:appley-templates><xsl:for-each> 來處理,所以映射這些元素很重要。在這些 XSLT 結構中,這些元素成了當前節點以及用來處理這些節點的子節點的上下文。例如,多數情況下您想看一下 students@id 屬性在特定學生的上下文(即其父映射的上下文)中發生。

因此,開始時請先將源文檔 students 中的 students/student 映射爲目標文檔 grades 中的 course/grades/student 。注意,這兩個元素都可重複:

  1. 在 Source 窗格中,選擇 students 文檔中的 students/student元素。
  2. 在 Target 窗格中拖動 course/grades/student元素上方被選中的節點。接着,在目標節點被突出顯示時放開它。

現在創建了 students/student 元素(在 students 中)和 course/grades/student 元素(在 grades 中)之間的映射。這個映射在 Outline 和 Summary 視圖中同時列出。在主窗口中,請注意這兩個元素旁邊都有一個小箭頭,用來表示這些元素已經被映射過。

圖 6. 創建的 students/student 元素(在 students 中)和 course/grades/student 元素(在 grades 中)之間的映射
顯示先前創建的映射的抓屏

現在,請對每一個元素重複上述步驟來完成餘下的基本映射:

  • course 中的 course/@title 映射爲 grades 中的 course/@title
  • course 中的 course/@id 映射爲 grades 中的 course/@id
  • course 中的 course/teacher 映射爲 grades 中的 course/teacher
  • students 中的 students/student/@name 映射爲 grades 中的 course/grades/student/@name
  • students 中的 students/student/@id 映射爲 grades 中的 course/grades/student/@id

圖 7. 已映射的元素
顯示已完成映射的元素的抓屏

Overview 窗格提供所有映射的摘要。第三列被保留用來指出基本映射的增強。映射可能的增強包括添加 XPath 表達式、分組、排序、Java 方法、JavaScript 以及轉換函數。

排序
在這一部分,您將增強初始映射來指定 student 節點的處理順序。您只可以在源元素和目標元素都可重複的映射上指定排序選項。對於 XSLT 來說,這意味着 <xsl:sort> 始終是 <xsl:apply-templates><xsl:for-each> 的子節點。

因此,爲了輸出按學生 ID 升序排序的期末成績和年級的列表,您需要完成以下步驟:  

  1. 在 Target 窗格中選擇 course/grades/student元素。
  2. 右鍵單擊啓動上下文菜單。
  3. 選擇 Sort以啓動 Select Mapping Sort Keys 嚮導
  4. From available sort keys一欄中選擇 id/text()
  5. 按下 >>按鈕將它添加到 Added sort keys欄。
  6. 在 Sort order 下,確保選中 Ascending
  7. 在 Data sort order 下,選擇 Numerical
  8. 單擊 Finish

圖 8. 帶有已填好的 Specify Sort Key 頁的 Select Mapping Sort Keys 嚮導
顯示帶有已填好的 Specify Sort Keys 頁的 Select Mapping Sort Keys 嚮導的抓屏

這個增強的映射所指定的 student 節點將按照鍵和所選的選項排序。排序圖標 排序圖標的抓屏現在顯示在基本映射旁邊的 Overview 窗格的第三列中以反映基本映射的增強。

圖 9. 增強的映射
顯示增強的映射的抓屏

中間轉換

使用 XPath 嚮導來組成期末成績表達式
接下來,您需要爲每一位學生計算期末成績。您可選擇將 course 文檔中的 <mark> 元素映射爲 grades 文檔中的 @finalMark 屬性。然而,映射本身並不能獲取您想在兩節點之間建立的語義。您實際上想做的是計算某一特定學生的所有成績的平均值。您可以使用一個 XPath 表達式來獲取這一關係。

編寫 XPath 表達式可能容易出錯並且不易調試。原因一部分在於 XSL 語言的聲明和遞歸特性,一部分在於 XPath 語法的複雜性。WebSphere Studio 提供了一個 XPath 嚮導來幫您構建和測試 XPath 表達式。

在這一部分,您將完成以下步驟來構建和測試一個計算各個學生期末成績的表達式:

  1. 啓動 XPath 嚮導
  2. 選擇節點集:第一次嘗試
  3. 選擇節點集:第二次嘗試
  4. 過濾節點選擇
  5. 彙總
  6. 使用全局文檔變量
  7. 使用當前節點

1. 啓動 XPath 嚮導

  1. 在 Target 窗格中,選擇 @finalMark屬性。右鍵單擊以啓動上下文菜單。
  2. 選擇 Define XSLT Function以啓動 XSLT Functions 嚮導。
  3. 選擇 XPath expression
  4. 單擊 Next
  5. 在 XPath Expression 頁面上,單擊 Advanced以啓動 XPath Expression 嚮導。

根據 XPathe 表達式,計算期末成績的公式如下:


sum(all of the marks for a specific student) 
div count(all of the marks for a specific student)
    

現在,您將構建一個返回某一特定學生的成績集的表達式。然後把這個成績集應用於求和函數和計數函數,最後將求得的和除以計數函數所得的計數。

2. 選擇節點集:第一次嘗試
由於存在多個源文件並且您是在一個未映射的目標節點上打開向導,所以現在您被提示選擇一個 XML 文件,您將根據該文件構建 XPath 表達式。展開 physics 下的目錄樹。選擇 course.xml(該文件包含學生的成績)。選擇 Next

由於成績沒有按學生分組,因此沒有真正的上下文節點。因此,XPath 表達式的起點是文檔的根目錄。

  1. 選擇文檔根目錄 #document
  2. 單擊 Next
  3. 在 XPath Expression 嚮導的 Create an XPath Expression 頁面上,XPath 域包含 XPath 表達式。您可以通過從節點樹和 XPath Expression 嚮導中的各種頁面選擇合適的選項來直接創建或者修改它。

    圖 10. XPath Expression 嚮導的 Create an XPath Expression 頁面
    顯示 XPath Expression 嚮導的 Create an XPath Expression 頁面的抓屏

  4. 左邊的節點樹列出了您 XML 文檔中的所有節點(包括屬性和元素)。從該節點樹選擇節點來自動更新 XPath 域。對於第一次嘗試,您將從根節點開始一路選擇節點到 <mark> 節點: <course><marks><assignment>以及 <mark>。現在,XPath 域出現:

    圖 11. 當前 XPath 域
    顯示當前 XPath 域的抓屏

  5. 通過單擊 Execute根據 XML 文檔測試表達式。

    圖 12. XPath 查詢結果
    顯示 XPath 查詢結果的抓屏

  6. 在結果中,請注意該成績集沒有包含任何學生的所有成績。因此,您在開始過濾之前首先要概括該表達式。

3. 選擇節點集:第二次嘗試
在第二次嘗試中,您需要創建您想要的實際成績集的一個超集。第一次嘗試時的問題是您僅從作業中收集成績。它不包含期中成績或者在平時測驗中取得的成績。您需要用包括期中成績和測驗成績以及作業成績的更全面的步驟替換 assignment 這一步。使用通配符 * 來完成這個任務。

  1. 把光標放在 XPath 域內。
  2. 從現有的 XPath 表達式中除去 assignment
  3. 讓光標就停留在這個位置,單擊 Location Paths選項卡。
  4. 從 Node tests 下拉菜單選擇通配符 * 。現在,XPath 域出現:

    圖 13. 當前 XPath 域
    顯示當前 XPath 域的抓屏

  5. 通過按下 Execute根據 XML 文檔測試這個表達式。

    圖 14. XPath 查詢結果
    顯示 XPath 查詢結果的抓屏

在結果中,請注意現在已存在您想要的成績集的超集。下一步就是過濾表達式。

4. 過濾節點選擇
最後一個表達式獲取全體學生的所有成績。現在您需要添加僅獲取某個特定學生的成績的過濾謂詞。轉換上下文中的當前節點是 <student> ,它實際來自另一個源文檔。在這種情況下,您需要用一個真實示例來模擬當前學生的 ID。最後就是做些調整。對於這個示例,我們使用 John Gravity 的學生 ID 001 作爲工作樣本。

按照 XPath 來說,您是想要 id=001 的學生的所有成績。

  1. 請把光標放在 XPath 域中通配符 * 的旁邊。
  2. 讓光標就停留在這個位置,單擊 Location Paths選項卡。
  3. 從 Precicates 下拉菜單中選擇 []
  4. 在方括號中輸入 studentId=001
  5. 現在,XPath 域出現:

    圖 15. 當前 XPath 域
    顯示當前 XPath 域的抓屏
                          

  6. 通過按下 Execute根據 XML 文檔測試這個表達式。

    圖 16. XPath 查詢結果
    顯示 XPath 查詢結果的抓屏

這就是 John Gravity 的精確成績集。現在您有了想要的表達式。接下來,您需要把這個成績集應用於求和函數與計數函數,最後將求得的和除以計數函數所得的計數。

5. 彙總
將求和函數與計數函數應用於節點集(代表各個學生的成績):

  1. 將光標放在 XPath 域中表達式的起始處。
  2. 讓光標就停留在這個位置,單擊 Functions選項卡。
  3. 從 Number set functions 下拉菜單中選擇 sum()
  4. 調整閉括號,使其包含整個 XPath 表達式。 
  5. 複製該表達式並將其副本粘貼到它的旁邊,用函數 count() 替換 sum()
  6. XPath 域現在顯示下面兩個函數:

    圖 17. 當前 XPath 域現在顯示兩個函數
    顯示當前 XPath 域現在顯示兩個函數的的抓屏
    顯示當前 XPath 域現在顯示兩個函數的的抓屏

最後將求得的和除以計數函數得到的值

  1. 將光標放在兩個函數間
  2. 讓光標就停留在這個位置,單擊 Operators選項卡。
  3. 從 Numbers 下拉菜單中選擇 div。現在,XPath 域出現:

    圖 18. 當前 XPath 域
    顯示當前 XPath 域的抓屏

  4. 通過按下 Execute根據 XML 文檔測試這個表達式。

    圖 19. XPath 查詢結果
    顯示 XPath 查詢結的抓屏

不出所料,John Gravity 的期末成績是 88

單擊 Finish。這樣您將返回到 XSLT Functions 嚮導的 XPath Expression 頁面。您剛纔創建的 XPath 表達式現在顯示在 parameter 域中。然而,因爲是用表達式的最終形式使用來自兩個不同來源的節點,所以您需要很好地調整該表達式。

圖 20. XSLT Functions 嚮導的 XPath Expression 頁面
顯示 XSLT Function 嚮導的 XPath Expression 頁面的抓屏

6. 使用全局文檔變量
因爲當前節點其實是來自另一個源文檔,所以您選擇了文檔根元素作爲最初的 XPath 表達式的起點。當存在兩個或更多源文檔時,在訪問 XPath 表達式中的節點時,您需要把一個源文檔與另一個明確地區別開來。對於多個 XML 源文檔,您可以訪問整個樣式表中的每一個源文檔,方法是使用在已生成的樣式表的 XML Sources 部分定義的全局變量。這些全局變量的名稱是: d1d2d3 、... dn 。這與映射編輯器的 Source 窗格中出現的 n 個文檔的次序一致。您需要將求和函數和計數函數的參數中的第一個“ . ”用 $d1 來替換,其中 d1 訪問文檔 course

圖 21. 用 $d1 替換
顯示 $d1 被替換到 XPath 表達式中的抓屏

7. 使用當前節點
最後,您需要用一個 XPath 表達式(它指示當前正處理的學生的 ID)來替換工作樣本 ID 001 。當處理目標文檔中的 @id@name 或者 @finalMark 時,當前節點是基於當前映射的 <student> 。因此,您可以使用當前函數來訪問當前學生。

  1. current()/id 替換 XPath 表達式中兩次出現的 001 。現在,Parameter 域出現:

    圖 22. 當前 parameter 域
    顯示當前 Parameter 域的抓屏

       
  2. 單擊 Finish

一個新的映射出現在 Overview 窗格中,並且函數圖標 函數圖標抓屏現在出現在旁邊以說明映射的增強。這就完成了這次轉換的映射。

圖 23. 這次轉換的映射
顯示這次轉換的映射的抓屏

生成並測試 XSLT 樣式表
既然映射完成了,那麼您就可以生成 XSLT 樣式表了。在 XML to XML Mapping Editor 中完成下列步驟:

  1. 按下工具欄上的 Generate XML 按鈕 GenerateXML 按鈕抓屏以啓動 Generate XSLT Script 嚮導。
  2. 選擇 CollegeExample/physics文件夾。
  3. 輸入文件名 grades.xsl
  4. 單擊 Finish

grades.xsl 文件在 Navigator 視圖中打開並顯示在 XSL 編輯器中:

圖 24. grades.xsl 文件
grades.xsl 文件的抓屏

XSL 轉換的缺省模式包括轉換和打開調試會話。然而,在這裏將禁用調試功能以使您可以只運行轉換。

  1. 從主菜單中選擇 Windows => Preferences =>XML => XSL Debugging
  2. 取消對 Run transformations and open a debugging session複選框的選擇。
  3. 單擊 OK

現在, transform only 選項被啓用。在這種存在多個 XML 源文檔的情況下,已生成的 XSL 樣式表使用 document 函數來訪問每一個 XML 源文檔。因此,在應用 XSLT 樣式表時,哪一個 XML 源文檔被您指定作爲主源文檔就無關緊要了。

將 XSLT 樣式表應用於 XML 源文檔:

  1. 選擇 Navigator窗格。
  2. CollegeExample/physics 文件夾下,選擇 grades.xsl,再選 course.xmlstudents.xml
  3. 右鍵單擊選中的文件,從下拉菜單選擇 ApplyXSL => As XML

圖 25. 從下拉菜單選擇 ApplyXSL =>AS XML
從下拉菜單選擇 Apply =>As XML 的抓屏

現在,新轉換的 XML 文件在 XML 編輯器被打開:

圖 26. 新轉換的 XML 文件

結束語
本文演示瞭如何在 WebSphere Studio Application Developer 版本 5.0 中使用 XML 和 XML Mapping Editor 完成下列工作:

  • 創建基本映射
  • 合併來自兩個源文檔的數據
  • 對數據進行排序
  • 使用 XPath 嚮導構建和測試高級 XPath 表達式
  • 生成和測試 XSLT 樣式表
下載
NameSizeDownload method
CollegeExample.zip0.006 MBHTTP
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章