-1

I have variable (array) - [123, 456, 789]. I need to extract all the values and output. I'm using XSLT 2.0.

Sample Input XML

<xsl:param name="pNumbers" select="'[123, 456, 789]'" />

<xsl:template match="Response">
    <xsl:copy-of select="."/>
      <xsl:element name="Numbers">
        <xsl:element name="Number">
              <xsl:value-of select="$pNumbers"/>
        </xsl:element>
      </xsl:element>
</xsl:template>

I need to get

           <Numbers>
                <Number>
                  123
              </Number>
                <Number>
                  456
              </Number>
                <Number>
                  789
              </Number>
          </Numbers>

Also, the value can be one in the array - [123]

       <Numbers>
            <Number>
              123
          </Number>
      </Numbers>

Using xsl:for-each did not happen to implement this.

Upd:

Almost, but not the last element

<xsl:template name="split">
   <xsl:param name="str" select="."/>
    <xsl:choose>
      <xsl:when test="contains($str, ',')">
        <xsl:element name="Number">
          <xsl:value-of select="normalize-space(substring-before($str, ','))"/>
        </xsl:element>
        <xsl:call-template name="split">
          <xsl:with-param name="str" select="substring-after($str, ',')"/>
        </xsl:call-template>
      </xsl:when>
      <xsl:otherwise>
        <xsl:element name="Number">
            <xsl:value-of select="$pNumbers"/>
        </xsl:element>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

Upd2

Solved XSLT 1.0. All thanks.

<xsl:template name="split">
     <xsl:param name="str" select="."/>
      <xsl:choose>
        <xsl:when test="contains($str, ',')">
          <xsl:element name="Number">
            <xsl:value-of select="normalize-space(substring-before($str, ','))"/>
          </xsl:element>
          <xsl:call-template name="split">
            <xsl:with-param name="str" select="substring-after($str, ',')"/>
          </xsl:call-template>
        </xsl:when>
        <xsl:otherwise>
          <xsl:element name="Number">
              <xsl:value-of select="normalize-space($str)"/>
          </xsl:element>
        </xsl:otherwise>
      </xsl:choose>
    </xsl:template>

    <xsl:template match="Numbers">
                <xsl:element name="Number">
                                  <xsl:call-template name="split">
                <xsl:with-param name="str" select="substring-before(
                                                  substring-after(
                                                  $pNumber, '[' )
                                                  ,']' )" />
              </xsl:call-template>
            </xsl:element>
    </xsl:template>
alexdeia
  • 89
  • 1
  • 9
  • XSLT dosn't have arrays unless you use XSLT 3.0 with XPath 3.1 support. And as your data comes from an extension function it is essencial anyway that you show and explain in detail which XSLT processor you use, how your extension function looks, in which language it is written. – Martin Honnen May 23 '17 at 10:05
  • We need to know what data type is your parameter. If it's a sequence, then you can do simply `xsl:for-each` to create an element for each value. If it's a string, tokenize it. – michael.hor257k May 23 '17 at 10:11
  • I'm trying something like this https://stackoverflow.com/questions/36176206/extract-value-from-an-array-in-xslt?rq=1 – alexdeia May 23 '17 at 10:22
  • Please edit your question and show us exactly what you are doing, both in terms of XSLT as well as in terms of the XSLT processor, the programming language you write your extension function in, the API you use to call the extension function. – Martin Honnen May 23 '17 at 10:25
  • @MartinHonnen I changed the question. Link above is about what I need – alexdeia May 23 '17 at 10:42
  • 1
    I am afraid `` is not even well-formed XML so we still do not know what kind of input data you have. – Martin Honnen May 23 '17 at 10:51
  • @MartinHonnen oh god, misprint with quotes. Problem how to get the last value – alexdeia May 23 '17 at 10:57
  • `` will give you a syntax error with XSLT version 2.0 as it is XPath 3.1 syntax and therefore will only work with XSLT version 3.0 and a processor supporting that. – Martin Honnen May 23 '17 at 11:00
  • @MartinHonnen I don't have syntax errors. I just need to split the array into values. Almost got it, except for the last value. Okay thank you... – alexdeia May 23 '17 at 11:07
  • @alexdeia Is your question not answered? – michael.hor257k May 23 '17 at 11:36
  • Well, you have edited the question and its code again, now you have `` which is simply a string and not an array. And you got an answer on how to parse and tokenize that string with XSLT 2.0. – Martin Honnen May 23 '17 at 11:45

1 Answers1

1

If - as it seems - your parameter is a string, you need to tokenize it. In XSLT 2.0, this can be much simpler than what you have started to do:

XSLT 2.0

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

<xsl:param name="pNumbers" select="'[123, 456, 789]'" />

<xsl:template match="/">
    <Numbers>
        <xsl:for-each select="tokenize(substring($pNumbers, 2, string-length($pNumbers) - 2), ', ')">
            <Number>
                <xsl:value-of select="."/>
            </Number>
        </xsl:for-each>
    </Numbers>
</xsl:template>

</xsl:stylesheet>

Result

<Numbers>
   <Number>123</Number>
   <Number>456</Number>
   <Number>789</Number>
</Numbers>

If you have control over the parameter's format, then remove the surrounding square brackets. Then it will become even simpler.

michael.hor257k
  • 113,275
  • 6
  • 33
  • 51
  • That's great! oh, it works everywhere, except IBM :(. Thanks. How is the same done on XSLT 1.0? Suddenly, the IBM gives a cropped XSLT 2.0 and something strange happens.... – alexdeia May 23 '17 at 12:12
  • I am afraid I have no idea what "*IBM gives a cropped XSLT 2.0*" means. Are you using IBM DataPower as your XSLT processor? If yes, why are you asking about XSLT 2.0? – michael.hor257k May 23 '17 at 12:20
  • yes, IBM DataPower. Should have been 2.0, but apparently I was wrong. By your [old answer](https://stackoverflow.com/questions/36176206/extract-value-from-an-array-in-xslt?rq=1), i made on 1.0, but the last value does not get – alexdeia May 23 '17 at 12:29
  • That's not my answer. And IBM Data Power is an XSLT 1.0 processor. However, AFAIK it supports the EXSLT [`str:tokenize()`](http://exslt.org/str/functions/tokenize/index.html) extension function. If you want to do this without extensions, then try this as the example: https://stackoverflow.com/a/23614821/3016153 – michael.hor257k May 23 '17 at 12:41