我有一种情况,我认为我需要菊花链我的xslt转换(即一个xslt转换的输出被输入到另一个).第一个转换相当复杂,有很多xsl:choice和ancestor xpaths.我的想法是将xml转换为xml,然后可以很容易地转换为html.
我的问题是'这是标准做法还是我错过了什么?'
提前致谢.
斯蒂芬
Dim*_*hev 10
在XSLT应用程序中经常使用执行转换链,但在XSLT 1.0中完全执行此操作需要使用特定于供应商的xxx:node-set()函数.在XSLT 2.0中,不需要这样的扩展,因为那里消除了臭名昭着的RTF数据类型.
这是一个例子(太简单而无意义,但完全说明了如何完成):
<xsl:stylesheet version="1.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:ext="http://exslt.org/common">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="vrtfPass1">
<xsl:apply-templates select="/*/*"/>
</xsl:variable>
<xsl:variable name="vPass1"
select="ext:node-set($vrtfPass1)"/>
<xsl:apply-templates mode="pass2"
select="$vPass1/*"/>
</xsl:template>
<xsl:template match="num[. mod 2 = 1]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="num" mode="pass2">
<xsl:copy>
<xsl:value-of select=". *2"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
当此转换应用于以下XML文档时:
<nums>
<num>01</num>
<num>02</num>
<num>03</num>
<num>04</num>
<num>05</num>
<num>06</num>
<num>07</num>
<num>08</num>
<num>09</num>
<num>10</num>
</nums>
Run Code Online (Sandbox Code Playgroud)
产生了想要的正确结果:
<num>2</num>
<num>6</num>
<num>10</num>
<num>14</num>
<num>18</num>
Run Code Online (Sandbox Code Playgroud)
说明:
在第一步中,XML文档被转换,结果被定义为变量的值$vrtfPass1.这仅复制num具有奇数值(不均匀)的元素.
的$vrtfPass1变量,作为类型RTF的,不是用于XPath表达式直接可用的,所以我们将其转换为正常树,使用EXSLT(由最XSLT 1.0处理器实现)函数ext:node-set-和限定另一个变量$vPass1,其值是此树.
我们现在在我们的转换链中执行第二次转换 - 在第一次转换的结果上,保持为变量的值$vPass1.不要混淆第一遍模板,我们指定新处理应该处于命名模式,称为"pass2".在此模式下,任何num元素的值乘以2.
XSLT 2.0解决方案(无RTF):
<xsl:stylesheet version="2.0"
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema">
<xsl:output omit-xml-declaration="yes" indent="yes"/>
<xsl:template match="/">
<xsl:variable name="vPass1" >
<xsl:apply-templates select="/*/*"/>
</xsl:variable>
<xsl:apply-templates mode="pass2"
select="$vPass1/*"/>
</xsl:template>
<xsl:template match="num[. mod 2 = 1]">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="num" mode="pass2">
<xsl:copy>
<xsl:value-of select=". *2"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
Run Code Online (Sandbox Code Playgroud)
我不认为这是标准做法,特别是因为您可以将一种 XML 方言直接转换为另一种方言。
然而,如果处理很复杂,将其分成几个步骤(在每个步骤中应用不同的变换)确实可以简化每个步骤并且有意义。
这确实取决于具体情况。