Search code examples
xsltapply-templates

How can I execute an apply-templates on all non-selected elements within a xsl:copy?


Let's say I have the following XSLT:

<xsl:template match="DTS:Executable[@DTS:ExecutableType='SSIS.Package.2' or @DTS:ExecutableType='MSDTS.Package.1']">
    <xsl:copy>
        <xsl:apply-templates select="@*"/>
        <xsl:apply-templates select="./DTS:Property"/>
        <xsl:apply-templates select="./DTS:ConnectionManager"/>
        <xsl:apply-templates select="./DTS:Configuration"/>
        <xsl:apply-templates select="./DTS:LogProvider"/>
    </xsl:copy>
</xsl:template>

I realize that if there are other node types, such as DTS:Variable, they'll be filtered from the produced XML since no apply-templates statement selects them.

My question is: how can I conclude the copy with an apply-templates statement that selects all elements not specified in the previous apply-templates statements?

I've tried something like:

    <xsl:apply-templates select="./node()[name!='DTS:Property' and name!='DTS:ConnectionManager' and name!='DTS:Configuration' and name!='LogProvider']" /> 

but that doesn't seem to work.


Solution

  • You should be using the function name() and not just name in your expression. Also note the ./ is superfluous here, so you can just write this.....

    <xsl:apply-templates select="node()[name()!='DTS:Property' and name()!='DTS:ConnectionManager' and name()!='DTS:Configuration' and name()!='LogProvider']" />
    

    Alternatively, it could be shorter to write the following

    <xsl:apply-templates select="node()[not(self::DTS:Property|self::DTS:ConnectionManager|self::DTS:Configuration|self::LogProvider)]" />