XSL Variable Assignment/Usage

2020-03-26 07:13发布

I have an XML file I'm processing with XSL to build a PDF. I'm running into an issue when I try to use an XSL variable. I'm not sure if I'm using it in the wrong scope, assigning it wrong, or calling it wrong. Here's my current code.

<xsl:template name="article-meta-details">
    <xsl:choose>
        <xsl:when test="/article-meta/oldedition = 1"> 
            <xsl:variable name="section_title" select="'Old'"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:variable name="section_title" select="'New'"/>
        </xsl:otherwise>
    </xsl:choose>
    <xsl:call-template name="subtitle">
    <xsl:value-of select="$section_title" />
</xsl:call-template>

This produces the following error:

XPST0008: Variable section_title has not been declared

I tried another solution I found on a different thread which said the variable had to be defined before being used. I thought it was saying to define it with xsl:param but that produced a similar result for me.

XTSE0010: xsl:param must be immediately within a template, function or stylesheet

I tried the code above with the following alterations in both variable places.

<xsl:param name="section_title" select="'Old'"/>

If someone could please point out what I'm doing wrong and/or how to resolve it it'd be very useful for me. Thanks.

Oh, the goal of this code is to replicate this functionality...

<xsl:template name="article-meta-details">
    <xsl:call-template name="subtitle">
    <xsl:with-param name="text" select="'Old'"/>
</xsl:call-template>

标签: xml xslt
3条回答
你好瞎i
2楼-- · 2020-03-26 07:56

The error message suggests that you are using XSLT 2.0, so you can simply write:

<xsl:template name="article-meta-details">
    <xsl:call-template name="subtitle">
      <xsl:with-param name="text" 
        select="if (/article-meta/oldedition = 1) then 'Old' else 'New'" />
    </xsl:call-template>
</xsl:template>
查看更多
对你真心纯属浪费
3楼-- · 2020-03-26 07:57

If someone could please point out what I'm doing wrong

The main problem with your approach is scope. When you define a variable like this:

<xsl:when test="/article-meta/oldedition = 1"> 
    <xsl:variable name="section_title" select="'Old'"/>
</xsl:when>

it exists only until you close the xsl:when element. Similarly, the other variable exists only within the xsl:otherwise tags. (If it weren't so, the two would collide, having the same name.)

and/or how to resolve it

It's hard to advise without seeing the wider picture, but couldn't you do simply:

<xsl:template name="article-meta-details">
    <xsl:call-template name="subtitle">
        <xsl:with-param name="text">
            <xsl:choose>
                <xsl:when test="/article-meta/oldedition = 1">Old</xsl:when>
                <xsl:otherwise>New</xsl:otherwise>
            </xsl:choose>
    </xsl:call-template>
    <!-- more? -->
</xsl:template>
查看更多
家丑人穷心不美
4楼-- · 2020-03-26 08:13

This is because you're approaching variable declaration as you might in a procedural language.

XSLT is compiled, and so it needs to be sure that your variable either exists or it doesn't. It sees you declaring it conditionally, and it gets worried.

Simply make the variable value conditional, rather than the variable's existence itself.

<xsl:variable name="section_title">
    <xsl:choose>
        <xsl:when test="/article-meta/oldedition = 1">Old</xsl:when>
        <xsl:otherwise>New</xsl:otherwise>
    </xsl:choose>
</xsl:variable>
查看更多
登录 后发表回答