.xslt文件
XSLT的第一个版本非常严格。 它有一个输入和一个输出(尽管您可以有多个模板文件)。 标准的版本2仍将您限制为一个输入,但是输出系统更加灵活。 现在,您可以使用xsl:result-document
指令拥有多个输出文件。 这个新标签具有两个关键属性,如表1所示。
表1. xsl:result-document属性
属性 | 描述 |
---|---|
href | 输出文件的文件名或标准URL |
format | 在相应的xsl:output 指令中定义要使用的格式的名称 |
为了测试该指令,我有一个输入XML文件,其中包含一组测试结果(参见清单1)。
清单1.输入的XML文件
<?xml version="1.0" encoding="UTF-8"?>
<tests>
<testrun run="test1">
<test name="foo" pass="true" />
<test name="bar" pass="true" />
<test name="baz" pass="true" />
</testrun>
<testrun run="test2">
<test name="foo" pass="true" />
<test name="bar" pass="false" />
<test name="baz" pass="false" />
</testrun>
<testrun run="test3">
<test name="foo" pass="false" />
<test name="bar" pass="true" />
<test name="baz" pass="false" />
</testrun>
</tests>
这是非常简单的东西。 在每个测试运行中,都有一组带有通过标志的命名测试,它告诉您测试是否成功。
为每个测试创建一个文件
我要做的第一件事是为每个测试结果创建一个文件。 清单2显示了XSL模板。
清单2.为每个测试创建文件的代码
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="2.0">
<xsl:output method="text"/>
<xsl:output method="html" indent="yes" name="html"/>
<xsl:template match="/">
<xsl:for-each select="//testrun">
<xsl:variable name="filename"
select="concat('output1/',@run,'.html')" />
<xsl:value-of select="$filename" /> <!-- Creating -->
<xsl:result-document href="{$filename}" format="html">
<html><body>
<xsl:value-of select="@run"/>
</body></html>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
</xsl:stylesheet>
从文件顶部开始,有几件事值得注意。 样式表标签上的version
属性设置为2.0
以便可以使用xsl:result-document
标签。 之后,您会看到样式表本身已设置为text
作为输出类型。 这意味着,如果我希望HTML文件具有HTML格式,则需要定义html
类型的第二种命名格式。 我在xsl:result-document
标记中使用了这种格式。
从那里开始,我使用xsl:for-each
循环遍历testrun
标签。 在每个这些标记中,我使用variable
标记创建一个新的$filename
变量,该变量将输出目录名称( output1
),运行名称和.html文件扩展名连接到一个路径中。
有了这些,我就可以通过将value-of
标记与$filename
变量一起使用来告诉用户正在创建哪些文件。 然后,我使用xsl:result-document
标签打开新文档并输出HTML。 清单3显示了在示例数据文件上运行引擎时的输出。
清单3.在示例数据文件上运行时,Saxon的输出
Creating output1/test1.html
Creating output1/test2.html
Creating output1/test3.html
获得更好的输出
似乎xsl:result-document
标记的内容以与模板其余部分相同的方式进行评估是不符合直觉的,但实际上是这样。 并且模板上下文中的所有变量均可用。
为了证明这一点,我已经升级了xsl:result-document
标记中的代码,以提供有关测试结果的更多信息(请参见清单4)。
清单4.模板中更好HTML输出
<xsl:result-document href="{$filename}" format="html">
<html><head>
<title>Test results - <xsl:value-of select="@run"/></title>
</head><body>
<xsl:value-of select="@run"/> <!-- Run -->
<table>
<tr><td>Test</td><td>Pass</td></tr>
<xsl:for-each select="test">
<tr><td>
<xsl:value-of select="@name" />
</td><td>
<xsl:value-of select="@pass" />
</td></tr>
</xsl:for-each>
</table>
</body></html>
</xsl:result-document>
有关此输出HTML结果,请参见清单5。
清单5.升级HTML输出
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8">
<title>Test results - test1</title>
</head>
<body>
<!-- Run: test1-->
<table>
<tr>
<td>Test</td>
<td>Pass</td>
</tr>
<tr>
<td>foo</td>
<td>true</td>
</tr>
<tr>
<td>bar</td>
<td>true</td>
</tr>
<tr>
<td>baz</td>
<td>true</td>
</tr>
</table>
</body>
</html>
创建一个索引
最后,我需要添加一个指向所有输出测试结果的索引文件。 为此,我使用了另一个xsl:result-document
标记并将输出硬编码到索引文件中(请参见清单6)。
清单6.构建索引文件的代码
<!-- Creating the index -->
<xsl:result-document href="output3/index.html"
format="html">
<html><head><title>Test Index</title></head>
<body>
<xsl:for-each select="//testrun">
<a href="{@run}.html"><xsl:value-of select="@run" />
</a><br/>
</xsl:for-each>
</body>
</html>
</xsl:result-document>
本节xsl:for-each
循环之后,该循环为每个测试用例构建HTML文件。 清单7显示了示例数据集的索引文件。
清单7.索引文件
<html>
<head>
<meta http-equiv="Content-Type"
content="text/html; charset=UTF-8">
<title>Test Index</title>
</head>
<body><a href="test1.html">test1</a><br>
<a href="test2.html">test2</a><br>
<a href="test3.html">test3</a><br></body>
</html>
摘要
使用xsl:result-document
指令,可以将单个XSL模板从单个数据源输出到多个文件。 此功能是XSLT 1.x中的非标准扩展,它为XSLT模板作者打开了无限的机会。
翻译自: https://www.ibm.com/developerworks/opensource/library/x-tipmultxsl/index.html
.xslt文件