1

I'm trying to access a specific element in an array depending on the value of the current date in an XML file.

For example, in the XML

<CurrentMonth>5</CurrentMonth>

Then, in the XSLT - this is set as a variable as

  <xsl:variable name="current-month">
       xsl:value-of select="//CurrentMonth" />
  </xsl:variable>

I also have declared an array of the "Month names" as

<xsl:variable name="array" as="element()*">
    <Item>Jan</Item>
    <Item>Feb</Item>
    <Item>Mar</Item>
    <Item>Apr</Item>
    <Item>May</Item>
    <Item>Jun</Item>
    <Item>Jul</Item>
    <Item>Aug</Item>
    <Item>Sept</Item>
    <Item>Oct</Item>
    <Item>Nov</Item>
    <Item>Dec</Item>
</xsl:variable>

Is it possible in XSLT to return the name of the month (e.g. "Jan") by using a variable as an index for the array?

Example :

<xsl:value-of select="$array[$current-month]">

The code above is throwing me

[FATAL]: Error checking type of the expression 'filter-expr(variable-ref(array/result-tree)

Thanks in advance.

2
  • 1
    Please select either XSLT 1.0 or 2.0, not both. Commented May 31, 2016 at 12:18
  • Apologies, this is XSLT 2.0 Commented May 31, 2016 at 12:19

2 Answers 2

1

You have several syntax errors:

<xsl:variable name="current-month">
   xsl:value-of select="//CurrentMonth" />
</xsl:variable>

needs to be:

<xsl:variable name="current-month">
   <xsl:value-of select="//CurrentMonth" />
</xsl:variable>

or preferably:

<xsl:variable name="current-month" select="//CurrentMonth" />

Next you have:

<xsl:value-of select="$array[$current-month]">

which needs to be closed:

<xsl:value-of select="$array[$current-month]"/>

and, in case you are using the first form of defining the variable, it needs to be:

<xsl:value-of select="$array[number($current-month)]">
Sign up to request clarification or add additional context in comments.

1 Comment

Syntax errors were just in Stack Overflow, as I retyped the scenario and had some mistakes, apologies. $array[number($current-month)] solved it for me. Thanks !
0

Define the variable as <xsl:variable name="current-month" select="xs:integer(//CurrentMonth)"/>, then you can use $array[$current-month] (although you index a sequence and not an array). With your code you need $array[position() = $current-month].

A minimal but complete stylesheet that runs fine for me with Saxon 9.6.0.7 HE is

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    exclude-result-prefixes="xs"
    version="2.0">

    <xsl:variable name="array" as="element()*">
        <Item>Jan</Item>
        <Item>Feb</Item>
        <Item>Mar</Item>
        <Item>Apr</Item>
        <Item>May</Item>
        <Item>Jun</Item>
        <Item>Jul</Item>
        <Item>Aug</Item>
        <Item>Sept</Item>
        <Item>Oct</Item>
        <Item>Nov</Item>
        <Item>Dec</Item>
    </xsl:variable>

    <xsl:variable name="current-month" select="xs:integer(//CurrentMonth)"/>

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

</xsl:stylesheet>

and outputs May when run against the input <CurrentMonth>5</CurrentMonth>.

5 Comments

I tried your first suggestion and recieved [ERROR]: Namespace prefix 'xs' is undeclared.
Yes, well, you need to also declare xmlns:xs="http://www.w3.org/2001/XMLSchema" on the root of your stylesheet to use the schema data types like xs:integer.
It's now throwing me "[ERROR]: The first argument to the non-static Java function 'integer' is not a valid object reference. [ERROR]: Could not compile stylesheet [FATAL]: Error checking type of the expression 'filter-expr(variable-ref(array/result-tree), [pred(variable-ref(current-month/void))])'. "
Can you tell us which XSLT 2.0 processor you use? The error messages sound unusual to me.
@Cdok, I have added a minimal but complete stylesheet that runs fine for me with Saxon 9.6.0.7, I can't reproduce the error you say you get.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.