I’m looking for a workaround on passing parameters to a template-match. I’m aware this isn’t allowed within XPath, and therefore I’m looking for a ‘plan B’ solution.
This is what I wished would work :
Part 1 of xslt (2.0) :
<xsl:template match="/">
<xsl:for-each select="//Main/PageList/Page">
<xsl:result-document href="{@ID}.xml">
<Page ID="{@ID}">
<xsl:apply-templates select="node()">
<xsl:with-param name="theID" select="@ID"/>
</xsl:apply-templates>
</Page>
</xsl:result-document>
</xsl:for-each>
</xsl:template>
So fairly straightforward, don’t bother about the tags used, what it does in essence is go through a node, and for each node it creates a single XML file. Each node starts with an ID, and it’s this ID I’d like to make available for other templates. Unfortunately this works fine for named templates, but it doesn’t work for matched ones (if I understood the theory correctly at least)
So below is what I’d like to see working :
<!-- identity template -->
<xsl:template match="node()|@*">
<xsl:param name="theID"/>
<xsl:copy>
<xsl:apply-templates select="node()|@*">
<xsl:with-param name="theID" select="$theID"/>
</xsl:apply-templates>
</xsl:copy>
</xsl:template>
<!-- lots of templates here doing what I want them to do -->
<!-- one template creating an issue -->
<xsl:template match="@src">
<!-- would be nice to know the current ID, but unfortunately this one stays empty... -->
<xsl:param name="theID"/>
<!-- clean current attribute a bit -->
<xsl:variable name="S1" select="replace(.,'\.\.\/','')"/>
<xsl:attribute name="src">
<xsl:choose>
<xsl:when test="contains($S1,'common')">
<!-- just use current value, don't bother about current ID -->
<xsl:value-of select="$S1"/>
</xsl:when>
<xsl:otherwise>
<!-- use ID parameter -->
<xsl:value-of select="concat($theID,'_',$S1)"/>
</xsl:otherwise>
</xsl:choose>
</xsl:attribute>
</xsl:template>
Don’t look at the code as such, it’s just a smaller part of the whole file, but the essence is that I want to use the ID parameter from my first part (match=”/”) inside the other template (match=”@src”), but this seems to be rather complex.
Am I missing something ? If I’m just having bad luck and it’s not possible indeed, would anyone have an advice how I could proceed ?
Thanks in advance !
Your problem is here:
the
selectattribute specifies that the processing should continue on any children nodes of the current node.However
node()only selects children nodes (elements, text nodes, processing instructions and comments) — not attributes.Solution:
—
.2. In order to cause the processing only of the
srcattribute of the current node use:—
.3. In order to process indirectly attributes tof the descendants of the current node, do:
—
You also must ensure that any template that processes
node()must have anxsl:paramnamedtheIDand that it must pass this param in anyxsl:apply-templatesinstruction.In practice this means that you mus override all XSLT built-in templates, because they aren’t aware of your
xsl:param.