0

Thanks in advance for your support. I was just stuck with a problem and tried a lot in all ways.

I have an XSLT 1.0 that need to parse the value of an xml tag by comma and store it in array.

<OPTIONS>val1,,val2,val3,,,val4</OPTIONS>

Here I need to parse the OPTIONS field value by comma and then store it in array. Here I was stuck with the way of storing it in array for further use.

Please advice

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    version="1.0">
    <xsl:output method="text" omit-xml-declaration="yes"/>
    <xsl:variable name="inline-array">
        <!--<Item>A</Item>
        <Item>B</Item>
        <Item>C</Item>-->

        <xsl:call-template name="splitByComma">
            <xsl:with-param name="str" select="OPTIONS"/>
        </xsl:call-template>
    </xsl:variable>

    <xsl:template match="/">
        <xsl:param name="array" select="document('')/*/xsl:variable[@name='inline-array']/*"/>
        <xsl:value-of select="$array[1]"/>          
    </xsl:template>

    <xsl:template name="splitByComma">
        <xsl:param name="str"/>
        <xsl:choose>
            <xsl:when test="contains($str,',')">
                <item><xsl:value-of select="substring-before($str,',')"/></item>
                <xsl:call-template name="splitByComma">
                    <xsl:with-param name="str"
                        select="substring-after($str,',')"/>
                </xsl:call-template>
            </xsl:when>
            <xsl:otherwise>
                <item><xsl:value-of select="$str"/></item>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

1 Answer 1

3

I think this couldn't work in XSLT 1.0 because when you are trying to load content of variable inline-array from the stylesheet (i.e. <xsl:param name="array" select="document('')/*/xsl:variable[@name='inline-array']/*"/>) you actually load its definition. Thus it contains element <xsl:call-template... with child <xsl:with-param... not the result of evaluating it.

enter image description here

So in this case you have two options:

(1) Employ some extending functions like xxx:node-set() if your xslt processor support it

For example if you use MS processor you could add its namespace in document element of your stylesheet: xmlns:msxsl="urn:schemas-microsoft-com:xslt".

The you can call function node-set() from this namespace: <xsl:variable name="array" select="msxsl:node-set($inline-array)/item" />. This will process your variable into nodeset which you can access as another xml: <xsl:value-of select="$array[3]"/>.

Other vendors also could have such extension - look at documentation of your processor. Or look at "exslt".

(2) You could also make another recursive named template taking a position of required value in your csv string. It would return just single value at specified position. But it could be a bit expensive for bigger data - it depends on your expected inputs.

(3) Switch to xslt 2.0 where these things are much easier

You can use tokenize() function in xslt 2.0

<xsl:variable name="OPTIONS" select="'val1,,val2,val3,,,val4'" />
<xsl:variable name="array" select="tokenize($OPTIONS, ',')" />
<xsl:value-of select="$array[3]" />
Sign up to request clarification or add additional context in comments.

5 Comments

@ Jirka, The variable is global that should be defined before the actual transformation takes place. Am i right ? There was an example from where i started working. Please follow the url here stackoverflow.com/questions/3299938/creating-arrays-in-xslt
Yes I read this link but there is a difference. Described solution loads a variable with "static" content. It just read it. You want to read it (it does) and interpret it (it doesn't - if it does then there wouldn't be any reason to call document() function). So as well as the solution on your link reads <Item> sequence and does nothing more it also reads sequence of elements from your stylesheet and does nothing more with them. It doesn't matter if the variable is global or not. For document() function your xslt file is just a xml file with no special meaning.
Yeah, I got it now. I am still struggling for the solution. Thank you so much. Let me know if you give some sample of code to fix my problem.
I tried to add some points in my answer - take a look on them.
Jirka, Many thanks for your comments. Using node-set, i have got what i need. Your support gave me good learning of xslt more.

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.