10

I am trying to declare a variable that has a default value or if a value is present in a repeating set to use a new different value.

This is what I have so far.

      <xsl:variable name="lsind">
        <xsl:value-of select="'N'"/>

        <xsl:for-each select='./Plan/InvestmentStrategy/FundSplit'>
          <xsl:choose>
            <xsl:when test="contains(./@FundName, 'Lifestyle')">
              <xsl:value-of select="'Y'"/>
            </xsl:when>
          </xsl:choose>
        </xsl:for-each>
      </xsl:variable>

What I want is if any instances of ./Plan/InvestmentStrategy/FundSplit/@FundName 'contains' LifeStyle then lsind ' Y' otherwise it falls back to the default value of 'N'.

I am doing it this way as if i use 'otherwise the last occurrence could potentially set lsind back to N?

Any suggestions?

0

2 Answers 2

16
<xsl:variable name="lsind">
  <xsl:choose>
    <xsl:when test="Plan/InvestmentStrategy/FundSplit[contains(@FundName, 'Lifestyle')]">
       <xsl:text>Y</xsl:text>
    </xsl:when>
    <xsl:otherwise>
       <xsl:text>N</xsl:text>
    </xsl:otherwise>
  </xsl:choose>
</xsl:variable>

should suffice

Sign up to request clarification or add additional context in comments.

1 Comment

You are a beautiful human being. Thank you! I was just starting to explore the xpath route suspecting that there must be a way.
6

This can be specified in a single XPath expression (even in XPath 1.0):

 <xsl:variable name="vLsind" select=
 "substring('YN',
             2 - boolean(plan/InvestmentStrategy/FundSplit[@FundName='Lifestyle']),
             1)"/>

Example 1:

<plan>
 <InvestmentStrategy>
  <FundSplit FundName="Lifestyle"/>
 </InvestmentStrategy>
</plan>

Transformation:

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

 <xsl:variable name="vLsind" select=
 "substring('YN',
             2 - boolean(plan/InvestmentStrategy/FundSplit[@FundName='Lifestyle']),
             1)"/>

 <xsl:template match="/">
   <xsl:value-of select="$vLsind"/>
 </xsl:template>
</xsl:stylesheet>

Result:

Y

Example 2:

<plan>
 <InvestmentStrategy>
  <FundSplit FundName="No Lifestyle"/>
 </InvestmentStrategy>
</plan>

Result:

N

Explanation:

  1. By definition boolean(some-node-set) is true() exactly when some-node-set is non-empty.

  2. By definition number(true()) is 1 and number(false()) is 0

  3. 1 and 2 cobined gives us: number(boolean(some-node-set)) is 1 exactly when some-node-set is non-empty, otherwise it is 0.

Other single-expression solutions:

XPath 1.0:

translate(number(boolean(YourXPathExpression)), '10', 'YN')

XPath 2.0:

if(YourXPathExpression)
 then 'Y'
 else 'N'

Or even:

 ('N', 'Y')[number(boolean(YourXPathExpression)) +1]

16 Comments

+1 Those are some wonderful examples of (mis)using XPath 1.0 functions!
@Goran: Was this stated by the police department? If this is misuse, then I am in for a much bigger trouble... :)
@DimitreNovatchev. It is not misuse, but it can be very obtuse, because it masks a logical construct within an expression, which may not be good for long-term maintenance, as most, or whomever comes after them, may need to try to get their head around it every time they re-visit it.
@DimitreNovatchev. Unfortunately, the designers of XSL made it very wordy, such as using otherwise when else would have been fine. These are text files, and lots of extra characters add up to extra load times from disk. Not a worry on a small file, but large files, in conjunction with scale, can limit performance.
@DimitreNovatchev. I don't know why the designers of XML didn't reserve all the single character namespaces for core XML technologies, such as x instead of xsl. Since all my usage of XML for data doesn't use namespaces, I define xmlns:xsl="w3.org/1999/XSL/Transform"> as xmlns:x="w3.org/1999/XSL/Transform"> instead, so that all my XSL tags begin with <x: instead of <xsl:. Saves a lot of typing time.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.