xslt-1.0apply-templates

Using xsl:apply-templates with conditional filtering


This snippet works correctly:

<xsl:template match="msa:Group">
    <h2>
        <xsl:value-of select="."/>
    </h2>

    <xsl:variable name="iGroupId" select="@Id"/>

    <xsl:apply-templates select="$PubDB/msa:PublisherDatabase/msa:Publishers/msa:Publisher[msa:GroupId=$iGroupId]">
            <xsl:sort select="msa:Name" data-type="text" order="ascending"/>
    </xsl:apply-templates>
</xsl:template>

What I want to know is why I had to save @Id to a variable and use that in the xpath statement. This failed:

select="$PubDB/msa:PublisherDatabase/msa:Publishers/msa:Publisher[msa:GroupId=@Id]"

Solution

  • Your attempt:

    select="$PubDB/msa:PublisherDatabase/msa:Publishers/msa:Publisher[msa:GroupId=@Id]"
    

    would select all msa:Publisher elements whose msa:GroupId child is equal to their @Id attribute.

    In order to refer to the @Id attribute of the current msa:Group element, you need to use the current() function:

    select="$PubDB/msa:PublisherDatabase/msa:Publishers/msa:Publisher[msa:GroupId=current()/@Id]"
    

    Read the explanation in the specification:
    https://www.w3.org/TR/1999/REC-xslt-19991116/#function-current


    P.S Consider using a key to resolve cross-references.