在 XSLT 中执行转换链
Performing chain of transformations in XSLT
我正在尝试通过 oXygen 中的一系列 XSL 样式表转换来转换 XML 文档。我发现问题 Is daisy chaining xslt an accepted practice? 和 Dimitre Novatchev 的回答(如下)非常好:它完美地完成了两次传递。然而,我似乎无法让它在第三次通过时起作用。
<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>
我尝试添加第二个变量,如下所示(在我的问题中,我调用命名模板而不是应用于整个文档)。我所说的 template2 应该应用于 template1 执行的转换的输出。
我应该在模板 1 中的某处声明变量 $vPass2,而不是在我声明 $vPass1 的同一位置吗?或者关于它的工作原理还有什么我不明白的吗?
<xsl:template match="/">
<xsl:variable name="vPass1" >
<xsl:call-template name="template1"/>
</xsl:variable>
<xsl:apply-templates mode="pass2" select="$vPass1/*"/>
<xsl:variable name="vPass2" >
<xsl:call-template name="template2"/>
</xsl:variable>
<xsl:apply-templates mode="pass3" select="$vPass2/*"/>
</xsl:template>
谢谢
应用另一个步骤时 - 这里是第三个步骤 - 您还必须将第二个步骤的结果也放入变量中。
因此,添加链接答案中的示例,三步解决方案可能如下所示:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:template match="/*">
<xsl:copy>
<xsl:variable name="vPass1">
<xsl:apply-templates select="/*/*" />
</xsl:variable>
<xsl:variable name="vPass2">
<xsl:apply-templates mode="pass2" select="$vPass1/*" />
</xsl:variable>
<xsl:variable name="vPass3">
<xsl:apply-templates mode="pass3" select="$vPass2/*" />
</xsl:variable>
<!-- Display the final result -->
<xsl:copy-of select="$vPass3"/>
</xsl:copy>
</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:template match="num" mode="pass3">
<xsl:copy>
<xsl:value-of select=". + 1"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应用于此输入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>
结果为(2*x+1)
<nums>
<num>3</num>
<num>7</num>
<num>11</num>
<num>15</num>
<num>19</num>
</nums>
关于您的特殊问题,您的第二个 <xsl:apply-templates mode="pass2" select="$vPass1/*"/>
不在变量中 - 因此其结果不会传递给第三步。
我正在尝试通过 oXygen 中的一系列 XSL 样式表转换来转换 XML 文档。我发现问题 Is daisy chaining xslt an accepted practice? 和 Dimitre Novatchev 的回答(如下)非常好:它完美地完成了两次传递。然而,我似乎无法让它在第三次通过时起作用。
<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>
我尝试添加第二个变量,如下所示(在我的问题中,我调用命名模板而不是应用于整个文档)。我所说的 template2 应该应用于 template1 执行的转换的输出。
我应该在模板 1 中的某处声明变量 $vPass2,而不是在我声明 $vPass1 的同一位置吗?或者关于它的工作原理还有什么我不明白的吗?
<xsl:template match="/">
<xsl:variable name="vPass1" >
<xsl:call-template name="template1"/>
</xsl:variable>
<xsl:apply-templates mode="pass2" select="$vPass1/*"/>
<xsl:variable name="vPass2" >
<xsl:call-template name="template2"/>
</xsl:variable>
<xsl:apply-templates mode="pass3" select="$vPass2/*"/>
</xsl:template>
谢谢
应用另一个步骤时 - 这里是第三个步骤 - 您还必须将第二个步骤的结果也放入变量中。
因此,添加链接答案中的示例,三步解决方案可能如下所示:
<?xml version="1.0"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
<xsl:output omit-xml-declaration="yes" indent="yes" />
<xsl:template match="/*">
<xsl:copy>
<xsl:variable name="vPass1">
<xsl:apply-templates select="/*/*" />
</xsl:variable>
<xsl:variable name="vPass2">
<xsl:apply-templates mode="pass2" select="$vPass1/*" />
</xsl:variable>
<xsl:variable name="vPass3">
<xsl:apply-templates mode="pass3" select="$vPass2/*" />
</xsl:variable>
<!-- Display the final result -->
<xsl:copy-of select="$vPass3"/>
</xsl:copy>
</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:template match="num" mode="pass3">
<xsl:copy>
<xsl:value-of select=". + 1"/>
</xsl:copy>
</xsl:template>
</xsl:stylesheet>
应用于此输入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>
结果为(2*x+1)
<nums>
<num>3</num>
<num>7</num>
<num>11</num>
<num>15</num>
<num>19</num>
</nums>
关于您的特殊问题,您的第二个 <xsl:apply-templates mode="pass2" select="$vPass1/*"/>
不在变量中 - 因此其结果不会传递给第三步。