2010-02-03 6 views
4

Хотелось бы узнать, можно ли в XLST использовать математику: abs (...)? Я видел это где-то, но он не работает. у меня есть что-то вроде:XSLT: можем ли мы использовать значение abs?

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

Я пытался сделать что-то вроде:

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

, но не работает. Я использую язык java 1.6.

+1

dup? http://stackoverflow.com/questions/804421/how-can-i-calculate-the-absolute-value-of-a-number-in-xslt –

+0

См. однострочное решение, которое я только что добавил :) –

ответ

0

math:abs не встроен в XSLT или XPATH. Это расширение XSLT, предоставляемое средой выполнения, с которой вы трансформируетесь.

Здесь размещена статья о .NET xslt extensions.

Адрес: for Java (Xalan).

+0

Я бы предпочитают изменять только файл xslt, а не java-код, потому что в java-коде есть много эффектов. –

+0

Слишком плохо. 'math: abs' будет предоставляться как расширение xslt вашим кодом Java. Прочтите связанные статьи, чтобы узнать, как это будет показано на вашем xslt. – Oded

3

abs() достаточно тривиально. Реализуется в чистом XSLT это будет выглядеть следующим образом:

<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> 

в вашем контексте вы бы ссылаться на это следующим образом:

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

На самом деле я нашел решение. Там уже есть математика: абс. Я только что использовал и для моей подписи Я поставил «math: abs (...)» –

+0

Мое решение было нацелено на XSLT 1.0, так как вы не упомянули, что можете использовать версию 2,0. – Tomalak

+1

См. Однолинейное решение, которое я только что добавил :) –

7

Вот одно выражение XPath реализации abs() функции:

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

Этоabs($x).

Вот краткая демонстрация этого в действии:

<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> 

когда это преобразование применяется на следующий документ XML:

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

разыскиваемый, правильный результат (abs() на каждом номере) произведено:

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

@tomalak На самом деле это всего лишь 1: 1 определение abs(). Если $ x> = 0, то просто $ x (умноженное на 1), Если $ x <0, то $ x, умноженное на -1 . Условия выше взаимно исключающие, так что точно одно из них истинно (1), и точно один - false (0). Мы используем это, чтобы суммировать два и создать единую формулу. –

+0

@Dimitre: Это именно то, что называется «Метод Беккера», когда выполняется со строками. :) Смотрите блог Олэг: http://www.tkachenko.com/blog/archives/000156.html. – Tomalak

+0

@tomalak Это свойство XPath 1.0 слияния булевых чисел в число. Он широко использовался и не только O.B. –

1

Anotherway:

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

При $ х положительна, тест возвращает "истина", так что 2 * Истинные-1 возвращает 1, так что конечный результат $ х. Когда $ x отрицательно, тест возвращает «false», поэтому 2 * false-1 возвращает -1, поэтому конечный результат - $ x.

Использование

2*(any-test-here)-1
является хорошим способом, чтобы иметь +1 когда тест истинный и -1 когда ложные.

1

Очень простое решение - использовать функцию трансляции XSL 1.0. То есть

<xsl:value-of select="translate($x, '-', '')/> 
Смежные вопросы