XSL Remove tag if temperature > 20 otherwise copy tag

Viewed 271

So I have to transform this XSL with the condition if temperature > 20 remove tag otherwise copy temperature So far I got something like this

<?xml version="1.0" ?>
<message-in>
    <realised-gps>
        <id>64172068</id>
        <resourceId>B-06- KXO</resourceId>
            <position>
                <coordinatesystem>Standard</coordinatesystem>
                <latitude>44.380765</latitude>
                <longitude>25.9952</longitude>
            </position>
        <time>2011-05- 23T10:34:46</time>
        <temperature>21.01</temperature> 
        <door>0</door>
    </realised-gps>
</message-in>

This is only removing the tag I can't make the otherwise or other if condition

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output indent="yes"/>
<xsl:strip-space elements="*"/>

<xsl:template match="@*|node()">
    <xsl:copy>
        <xsl:apply-templates select="@*|node()"/>
    </xsl:copy>
</xsl:template> 

<xsl:template match="temperature">
        <xsl:if test="temperature &gt; 20">
            <xsl:apply-templates />
        </xsl:if>           
        <xsl:if test="temperature &lt;= 20">
            <xsl:copy>
                <xsl:apply-templates select="//temperature|node()"/>
            </xsl:copy>
        </xsl:if>
</xsl:template>
</xsl:stylesheet>

Expected Output File for temperature < than 20

<?xml version="1.0" ?>
<message-in>
    <realised-gps>
        <id>64172068</id>
        <resourceId>B-06- KXO</resourceId>
            <position>
                <coordinatesystem>Standard</coordinatesystem>
                <latitude>44.380765</latitude>
                <longitude>25.9952</longitude>
            </position>
        <time>2011-05- 23T10:34:46</time>
        <temperature>15</temperature> 
        <door>0</door>
    </realised-gps>
</message-in>
1 Answers

Instead of doing this....

<xsl:if test="temperature &gt; 20">

You need to do this...

<xsl:if test=". &gt; 20">

Because you are in a template matching temperature already, the test temperature &gt; 20 is going to look for a child element also called temperature, when really all you want to check is the value of the current node.

Also, instead of doing this, which will end up recursively matching the same template

<xsl:apply-templates select="//temperature|node()"/>

You can just do this....

<xsl:apply-templates />

So you template could look like this...

<xsl:template match="temperature">
        <xsl:if test=". &gt; 20">
            <xsl:apply-templates />
        </xsl:if>           
        <xsl:if test=". &lt;= 20">
            <xsl:copy>
                <xsl:apply-templates />
            </xsl:copy>
        </xsl:if>
</xsl:template>

However, there is an easy way. Instead of the above template, simply be more specific with the template match for the node you wish to remove....

<xsl:template match="temperature[. &gt; 20]" />

Try this XSLT

<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:output indent="yes"/>
    <xsl:strip-space elements="*"/>

    <xsl:template match="@*|node()">
        <xsl:copy>
            <xsl:apply-templates select="@*|node()"/>
        </xsl:copy>
    </xsl:template> 

    <xsl:template match="temperature[. &gt; 20]" />
</xsl:stylesheet>
Related