CC.
CC.

Reputation: 2928

XSLT: can we use abs value?

I would like to know if in XLST can we use the math:abs(...) ? I saw this somewhere but it does not work . I have something like:

<tag>
  <xsl:value-of select="./product/blablaPath"/>
</tag>

I tried to do something like:

<tag>
  <xsl:value-of select="math:abs(./product/blablaPath)"/>
</tag>

but does not work. I'm using java 1.6 language.

Upvotes: 4

Views: 8765

Answers (5)

Justin Rowe
Justin Rowe

Reputation: 2456

A very simple solution is to use the XSL 1.0 translate function. I.e.

<xsl:value-of select="translate($x, '-', '')/>

Upvotes: 3

Xenos
Xenos

Reputation: 3507

Anotherway:

(2*($x >= 0) - 1)*$x

When $x is positive, the test returns "true", so 2*true-1 returns 1, so final result is $x. When $x is negative, the test returns "false", so 2*false-1 returns -1, so final result is -$x.

Using

2*(any-test-here)-1
is a good way to have +1 when test is true, and -1 when false.

Upvotes: 1

Dimitre Novatchev
Dimitre Novatchev

Reputation: 243529

Here is a single XPath expression implementing the abs() function:

($x >= 0)*$x - not($x >= 0)*$x

This evaluates to abs($x).

Here is a brief demonstration of this in action:

<xsl:stylesheet version="1.0"
  xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
  <xsl:output omit-xml-declaration="yes" indent="yes"/>
  <xsl:strip-space elements="*"/>

 <xsl:template match="node()|@*">
  <xsl:copy>
   <xsl:apply-templates select="node()|@*"/>
  </xsl:copy>
 </xsl:template>

 <xsl:template match="text()">
  <xsl:param name="x" select="."/>
  <xsl:value-of select=
  "($x >= 0)*$x - not($x >= 0)*$x"/>
 </xsl:template>
</xsl:stylesheet>

when this transformation is applied to the following XML document:

<t>
  <num>-3</num>
  <num>0</num>
  <num>5</num>
</t>

the wanted, correct result (abs() on every number) is produced:

<t>
  <num>3</num>
  <num>0</num>
  <num>5</num>
</t>

Upvotes: 7

Tomalak
Tomalak

Reputation: 338316

abs() is trivial enough. Implemented in pure XSLT it would look like this:

<xsl:template name="abs">
  <xsl:param name="number">

  <xsl:choose>
    <xsl:when test="$number &gt;= 0">
      <xsl:value-of select="$number" />
    <xsl:when>
    <xsl:otherwise>
      <xsl:value-of select="$number * -1" />
    </xsl:otherwise>
  </xsl:if>
</xsl:template>

in your context you would invoke it like this:

<tag>
  <xsl:call-template name="abs">
    <xsl:with-param name="number" select="number(product/blablaPath)" />
  </xsl:call-template>
</tag>

Upvotes: 3

Oded
Oded

Reputation: 499132

math:abs is not built in to XSLT or XPATH. It is an XSLT extension, provided by the runtime you are transforming with.

Here is an article about .NET xslt extensions.

Here is one for Java (Xalan).

Upvotes: 0

Related Questions