0

I am new to XSLT and have a similar requirement to Line Break in XSLT for a comma separated value however I need to do the following

  1. Check if the value is a single string e.g. Apples or whethe it is a comma delimited list e.g. Apples, Pears, etc
  2. If it is a comma delimited list then check if the list has a particular value or values
  3. If the value exists then do something
  4. If it is a single string e.g. Apple then do something

How can I achieve this is XSLT 2.0?

Community
  • 1
  • 1
PeanutsMonkey
  • 6,919
  • 23
  • 73
  • 103

1 Answers1

2

You can tokenize the list. A function like this might do the job (embedded in a working XSLT for demonstration purposes):

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="2.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:my="NS:MY">
  <xsl:function name="my:test">
    <xsl:param name="string"/>
    <xsl:variable name="tokens" select="tokenize(normalize-space($string),'\s*,\s*')"/>
    <xsl:choose>
      <xsl:when test="normalize-space($string)='Apples'">
        Do something where we have a single "Apples" 
      </xsl:when>
      <xsl:when test="normalize-space($string)='Pears'"> 
        Do something where we have a single "Pears" 
      </xsl:when>
      <xsl:when test="$tokens='Apples' and $tokens='Pears'"> 
        There are Apples and Pears 
      </xsl:when>
      <xsl:when test="$tokens='Apples'"> 
        There are Apples in the list 
      </xsl:when>
      <xsl:when test="$tokens='Pears'"> 
        There are Pears in the list 
      </xsl:when>
      <xsl:otherwise> 
        Didn't find what we're looking for 
      </xsl:otherwise>
    </xsl:choose>
  </xsl:function>

  <xsl:template match="/">
    <out>
      <xsl:value-of select="my:test('Apples')"/>
      <xsl:value-of select="my:test('Pears,Oranges')"/>
      <xsl:value-of select="my:test(' Apples ,Pears,Oranges')"/>
      <xsl:value-of select="my:test('Oranges , Bananas, Strawberries')"/>
    </out>
  </xsl:template>
</xsl:stylesheet>

You could also use regular expressions.

See the XPath documentation for what normalize-space() and tokenize() do. You might want to replace the bogus namespace "NS:MY" with something sensible.

Thomas W
  • 14,757
  • 6
  • 48
  • 67
  • When I try `Apples, Pears Do something where we have a single "Apples" ` as an example it fails. The error message is A sequence of more than one item is not allowed as the first argument of normalize-space() – PeanutsMonkey Nov 30 '12 at 01:25
  • Yes, you should first do `normalize-space()` (to remove leading and trailing space if necessary) and then `tokenize()`. I added some more example code above. – Thomas W Nov 30 '12 at 01:34
  • Thanks Thomas but why does it give me an error when I use my example – PeanutsMonkey Nov 30 '12 at 01:48
  • `tokenize()` returns a sequence of strings. `noramlize-space()` expects a string and not sequence. – Thomas W Nov 30 '12 at 02:07
  • Thanks. I don't quite follow. I have a sequence which I normalize. Why would it then throw an error when I normalize it again? – PeanutsMonkey Nov 30 '12 at 03:10
  • You can't normalize a sequence. It's a construct comparable to an array. You can only normalize a string. (If your comma separated values strings are guaranteed to not have leading/trailing whitespace, then you don't have to normalize anything.) – Thomas W Nov 30 '12 at 06:20