Erol Pazarbaşı
Erol Pazarbaşı

Reputation: 13

XSLT ERROR: Static error in XPath expression supplied to xsl:evaluate: Undeclared variable in XPath expression

I'm tring to use a value in a specific tag as variable name. But while converting xml system gives Undeclared variable in XPath expression Exception.

My Xml file is

<request>
    <entityType>individual</entityType>
</request>

And Xslt file is

<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
    xmlns:xs="http://www.w3.org/2001/XMLSchema"
    xmlns:math="http://www.w3.org/2005/xpath-functions/math"
    exclude-result-prefixes="xs math"
    version="3.0">

    <xsl:param name="individual" static="yes" as="xs:string" select="'1'"/>
    <xsl:param name="legal" static="yes" as="xs:string" select="'2'"/>
 

    <xsl:template match="/*">
  
      <xsl:param name="entity" as="xs:string" select="concat('$',entityType)"/>     
        <xsl:variable name="input" as="xs:string">
            <xsl:evaluate xpath="$entity"/>
        </xsl:variable>
    
        <HTML><TITLE><xsl:value-of select="$input"/></TITLE></HTML>
    </xsl:template>
</xsl:stylesheet>

i expect the result as

<HTML><TITLE>1</TITLE></HTML>

But I get "Static error in XPath expression supplied to xsl:evaluate: Undeclared variable in XPath expression" message.

Upvotes: 1

Views: 138

Answers (2)

Martin Honnen
Martin Honnen

Reputation: 167716

If you read https://www.w3.org/TR/xslt-30/#dynamic-xpath then you will find it clearly states "Variables declared in the stylesheet in xsl:variable or xsl:param elements are not in-scope within the target expression.". You will have to use xsl:with-param inside the xsl:evaluate and/or with-params on the xsl:evaluate to declare the parameters you need.

<xsl:evaluate xpath="$entity" with-params="map{ QName('', 'individual') : $individual }"/>

As pointed out in your comment, you want to map certain string color values to integer color values, that might be possible in XSLT 3 with a map e.g. with an input of

<colors>
  <color>red</color>
  <color>green</color>
</colors>

and an XSLT 3.0 of e.g.

<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
  version="3.0"
  xmlns:xs="http://www.w3.org/2001/XMLSchema"
  exclude-result-prefixes="#all"
  expand-text="yes">
  
  <xsl:param name="color-map"
             as="map(xs:string, xs:integer)"
             select="map {
                      'red' : 1,
                      'green' : 2
                    }"/>
                    
  <xsl:template match="color">
    <xsl:copy>{$color-map(.)}</xsl:copy>
  </xsl:template>

  <xsl:mode on-no-match="shallow-copy"/>
  
</xsl:stylesheet>

you would get a result of e.g.

<colors>
  <color>1</color>
  <color>2</color>
</colors>

Online fiddle example.

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163595

@MartinHonnen is correct in his explanation of why this doesn't work, but standing back from it, I wonder what you are actually trying to achieve? What is suppposed to happen if the source XML document contains a value other than "individual" or "legal"? If these are the only two values that the stylesheet can correctly process, surely there is an easier way of mapping these to the integers 1 and 2?

I don't really know what your problem is, but I suspect that xsl:evaluate is not the right solution to it.

Upvotes: 2

Related Questions