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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章