XML - 数据交换管理/C.6
外观
现在您已经知道如何创建模式来定义概念上的主键/外键关系,您需要知道如何访问和显示这些数据。查看下面的样式表以获取示例。
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<!-- See note below about new elements added -->
<xsl:key name="predecessor" match="president" use="@primaryKey"/>
<!--xsl:key name="name referenced from within XSL file" match="element in XML file containing key"
use="attribute or sub-element containing actual value of key "-->
<!--key() function use: key('predecessor',2) will return the nodes contained
by the president element with attribute: primaryKey="2"
Since a node list is returned, <xsl:value-of select="key('predecessor',2)/firstName"/>
will output John -->
<xsl:output method="html"/>
<xsl:template match="/">
<table style="font-family:arial">
<tr style="background-color:#6495ED;font-weight:bold">
<td>President First Name</td>
<td>President Last Name</td>
<td>Predecessor First Name</td>
<td>Predecessor Last Name</td>
</tr>
<xsl:for-each select="//president">
<tr style="background-color:#3CB371">
<td>
<xsl:value-of select="firstName"/>
</td>
<td>
<xsl:value-of select="lastName"/>
</td>
<xsl:choose>
<!--XSL equivolent to a programmatic if-else structure-->
<xsl:when test="predecessor">
<!--Test to see if there is a predecessor-->
<td>
<xsl:value-of select="key('predecessor',predecessor/@foreignKey)/firstName"/>
</td>
<td>
<xsl:value-of select="key('predecessor',predecessor/@foreignKey)/lastName"/>
</td>
</xsl:when>
<xsl:otherwise>
<!--Equivolent to else-->
<td colspan="2" style="text-align:center">
This is the first president!
</td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
|
表 6-3:总统实体的 XML 样式表 - president.xsl
- <xsl:key> 此元素是必要的声明,以便使用下面描述的 key() 函数。此元素需要三个必要的属性
- name: 此属性包含在 XSL 文件中的 key() 函数中引用的名称。name 属性中的值可以在编程术语中被认为是包含对象实例的变量,例如:在 Java 中的“String stringVariable”。
- match: 此属性类似于上面描述的 .<xsd:selector> 元素。这是 XML 文件中包含父键(关系的主键)的元素。
- use: 此属性类似于上面描述的 <xsd:field> 元素。这是包含父键值的字段。
- key(string,object) 函数:此函数根据传递给它的参数返回节点集。string 参数是在 <xsl:key> 标签的 name 属性中定义的值。object 参数是您希望获取节点的键值的主键。key('predecessor',2) 将返回包含主键为“2”的总统元素的节点。由于返回的是节点集,因此您可以使用 XPath 表达式访问返回集的子节点,就像您访问任何元素一样。因此:<xsl:value-of select="key('predecessor',2)/firstName "/> 将输出“John”。有关 key 函数的更多信息,请访问:http://www.w3.org/TR/xslt#key
- <xsl:choose> 此 XSL 元素提供了一种在 XSL 样式表中创建 if-else 类型结构的方法。这在我们的示例中是必要的,因为第一个总统将没有前任。我们只在存在前任的情况下显示前任!<xsl:choose> 元素中有两个元素可以执行此操作
- <xsl:when> 此元素相当于编程中的 'if' 语句。test 属性包含第 5 章中描述的测试语句。在上面的示例中,它只是测试前任元素是否存在(如果总统有前任)。
- <xsl:otherwise> 此元素相当于编程中的 'else' 语句。如果 <xsl:when> 语句中的测试条件失败,则显示其内容。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE stylesheet xmlns:xsl='http://www.w3.org/1999/XSL/Transform'>
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:key name="squadCaptain" match="player" use="@playerId"/>
<xsl:output method="html"/>
<xsl:template match="/">
<xsl:for-each select="//team">
<table>
<tr style="background-color:#6495ED;font-weight:bold">
<td colspan="3">
Team Id: <xsl:value-of select="@teamId"/><br />
Team Name: <xsl:value-of select="teamName"/><br />
Team Type: <xsl:value-of select="teamType"/>
</td>
</tr>
<tr style="background-color:#F0E68C;font-weight:bold">
<td>Player Id</td>
<td>Player Name</td>
<td>Player Captain</td>
</tr>
<xsl:for-each select="player">
<tr style="background-color:#D3D3D3">
<td><xsl:value-of select="@playerId"/></td>
<td><xsl:value-of select="firstName"/>&space;
<xsl:value-of select="lastName"/></td>
<xsl:choose>
<xsl:when test="squadCaptain">
<td>
<xsl:value-of select="key('squadCaptain',squadCaptain/@fk_playerId)/firstName"/>
&space;
<xsl:value-of select="key ('squadCaptain',squadCaptain/@fk_playerId)/lastName"/> </td>
</xsl:when>
<xsl:otherwise>
<td style="background-color:#FF0000;font-weight:bold">Squad Captain</td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
<br />
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
|
表 6-4:团队实体的 XML 样式表 - team.xsl
- <!doctype stylesheet[….]> - 此声明是声明实体所必需的,必须出现在 <xsl:stylesheet> 标签之前
- <!ENTITY space "<xsl:text xmlns:xsl='http://www.w3.org/1999/XSL/Transform'> </xsl:text>"> {2}- 此声明必须出现在上面显示的 doctype 声明中的方括号“[]”之间。“space” 是您要定义的实体的名称。双引号之间的值是实体所代表的内容。在上面的示例中,实体 space 代表一个空格,用 <xsl:text> </xsl:text> 语句表示。位于 <xsl:text> 元素中的 xmlns 属性仅适用于使用 Microsoft XML 解析器的解析器,但应为了跨平台兼容性而包含在内。使用此实体的语法与在 XSL 样式表中使用任何其他实体的语法相同,即一个“&”符号,后跟实体名称和一个分号。在上面的示例中,这将是 &space;,如上所示。现在,只要样式表中需要空格,就可以使用“&space;”代替 <xsl:text> </xsl:text>
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:fo="http://www.w3.org/1999/XSL/Format">
<xsl:key name="subProduct" match="accessory" use="@accessoryId"/>
<xsl:output method="html"/>
<xsl:template match="/">
<table>
<tr style="background-color:#6495ED;font-weight:bold">
<td>Accessory/Package</td>
<td>Accessory/Package Price</td>
<td>Subproduct(s)</td>
</tr>
<xsl:for-each select="//accessory">
<tr style="background-color:#D3D3D3;vertical-align:top;">
<td>
<xsl:value-of select="accessoryName"/>
</td>
<td>
<xsl:value-of select="format-number(accessoryPrice,'$###,###.00')"/>
</td>
<xsl:choose>
<xsl:when test="subProduct ">
<td>
<table>
<tr style="background-color:#F0E68C;font-weight:bold">
<td>Accessory Name</td>
<td>Accessory Price</td>
</tr>
<xsl:for-each select="subProduct">
<tr style="background-color:#7B68EE">
<td><xsl:value-of select="key('subProduct',@fk_SubProductId)/accessoryName"/></td>
<td><xsl:value-of select="format-number_
(key ('subProduct',@fk_SubProductId)/accessoryPrice,'$###,###.00')"/></td>
</tr>
</xsl:for-each>
</table>
</td>
</xsl:when>
<xsl:otherwise>
<td>N/A</td>
</xsl:otherwise>
</xsl:choose>
</tr>
</xsl:for-each>
</table>
</xsl:template>
</xsl:stylesheet>
|
表 6-9:附件实体的 XML 样式表 - accessory.xsl