Question

I have following xml element in the source and would like to map to an element in the target.

Whenever there is no node in the source, I want to default it to a string "None"

--------------------------Source XML----------------------------------------------

<?xml version="1.0" encoding="UTF-8"?>
<Instructions  InstructionType="Gen">Some Message</Instructions>
<Instructions  InstructionType="Test">Some Other Message</Instructions>

---------------------------Transformation XSL--------------------------------------

<xsl:if test='/ns1:OrderResponse/ns1:OrderResponseBody/ns1:OrderResponseProperties/ns1:Instructions/@InstructionType = "Gen"'>
    <xsl:choose>
        <xsl:when test='/ns1:OrderResponse/ns1:OrderResponseBody/ns1:OrderResponseProperties/ns1:Instructions[@InstructionType = "Gen"] != ""'>
            <ns0:siGen>
                <xsl:value-of select='substring(/ns1:OrderResponse/ns1:OrderResponseBody/ns1:OrderResponseProperties/ns1:Instructions[@InstructionType = "Gen"],1.0,199.0)'/>
            </ns0:siGen>
        </xsl:when>
        <xsl:when test="not(/ns1:OrderResponse/ns1:OrderResponseBody/ns1:OrderResponseProperties/ns1:Instructions[@InstructionType = 'Gen'])">
            <ns0:siGen>
                <xsl:text disable-output-escaping="no">None</xsl:text>
            </ns0:siGen>
        </xsl:when>
        <xsl:otherwise>
            <ns0:siGen>
                <xsl:text disable-output-escaping="no">None</xsl:text>
            </ns0:siGen>
        </xsl:otherwise>
    </xsl:choose>
</xsl:if> 

---------------------------------------------Issue-------------------------------------------------------------

When the source xml doesn't have the the node at all as shown below (commented), I cannot default the value "None" to the target element "ns0:siGen"

<!--Instructions  InstructionType="Gen">Some Message</Instructions-->

<Instructions  InstructionType="Test">Some Other Message</Instructions>

I dont understand why the below condition is not working:

<xsl:when test="not(/ns1:OrderResponse/ns1:OrderResponseBody/ns1:OrderResponseProperties/ns1:Instructions[@InstructionType = 'Gen'])">

Please advise.

Thanks

Yogi

Was it helpful?

Solution

The very first line in your XSLT sample says this...

<xsl:if   
     test='/ns1:OrderResponse/ns1:OrderResponseBody/ns1:OrderResponseProperties/ns1:Instructions/@InstructionType = "Gen"'>

i.e. You are testing if there is an Instructions element which has an InstructionType equal to "Gen". So, obviously if you comment this Instructions element, the statement will be false, and so your xsl:choose inside the statement will not be executed.

To simplify things, consider putting the instructions element in a variable

<xsl:variable name="gen" 
              select="ns1:OrderResponse/ns1:OrderResponseBody/ns1:OrderResponseProperties/ns1:Instructions[@InstructionType = 'Gen']" />

Then you can have a simple xsl:choose to test this

 <ns0:siGen>
    <xsl:choose>
       <xsl:when test="$gen != ''"><xsl:value-of select="$gen" /></xsl:when>
       <xsl:otherwise>None</xsl:otherwise>
    </xsl:choose>
 <ns0:siGen>
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top