<tr>
<td>2-inch widgets</td>
<td>13.50</td>
</tr>
<tr>
<td>1-inch bolts</td>
<td>4.00</td>
</tr>
</table>
</body>
</html>
需要在样式表中创建一系列模板。这些模板处理您要带入输出文档的每个不同元素。每个模板还必须创建支持的 xhtml 元素结构,例如表标题和行。使用推方法从源文档(清单 1)创建清单 2 中所示的输出的样式表类似于下面的样子:
清单 3. 用于数据的样本推样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform"
version="1.0">
<xsl:template match="orders">
<html>
<body>
<xsl:apply-templates select="invoice"/>
</body>
</html>
</xsl:template>
<xsl:template match="invoice">
<xsl:apply-templates select="customername" />
<p>
<xsl:apply-templates select="address" />
<xsl:apply-templates select="city" />
<xsl:apply-templates select="state" />
<xsl:apply-templates select="zip" />
</p>
<table>
<tr>
<th>description</th>
<th>cost</th>
</tr>
<xsl:apply-templates select="item" />
</table>
<p />
</xsl:template>
<xsl:template match="customername">
<h1><xsl:value-of select="." /></h1>
</xsl:template>
<xsl:template match="address">
<xsl:value-of select="." /><br />
</xsl:template>
<xsl:template match="city">
<xsl:value-of select="." />
<xsl:text>, </xsl:text>
</xsl:template>
<xsl:template match="state">
<xsl:value-of select="." />
<xsl:text> </xsl:text>
</xsl:template>
<xsl:template match="zip">
<xsl:value-of select="." />
</xsl:template>
<xsl:template match="item">
<tr>
<xsl:apply-templates />
</tr>
</xsl:template>
<xsl:template match="description">
<td><xsl:value-of select="." /></td>
</xsl:template>
<xsl:template match="totalcost">
<td><xsl:value-of select="." /></td>
</xsl:template>
<xsl:template match="*">
<xsl:apply-templates />
</xsl:template>
<xsl:template match="text()" />
</xsl:stylesheet>
请注意:有两个令人感兴趣的添加项,您应当将它们包括在样式表中:
最后的空模板确保从输出文档中省去多余内容(如发票上项目的单价)。
以文档次序处理其所有子元素的模板确保处理自始至终都沿着源树进行。那样,您不会仅因为没有特定的发票模板而丢失任何发票内容。
正如您看到的那样,这种结构有点臃肿。虽然制作代码是非常简单的,但维护代码是棘手的。即使对于这个十分简单的示例,如果您要查明 xhtml 表是如何填充的,那么就必须从一个模板跳到另一个模板来发现 td 对象的创建位置。在更复杂的示例中,可能会有许多页的模板,许多模板都是从其它模板调用的。代码的维护也更困难。
拉样式表
另一方面,拉样式表依靠编码者的能力来知道接下来期望源文档中的哪些元素出现。通过重复元素、在输出中创建适当的结构以及根据需要从源文档中拉出值,代码可以显式地进行循环处理。这里是一个执行与清单 2 相同转换的样式表,但它使用拉策略,而不是推策略:
清单 4. 用于数据的样本拉样式表
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/xsl/transform"
version="1.0">
<xsl:template match="orders">
<html>
<body>
<xsl:for-each select="invoice">
<h1>
<xsl:value-of select="customername" />
</h1>
<p>
<xsl:value-of select="address" /><br />