XSLT 是一种用于将 XML 文档转换为 XHTML 文档或其他 XML 文档的语言。这种转换通常由专用的软件或者浏览器执行。目前,绝大多数主流的浏览器支持XSLT转换。XSLT本质上也是一个XML文档,因此它的编写也是要遵循XML的基本规范。XSLT中有很多元素,此处总结一下<xsl:apply-templates>的使用方法。
假设有如下一个XML文档。
其中加粗的部分,是为了能够使得浏览器能够转换该XML文档而引入指令语句,表示引入一个example.xslt文件
那么任务的重点实际上是编辑符合规范的example.xsl文件。我们一步一步完善这个XSLT文件。首先加入 <xsl:template match="/">
节点,如下:
该节点中,match="/"表示匹配需转换的xml文件中的根结点,这是一个XPath的路径表达式,(XPath 是一门在 XML 文档中查找信息的语言。XPath 可用来在 XML 文档中对元素和属性进行遍历,如果需要了解更多关于XPath的信息,可以参考http://www.w3school.com.cn/xpath/index.asp)。因此 <xsl:template match="/"> </xsl:template> 也就表示了把需要转换的XML文档的根结点内的内容换成 <xsl:template match="/"> </xsl:template> 中的内容。即转换后变成了:
<html>
<body>
<h2>职员列表清单</h2>
</body>
</html>
因此在IE中显示的内容如下:
接下来可以使用<xsl:apply-templates>,<xsl:apply-templates>类似一个函数,对 <xsl:template match="/"> 中的每一个元素做一次转换。 <xsl:apply-templates> 总是包含在 <xsl:template >中的。
如果在XSLT中加了<xsl:apply-templates>,即如下:
那么,默认的显示了当前template中的根元素的值,因为当前template中的match是"/",对应的内容是XML文档中的<company>节点的内容,因此把company节点下的元素值都显示了,如下:
这类直接获取了company节点下的值,并且也没指定要如何转换,因此等价于下面的写法:
如果只要获取staff的值,那么在select的时候,指定staff节点既可以了。
或者,也可以同时修改template的match值:
显示的内容都是一样的,如下图:
事实上,上例中,我们定义了模板,改模板只要求匹配"/"即根结点元素,对于根结点内的子元素,如何转换并无响应的模板来指明,因此下一步,在定义一个新的模板,来指明如何对staff元素实行转换:
此处添加了一个新的模板,这个模板只对staff元素生效。因此,在上面<xsl:apply-templates select="company/staff"/>应用这个模板时,检测到下面有对应的模板,就会根据该模板来转换当前的元素。因此显示效果如下:
也就是说,相当于把XML转换成了如下的html代码:
<html>
<body>
<h2>职员列表清单</h2>
<b>姓名:张三</b>: 性别:male年龄:30
<b>姓名:李四</b>: 性别:female年龄:22
</body>
</html>
更完善的,我们可以再添加一个模板,显示老板的信息,如下:
转换结果如下:
至此, <xsl:apply-templates />的使用方法也有大致的解了,总结一下:
<xsl:apply-templates/>总是包含在<xsl:template />中,当转换软件遇到这个语句时,就会对 <xsl:apply-templates/>所匹配的元素进行转换(所匹配的元素由select属性设置,该值是一个XPath中的路径表达式,并且和<xsl:template />中的match相关)。
<xsl:apply-templates/>在对元素应用模板的时候,会去文档中查看是否存在一个对应的模板(即该模板定义了如何转换 <xsl:apply-templates/>匹配的元素)。所谓处理转换,实际上就是把XML文档中的值,代入模板,并输出代入后的模板内容,类似变量赋值。
网上看到一篇文章http://www.cnblogs.com/it_mac/archive/2010/06/27/1766151.html,作者列出了他的错误。实际上,错误是由于第18行<xsl:apply-templates/>,该语句的执行,是在<xsl:template match="cd">下,即在对cd下的元素做转换的时候。cd下有3个子元素title,artist和tracks,这3个子元素都会做转换,只不过由于并未找到和title,artist元素相对应的模板,因此把他们按文本的形式输出了,所以转换的结果就如作者写的那样。
这里只需要做一个小改动,把语句改成<xsl:apply-templates select="tracks"/>即可,这表示,对cd下的元素,只选择tracks元素做转换,就解决问题了。