Family
Family

Reputation: 1113

Increase the value of a variable being passed to call-template

I have the following bit of xsl inside a template:

<xsl:variable name="current_x" select="position_x" />
<xsl:variable name="current_y" select="position_y" />
<xsl:if test="units_display='true'">
  <xsl:call-template name="DisplayBox">
    <xsl:with-param name="value"><xsl:value-of select="units" /></xsl:with-param>
    <xsl:with-param name="text" select="'Units'" />
  </xsl:call-template>
</xsl:if>
<xsl:if test="sensor_display='true'">
  <xsl:call-template name="DisplayBox">
    <xsl:with-param name="value"><xsl:value-of select="sensor" /></xsl:with-param>
    <xsl:with-param name="text" select="'Type'" />
  </xsl:call-template>
</xsl:if>

My call-template is like this:

<xsl:template name="DisplayBox">
<xsl:param name="current_x" select="0"/>
<xsl:param name="current_y" select="0"/>
<xsl:param name="value" />
<xsl:param name="text" />
<g transform="translate({$current_x},{$current_y})">
  <rect x="20" y="150" width="220" height="20" fill="#FFFFFF" stroke="black" stroke-width="1" />
  <text x="25" y="168" font-family="arial" font-size="20px" fill="black">
    <xsl:value-of select="$value"/>
  </text>
  <line x1="90" y1="150" x2="90" y2="170" stroke="black" stroke-width="1" />
  <text x="95" y="168" font-family="arial" font-size="20px" fill="black">
    <xsl:value-of select="$text" />
  </text>
</g>
</xsl:template>

This displays the value of 'value' and 'text' inside a rectangle. The thing I cannot work out how to do, however, is to not have them write on top of each other. I want to increase the current_y value if the test="xxxx_display=true. But I am at a loss of how to achieve this.

I can't work out how I can increase the value of current_y outside of the call-template.

EDIT:

There seems to be a problem in using transform translate in the call-template. It seems to ignore those values.

I have modded the code to now be:

      <xsl:if test="units_display='true'">
        <g transform="translate({position_x},{position_y})">
          <xsl:call-template name="DisplayBox">
            <xsl:with-param name="value">
              <xsl:value-of select="units" />
            </xsl:with-param>
            <xsl:with-param name="text" select="'Units'" />
          </xsl:call-template>
        </g>
      </xsl:if>
      <xsl:if test="sensor_display='true'">
        <g transform="translate({position_x},{position_y + 20})">
          <xsl:call-template name="DisplayBox">
            <xsl:with-param name="value">
              <xsl:value-of select="sensor" />
            </xsl:with-param>
            <xsl:with-param name="text" select="'Type'" />
          </xsl:call-template>
        </g>
      </xsl:if>

But, I don't want to hard-code 'position_y + 20'. I would like the 2nd value to be at position_y if the first value display was not true, but the 2nd value to be at position_y + 20 if the first value display was true. This must be possible somehow I would hope.

Upvotes: 0

Views: 329

Answers (2)

nwellnhof
nwellnhof

Reputation: 33658

Simply pass the the parameters current_x and current_y with the adjusted values like this:

<xsl:if test="units_display='true'">
  <xsl:call-template name="DisplayBox">
    <xsl:with-param name="value"><xsl:value-of select="units" /></xsl:with-param>
    <xsl:with-param name="text" select="'Units'" />
    <xsl:with-param name="current_x" select="position_x"/>
    <xsl:with-param name="current_y" select="position_y + 100"/>
  </xsl:call-template>
</xsl:if>
<xsl:if test="sensor_display='true'">
  <xsl:call-template name="DisplayBox">
    <xsl:with-param name="value"><xsl:value-of select="sensor" /></xsl:with-param>
    <xsl:with-param name="text" select="'Type'" />
    <xsl:with-param name="current_x" select="position_x"/>
    <xsl:with-param name="current_y" select="position_y + 200"/>
  </xsl:call-template>
</xsl:if>

EDIT: If you want to go with the second approach, try to change the sensor_display part to:

  <xsl:if test="sensor_display='true'">
    <xsl:variable name="offset">
      <xsl:choose>
        <xsl:when test="units_display='true'">20</xsl:when>
        <xsl:otherwise>0</xsl:otherwise>
      </xsl:choose>
    </xsl:variable>
    <g transform="translate({position_x},{position_y + $offset})">
      <xsl:call-template name="DisplayBox">
        <xsl:with-param name="value">
          <xsl:value-of select="sensor" />
        </xsl:with-param>
        <xsl:with-param name="text" select="'Type'" />
      </xsl:call-template>
    </g>
  </xsl:if>

BTW, if you rephrase your question like this, it's better to start a new question.

Upvotes: 1

Michael Kay
Michael Kay

Reputation: 163595

By the way, don't do this:

<xsl:with-param name="value"><xsl:value-of select="sensor" /></xsl:with-param>

when you mean this:

<xsl:with-param name="value" select="sensor" />

It's not only verbose, it's also incredibly inefficient: instead of simply passing a reference to a value, you are constructing a temporary tree containing a text node that holds a copy of the value. Creating new trees is an expensive operation.

Upvotes: 2

Related Questions