2

I have declared a variable in my XSLT as given below :

    <xsl:variable name="inline-array">
    <Item>A</Item>
    <Item>B</Item>
    <Item>C</Item>
</xsl:variable>

I am accessing this variable as given below :

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

This is working fine as long as my inline array has static contents. But my requirement is to dynamically assign values in the XSLT to the tag "Item" ie. Something like :

<xsl:variable name="inline-array">
    <Item>$item1</Item>
    <Item>$item2</Item>
    <Item>$item3</Item>
</xsl:variable>

But, I tried all possible options without any luck. Any suggestions will be greatly appreciated. Any other options to fulfill my requirement is also welcome. Thanks.

1
  • To be honest, it sounds like you need to re-think how you're doing this. It's entirely possible there's a much easier way to do it in XSLT; it sounds like you're trying to use procedural/object-oriented techniques, but XSLT's a functional language. It might help if you can go into more detail as to what you're trying to achieve. Commented May 18, 2011 at 8:58

2 Answers 2

3

One way to achieve this is to make use of an extension function, namely the node-set function, which returns a set of nodes from a result tree fragment.

First you would need to define the namespace for the extension functions like so

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt">

In this case, I am using the Microsoft extension functions, but others are available depending on which platform you are using. (http://exslt.org/common is another common one for non-Microsoft platforms).

Next, you define your "array" parameter (or variable, you wanted), like so.

<xsl:param name="array" select="msxsl:node-set($inline-array)"/>

Finally, you can then access this array like so

<xsl:value-of select="$array/Item[1]"/>

Putting this altogether in a simple example gives you this

<xsl:stylesheet version="1.0" 
    xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
    xmlns:msxsl="urn:schemas-microsoft-com:xslt">

   <xsl:output method="text" />

   <xsl:variable name="inline-array">
      <Item>
         <xsl:value-of select="$Item1"/>
      </Item>
      <Item>
         <xsl:value-of select="$Item2"/>
      </Item>
      <Item>
         <xsl:value-of select="$Item3"/>
      </Item>
   </xsl:variable>

   <xsl:param name="Item1">1</xsl:param>
   <xsl:param name="Item2">2</xsl:param>
   <xsl:param name="Item3">3</xsl:param>
   <xsl:param name="array" select="msxsl:node-set($inline-array)"/>

   <xsl:template match="/">
      <xsl:value-of select="$array/Item[1]"/>
   </xsl:template>

</xsl:stylesheet>

When run, this simply outputs the following result:

1

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

1 Comment

Thanks Tim, My inline-array is of the structure : <xsl:variable name="atomic-responses"> <Response> <xsl:copy-of select="$response-A" /> </Response> <Response> <xsl:copy-of select="$response-B" /> </Response> <Response> <xsl:copy-of select="$response-C" /> </Response> </xsl:variable> Each response tag contains a response XML. But, when I try to output using: <xsl:copy-of select="$array/Response[1]" /> It appends the tag <Response> as well. Anyway to avoid this?
2

Firstly, are you stuck with XSLT 1.0? Workarounds like accessing the stylesheet source code using document('') are very rarely needed if only you can move to XSLT 2.0.

Secondly, I think we need to look at the design of the stylesheet, and we can't really do that without a description of the problem you are trying to solve (as distinct from your attempts at a solution.)

Comments

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.