Search code examples
xmlxsltqt4

XSLT: apply-templates with directly invoked rule, param stays empty (Qt4 XSLT processor)


I'm trying to send some variables down to a template through apply-templates which has a direct match-rule, but the variables arrive empty in the matched template. I suspect this is a missing feature or bug in the Qt4 XSLT-processor.

Here's my example XML:

<Appointments>
  <Data>
    <Appointment StartDateTime="2017-11-20T13:00:00">
      <stay name="Hans Wu"/>
    </Appointment>
  </Data>
</Appointments>

An here's the XSLT:

<xsl:stylesheet xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:fn="http://www.w3.org/2005/xpath-functions"
xmlns:xs="http://www.w3.org/2001/XMLSchema">

<xsl:template match="/">                
    <xsl:apply-templates select="/Appointments/Data/Appointment"/>
</xsl:template>

<xsl:template match="Appointment">
    <xsl:variable name="StartTime" select="@StartDateTime"/>
    <xsl:variable name="TestParam" select="'TestParam'"/>

    <div>
        <xsl:text>--- </xsl:text>
        <xsl:value-of select="$StartTime"/>
        <xsl:text> ---</xsl:text>
    </div>

    <xsl:apply-templates select="stay">
        <xsl:with-param name="StartTime" select="$StartTime"/>
        <xsl:with-param name="TestParam" select="$TestParam"/>
    </xsl:apply-templates>
</xsl:template>

<xsl:template match="stay">
    <xsl:param name="StartTime"/>
    <xsl:param name="TestParam"/>

    <div>
        <xsl:text>### </xsl:text>
        <xsl:value-of select="$StartTime"/>
        <xsl:text> ###</xsl:text>
    </div>

    <div>
        <xsl:text>$$$ </xsl:text>
        <xsl:value-of select="$TestParam"/>
        <xsl:text> $$$</xsl:text>
    </div>

</xsl:template>

I'd expect the resulting HTML to also contain the timestamp within the "###"-text, but this is not the case when I run this in my Qt4-environment:

<div>--- 2017-11-20T13:00:00 ---</div>
<div>###  ###</div>
<div>$$$ TestParam $$$</div>

As this works just as expected in oxygenDeveloper and should be a standard feature - is this a bug resp. missing in the built-in XSLT-Processor of Qt4?

Other similar answers suggested that the XSLT built-in template matches and won't pass through the parameters. Since I'm directly calling the matching "stay" template, as demonstrated by the "TestParam", I assume the issue from this question does not apply here.


Solution

  • As it appears, this is indeed an issue with the Qt4-XSLT-processor.

    However, the workaround/solution is pretty obvious and simple once I stopped thinking within the cramped boundaries of variables and params and looked at the bigger picture.

    Here's the XSLT that works for me:

    <xsl:template match="/">                
        <xsl:apply-templates select="/Appointments/Data/Appointment"/>
    </xsl:template>
    
    <xsl:template match="Appointment">
        <xsl:variable name="StartTime" select="@StartDateTime"/>
        <xsl:variable name="TestParam" select="'TestParam'"/>
    
        <div>
            <xsl:text>--- </xsl:text>
            <xsl:value-of select="$StartTime"/>
            <xsl:text> ---</xsl:text>
        </div>
    
        <xsl:apply-templates select="stay">
            <xsl:with-param name="TestParam" select="$TestParam"/>
        </xsl:apply-templates>
    </xsl:template>
    
    <xsl:template match="stay">
        <xsl:param name="TestParam"/>
    
        <div>
            <xsl:text>### </xsl:text>
            <xsl:value-of select="../@StartDateTime"/>
            <xsl:text> ###</xsl:text>
        </div>
    
        <div>
            <xsl:text>$$$ </xsl:text>
            <xsl:value-of select="$TestParam"/>
            <xsl:text> $$$</xsl:text>
        </div>
    
    </xsl:template>
    

    The significant difference here is that in the stay-Template I select ../@StartDateTime instead of the variable from the param:

    <xsl:value-of select="../@StartDateTime"/>
    

    So I select the StartDateTime-attribute directly from the parent-element, simple as that.

    Works for my case, might not work if you have a more difficult structure where you need to use a variable.