1

I have many variables and only two cases. My original approach goes out of scope:

<xsl:choose>
    <xsl:when test='$something = 6'>
        <xsl:variable name="foo">x</xsl:variable>
        <!-- 50 other variables -->
    </xsl:when>
    <xsl:when test='$something = 7'>
        <xsl:variable name="foo">y</xsl:variable>
        <!-- 50 other variables -->
    </xsl:when>
</xsl:choose>

ie. later, with saxon, XPST0008: Variable x has not been declared (or its declaration is not in scope)

I think it would work if I would choose inside an xsl:variable tag, but then the tests would be repeated over and over and over and over and over:

<xsl:variable name="foo">
    <xsl:choose>
      <xsl:when test='$something = 6'>x</xsl:when>
      <xsl:when test='$something = 7'>y</xsl:when>
    </xsl:choose>
</xsl:variable>
<!-- 50 other variables, the two tests repeated for each... -->

Is there a way to keep the variables in scope but also don't repeat myself?


update 1

adding the complete 'sscce' files on request

original approach:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <xsl:variable name="something">6</xsl:variable>
    <xsl:choose>
        <xsl:when test="$something = '6'">
            <xsl:variable name="foo">x</xsl:variable>
            <!-- 50 other variables -->
        </xsl:when>
        <xsl:when test="$something = '7'">
            <xsl:variable name="foo">y</xsl:variable>
            <!-- 50 other variables -->
        </xsl:when>
    </xsl:choose>
    <xsl:value-of select="$foo"/>
</xsl:template>
</xsl:stylesheet>

approach that works but forces to repeat myself:

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet  version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:template match="/">
    <xsl:variable name="something">6</xsl:variable>
    <xsl:variable name="foo">
        <xsl:choose>
          <xsl:when test='$something = 6'>x</xsl:when>
          <xsl:when test='$something = 7'>y</xsl:when>
        </xsl:choose>
    </xsl:variable>
    <!-- 50 other variables, the two tests repeated for each... -->
    <xsl:value-of select="$foo"/>
</xsl:template>
</xsl:stylesheet>

example xml file: <xml/>. example saxon command-line: java -jar saxon9he.jar -s:in.xml -xsl:in.xsl -o:out.html

n611x007
  • 8,952
  • 8
  • 59
  • 102
  • For compatibility I need to prefer xslt-1 over 2... But for future-compatibility, 2 is also in my interest. – n611x007 May 08 '15 at 11:17
  • Are you allowed to use XSLT extensions (see http://exslt.org/)? If yes, I think of a workaround... – potame May 08 '15 at 11:46
  • @potame yes, I can use exslt here (I didn't know beforehand) – n611x007 May 08 '15 at 11:49
  • Your original attempt may go out of scope here, but you can always recreate a smaller example of your try. You should rather show that minimal, complete, and executable code for us to tell you what's wrong with it.. or the right way of doing it. – Lingamurthy CS May 08 '15 at 13:38
  • @LingamurthyCS I appended a complete example. – n611x007 May 08 '15 at 14:10
  • 1
    Your "complete" stylesheet does not do anything. Perhaps if you show us the wider picture (i.e. what do you intend to do with these variables once you have defined them), another approach may be found. – michael.hor257k May 08 '15 at 14:24
  • @michael.hor257k I guess this means that xslt is unable to do this on its own? I hope I can gather an even more complete example however it takes time to clear it from sensitive and distractive information. What I do with it is basically using `xsl:variable`s to manage css colors because css historically failed to do that, and having multiple "color schemes" inside the xsl mapping to a single style def in the output. The number of colors is high and the number of color schemes is low. So for each color the test to check which color scheme is used is repeated. It works but it's totally bloated. – n611x007 May 08 '15 at 15:14
  • In that case, @naxa, you could store your mapping from colour schemes to colours in another XML file and load it using document('other.xml') instead of using variables. Will that approach help? – Welbog May 08 '15 at 16:30
  • @Welbog due to the unusual requirement of my case at hand to keep the size of the fileset at the absolute minimum, this approach doesn't seem to be ideal, I cannot use it unfortunately. – n611x007 May 10 '15 at 16:35

2 Answers2

2

Well, I'd rather process that way :

<xsl:variable name="something">6</xsl:variable>

<xsl:variable name="var.set">
  <xsl:choose>
    <xsl:when test="$something = '6'">
        <foo>x</foo>
        <bar>xx</bar>
        <!-- 50 other variables, to be inserted as tag -->
    </xsl:when>
    <xsl:when test="$something = '7'">
        <foo>y</foo>
        <bar>yy</bar>
        <!-- 50 other variables, to be inserted as tag -->
    </xsl:when>
  </xsl:choose>
</xsl:variable>

The variable var.set will be a nodeset that you will be able to read thanks to the exsl:node-set() extension.

For example to retrieve the value for foo (stored as a node and not as a variable anymore), use something like: <xsl:value-of select="exsl:node-set($var.set)/foo" />. Like this you will handle a single variable, quite as if it were an array of values.

PS: on the root tag of your stylesheet, do not forget to add the exsl namespace declaration xmlns:exsl="http://exslt.org/common" extension-element-prefixes="exsl"

potame
  • 7,597
  • 4
  • 26
  • 33
1

If you know your mappings beforehand, you can store them in their own file.

So instead of having something like this

<xsl:variable name="var1">
  <xsl:if test="something = 5">x</xsl:if>
</xsl:variable>
<xsl:value-of select="$var1"/>

You could have this

<xsl:value-of select="document('other.xml')/root/scheme[@number = 5]/@value"/>

With this as other.xml

<root>
  <scheme number="5" value="x"/>
  <scheme number="6" value="y"/>
</root>

You'll probably want a more complex other.xml, with various groups of colours for each colour scheme, but the idea would be the same, and avoids tests and variables completely.

Welbog
  • 59,154
  • 9
  • 110
  • 123
  • While it seems I cannot use this approach due to an unusual requirement in my specific case, but I like the idea, it will definitely serve me well in the future! – n611x007 May 10 '15 at 16:47