xslt-1.0apply-templates

Apply templates that matchs two conditions


I need to list all the INST names but only if the "onlyTesters" node don´t exists in the "inst/idef" part of XML body above.

I know thats strange but I can´t change the XML I receive.

XML:

<river>
    <station num="699">
        <inst name="FLU(m)" num="1">
            <idef></idef>
        </inst>
        <inst name="Battery(V)" num="18">
            <idef>
                <onlyTesters/>
            </idef>
        </inst>
    </station>
    <INST name="PLU(mm)" num="0" hasData="1" virtual="0"/>
    <INST name="FLU(m)" num="1" hasData="1" virtual="0"/>
    <INST name="Q(m3/s)" num="3" hasData="1" virtual="1"/>
    <INST name="Battery(V)" num="18" hasData="1" virtual="0"/>
</river>

XSL:

<xsl:template match="/">
    <xsl:apply-templates select="//INST[@hasData = 1 and not(//inst[@num=(current()/@num)]/idef/onlyTesters)]/@name"/>
 </xsl:template>

<xsl:template match="//INST[@hasData = 1 and not(//inst[@num=(current()/@num)]/idef/onlyTesters)]/@name">
    <xsl:value-of select="@name"/>,
</xsl:template>

I´m having no match.

This is the result I expect:

PLU(mm),FLU(m),Q(m3/s)

Solution

  • You can achieve this with only one template:

    <xsl:template match="/">
        <xsl:for-each select="//INST[@hasData='1' and not(@name=//inst[idef/onlyTesters]/@name)]">
            <xsl:value-of select="@name"/>
            <xsl:if test="position() != last()">, </xsl:if>
        </xsl:for-each>
    </xsl:template>
    

    Output is:

    PLU(mm), FLU(m), Q(m3/s)