multix
multix

Reputation: 15

Store condition test in variable

I am quite new to XSLT and need to transform an address xml file. I need to store the result of an condition test in a variable, I want to use it later in the same template.

Here my source xml:

<?xml version="1.0" encoding="UTF-8"?>
<message>
<partner>
    <addressInfo>
        <addressUsage>
            <Code>Default</Code>
            <Main>false</Main>
        </addressUsage>
        <addressUsage>
            <Code>BILL_TO</Code>
            <Main>false</Main>
        </addressUsage>
        <Address>...</Address>
    </addressInfo>
    <addressInfo>
        <addressUsage>
            <Code>SHIP_TO</Code>
            <Main>false</Main>
        </addressUsage>
        <addressUsage>
            <Code>BILL_TO</Code>
            <Main>true</Main>
        </addressUsage>
        <Address>...</Address>
    </addressInfo>
</partner>
</message>

Now, I need to know if there is an address with code "BILL_TO" and Main = "true". I need to store this in a variable. But in my test I always fail.

Here my XSLT:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" >

<xsl:output method="xml" indent="yes" omit-xml-declaration="yes"/>

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


<xsl:template match="partner">
    <partner>
    <xsl:variable name="main_bill_to">
        <xsl:choose>
            <xsl:when test="(./addressInfo/addressUsage/Code = 'BILL_TO' and Main = 'true')">
                <xsl:value-of select="'Y'" />
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="'N'" />
            </xsl:otherwise>
        </xsl:choose>
    </xsl:variable> 

    <xsl:if test="($main_bill_to = 'Y')">
        <result>yes</result>
    </xsl:if>

    <xsl:if test="($main_bill_to = 'N')">
        <result>no</result>
    </xsl:if>
    </partner>
</xsl:template>
</xsl:stylesheet>

I always get the output "no".

<message>
    <partner>
       <result>no</result>
    </partner>
</message>

Any idea? Many thanks!

Upvotes: 0

Views: 254

Answers (1)

Tim C
Tim C

Reputation: 70648

This expression is not quite right...

<xsl:when test="(./addressInfo/addressUsage/Code = 'BILL_TO' and Main = 'true')">

You are actually asking "Is there an element addressInfo/addressUsage/Code (under partner) equal to 'BILL_TO', and is there also an element Main (under partner) equal to 'true'".

In other words, it is looking for an element named Main under partner, not under the same addressUsage as the Code element you are checking.

You need to do this...

<xsl:when test="addressInfo/addressUsage[Code = 'BILL_TO' and Main = 'true']">

So, this is now asking "Is there an addressInfo/addressUsage element which has both Code set to 'BILL_TO' and Main set to 'true'"?

Note the ./ is not really necessary, which is why I removed it.

Also note, you don't really need to go to all the trouble of using an xsl:choose to set the variable to "Y" or "N". You can, in this case, simplify the code block to this....

<xsl:template match="partner">
  <partner>
    <xsl:variable name="main_bill_to" select="addressInfo/addressUsage[Code = 'BILL_TO' and Main = 'true']" />

    <xsl:if test="$main_bill_to">
        <result>yes</result>
    </xsl:if>

    <xsl:if test="not($main_bill_to)">
        <result>no</result>
    </xsl:if>
  </partner>
</xsl:template>

So now, you are checking if an element exists to determine what to display.

Upvotes: 1

Related Questions