Reputation: 45
I encountered a strange issue while I was trying to build an XSLT stylesheet that takes a parameter and applies appropriate templates based on a string value of that parameter. Here is my code:
<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
version="3.0" default-mode="s">
<xsl:mode name="s" streamable="yes" on-no-match="shallow-skip"/>
<xsl:mode name="ns" streamable="no"/>
<xsl:output method="xml" indent="yes"/>
<xsl:param name="TemplateName" as="xs:string"/>
<xsl:template match='/' mode="s">
<File>
<xsl:apply-templates mode="s"/>
</File>
</xsl:template>
<xsl:template match="Employee">
<xsl:choose>
<xsl:when test="$TemplateName = 'Template1'">
<xsl:apply-templates select="Template1"/>
</xsl:when>
<xsl:when test="$TemplateName = 'Template2'">
<xsl:apply-templates select="Template2"/>
</xsl:when>
<xsl:when test="$TemplateName = 'Template3'">
<xsl:apply-templates select="Template3"/>
</xsl:when>
<xsl:when test="$TemplateName = 'Template4'">
<xsl:apply-templates select="Template4"/>
</xsl:when>
</xsl:choose>
</xsl:template>
<xsl:template match="Template1">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="Template2">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="Template3">
<xsl:copy-of select="."/>
</xsl:template>
<xsl:template match="Template4">
<xsl:copy-of select="."/>
</xsl:template>
</xsl:stylesheet>
Everything works without any issues as long as I have only 3 "xsl:when" conditions in my "xsl:choose" code. As soon as I add the 4th condition:
<xsl:when test="$TemplateName = 'Template4'">
<xsl:apply-templates select="Template4"/>
</xsl:when>
I receive the following error:
Template rule is declared streamable but it does not satisfy the streamability rules. * There is more than one consuming operand: {xsl:apply-templates} on line 25, and {xsl:apply-templates} on line 28
I am using Saxon-EE 9.7.0.19.
What is causing this issue? Is there any other way to apply templates dynamically based on input parameter?
Input XML:
<?xml version="1.0" encoding="UTF-8"?>
<Root>
<Employee>
<Template1>SomeData1</Template1>
<Template2>SomeData2</Template2>
<Template3>SomeData3</Template3>
<Template4>SomeData4</Template4>
</Employee>
<Employee>
<Template1>SomeData1</Template1>
<Template2>SomeData2</Template2>
<Template3>SomeData3</Template3>
<Template4>SomeData4</Template4>
</Employee>
<Employee>
<Template1>SomeData1</Template1>
<Template2>SomeData2</Template2>
<Template3>SomeData3</Template3>
<Template4>SomeData4</Template4>
</Employee>
</Root>
Upvotes: 0
Views: 288
Reputation: 163458
Please try it on a more recent Saxon release (9.9 or 10.0). The streaming capabilities in the product advanced considerably since 9.7 was released back in 2015. (The XSLT 3.0 spec wasn't even published then.)
Upvotes: 0