Reputation: 171
Given:
<table>
<title>Inspection</title>
<tgroup/>
<tbody>
<row>
<entry>
<para>Blend well.</para>
</entry>
</row>
<row>
<entry>
<effect effrg="cde"/>
</entry>
</row>
<!-- this entry would be empty -->
<row>
<entry>
<effect effrg="cde"/>
</entry>
</row>
<row>
<entry>
<!-- first effect would create a block, second should be ignored -->
<effect effrg="abc"/>
<effect effrg="abc"/>
</entry>
</row>
</tbody>
</table>
I was trying to prevent an error caused by an empty fo:table-cell
. This could happen when the only child of <entry>
was <effect>
, and that effect/@effrg
matched the previous @effrg
, because then nothing would be printed. I wanted to minimize extraneous fo:blocks
so I thought I could use parameters as a flag:
<xsl:template match="entry/effect[not(*)]" priority="50">
<xsl:param name="need-block" as="xs:boolean" select="true()"/>
<xsl:variable name="preceding-effrg" as="xs:string?">
<xsl:call-template name="get-previous-effectivity"/>
</xsl:variable>
<xsl:variable name="effrg" as="xs:string?" select="normalize-space(@effrg)"/>
<xsl:choose>
<xsl:when test="$effrg ne $preceding-effrg">
<fo:block xsl:use-attribute-sets="effect">
<xsl:text>{$asterisks3} </xsl:text>
<xsl:apply-templates select="@effrg"/>
</fo:block>
<xsl:apply-templates>
<xsl:with-param name="need-block" as="xs:boolean" select="false()" tunnel="true"/>
</xsl:apply-templates>
</xsl:when>
<xsl:when test="$need-block="false()"/>
<!-- any other sibling elements will create a block -->
<xsl:when test="../*[local-name() ne 'effect']"/>
<xsl:when test="following-sibling::*"/>
<xsl:otherwise>
<fo:block/>
</xsl:otherwise>
</xsl:choose>
</xsl:template>
<xsl:template name="get-previous-effectivity">
<xsl:param name="pos" as="xs:integer" select="1" />
<xsl:value-of select="preceding::effect[$pos]/@effrg[normalize-space(.) != ''][1]"/>
</xsl:template>
I couldn't change the value of $need-block
in the effect
template by passing it another value. If a default value was assigned it retained that value, and if it didn't have a default value, it remained empty, even though I confirmed the parameter passing in was false()
. I tried tunneling, turning off tunneling, passing it from the parent and passing from a template where $need-block
was defaulted to false()
. When I stepped through the code it seemed to ignore the $with-param
. I've done this in xslt 1.0, is that considered bad practice?
Upvotes: 0
Views: 75
Reputation: 167716
I wonder whether you can't simply use an accumulator e.g.
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="3.0"
xmlns:xs="http://www.w3.org/2001/XMLSchema"
xmlns:fo="http://www.w3.org/1999/XSL/Format"
exclude-result-prefixes="#all"
expand-text="yes">
<xsl:mode use-accumulators="#all"/>
<xsl:param name="asterisks3" as="xs:string">***</xsl:param>
<xsl:accumulator name="last-effrg" as="xs:string?" initial-value="()">
<xsl:accumulator-rule phase="end" match="effect[@effrg]" select="normalize-space(@effrg)"/>
</xsl:accumulator>
<xsl:template match="entry/effect[not(*)][not(normalize-space(@effrg) = accumulator-before('last-effrg'))]">
<fo:block>
<xsl:text>{$asterisks3} </xsl:text>
<xsl:apply-templates select="@effrg"/>
</fo:block>
</xsl:template>
</xsl:stylesheet>
will output two
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">*** cde</fo:block>
..
<fo:block xmlns:fo="http://www.w3.org/1999/XSL/Format">*** abc</fo:block>
I think your parameter passing fails as you neeed the parameter value in siblings, not in children or descendants.
Upvotes: 0
Reputation: 163625
If you declare it as a tunnel parameter in xsl:with-param
then it will only match a parameter declared with tunnel="yes"
in xsl:param
, and vice versa.
Upvotes: 1