Форматирование представления научных чисел в xsl - PullRequest
3 голосов
/ 06 декабря 2010

У меня есть следующее значение в моем XML -1.8959581529998104E-4.Я хочу отформатировать это к точному числу, это должно использовать XSL, чтобы дать мне -0.000189595815299981.

format-number (-1.8959581529998104E-4, '0.000000; -0.000000') дает мне NaN.

Есть идеи?

Приветствия

Andez

Ответы [ 5 ]

15 голосов
/ 06 декабря 2010

XSLT 1.0 не поддерживает научную нотацию.

Это: number('-1.8959581529998104E-4') Результат: NaN

Это: number('-0.000189595815299981') Результат: -0.000189595815299981

XSLT 2.0 поддерживает научную нотацию

Это: number('-1.8959581529998104E-4') Результат: -0.000189595815299981

РЕДАКТИРОВАТЬ : очень простое решение XSLT 1.0:

<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
    <xsl:template match="number[substring-after(.,'E')]">
        <xsl:variable name="vExponent" select="substring-after(.,'E')"/>
        <xsl:variable name="vMantissa" select="substring-before(.,'E')"/>
        <xsl:variable name="vFactor"
             select="substring('100000000000000000000000000000000000000000000',
                               1, substring($vExponent,2) + 1)"/>
        <xsl:choose>
            <xsl:when test="starts-with($vExponent,'-')">
                <xsl:value-of select="$vMantissa div $vFactor"/>
            </xsl:when>
            <xsl:otherwise>
                <xsl:value-of select="$vMantissa * $vFactor"/>
            </xsl:otherwise>
        </xsl:choose>
    </xsl:template>
</xsl:stylesheet>

С этим входом:

<number>-1.8959581529998104E-4</number>

Выход:

-0.00018959581529998104
4 голосов
/ 09 декабря 2014

Это основано на ответе пользователя 357812.Но я заставил его действовать как функция и обрабатывать ненаучные обозначения

<xsl:template name="convertSciToNumString" >
    <xsl:param name="inputVal" select="0"/>
    <xsl:variable name="vExponent" select="substring-after($inputVal,'E')"/>
    <xsl:variable name="vMantissa" select="substring-before($inputVal,'E')"/>
    <xsl:variable name="vFactor"
         select="substring('100000000000000000000000000000000000000000000',
                           1, substring($vExponent,2) + 1)"/>
    <xsl:choose>
        <xsl:when test="number($inputVal)=$inputVal">
            <xsl:value-of select="$inputVal"/>
        </xsl:when>
        <xsl:when test="starts-with($vExponent,'-')">
            <xsl:value-of select="format-number($vMantissa div $vFactor, '#0.#############')"/>
        </xsl:when>
        <xsl:otherwise>
            <xsl:value-of select="format-number($vMantissa * $vFactor, '#0.#############')"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>

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

<xsl:template match="X">
    <X>
        <xsl:call-template name="convertSciToNumString">
            <xsl:with-param name="inputVal" select="text()"/>
        </xsl:call-template>
    </X>    
</xsl:template>

Это должно обрабатывать смесь научных обозначений и десятичных значений.

1 голос
/ 12 января 2017

Еще один возможный обходной путь без шаблона:

<xsl:stylesheet version="1.0" ... xmlns:java="http://xml.apache.org/xslt/java">
...
<xsl:value-of select="format-number(java:java.lang.Double.parseDouble('1E-6'), '0.000')"/>
0 голосов
/ 19 июня 2019

Логика не работает должным образом в приведенных выше ответах Moop и user357812 при определении vFactor в одном конкретном сценарии.

Если vExponent - однозначное положительное число (без предшествующего знака «+»), то vFactor устанавливается в пустую строку. Это потому, что было сделано предположение, что 1-й символ vExponent будет знаком плюс / минус и, следовательно, 2-й символ будет интересен. Переменная vMantissa затем умножается на пустую строку, в результате чего шаблон выводит NaN.

Если vExponent является многозначным положительным числом (без предшествующего знака «+»), тогда для vFactor установлено неправильное значение. Из-за вышеупомянутого предположения 1-ая цифра игнорируется, а vMantissa затем умножается на неверный vFactor.

Поэтому я немного изменил ранее опубликованный код, чтобы он мог обрабатывать научные номера форм: 2E-4, 2E + 4 и 2E4.

<xsl:template name="convertSciToNumString" >
    <xsl:param name="inputVal" select="0"/>
    <xsl:variable name="vMantissa" select="substring-before(., 'E')"/>
    <xsl:variable name="vExponent" select="substring-after(., 'E')"/>
    <xsl:variable name="vExponentAbs" select="translate($vExponent, '-', '')"/>
    <xsl:variable name="vFactor" select="substring('100000000000000000000000000000000000000000000', 1, substring($vExponentAbs, 1) + 1)"/>
    <xsl:choose>
        <xsl:when test="number($inputVal)=$inputVal">
            <xsl:value-of select="$inputVal"/>
        </xsl:when>
        <xsl:when test="starts-with($vExponent,'-')">
            <xsl:value-of select="format-number($vMantissa div $vFactor, '#0.#############')"/>
        </xsl:when>
        <xsl:otherwise>         
            <xsl:value-of select="format-number($vMantissa * $vFactor, '#0.#############')"/>
        </xsl:otherwise>
    </xsl:choose>
</xsl:template>
0 голосов
/ 20 февраля 2012

Только что попробовал это с xsltproc, используя libxslt1.1 в версии 1.1.24 под Linux:

XSLT 1.1 теперь может читать в экспоненциальном / научном формате, даже без какого-либо специального шаблона, кажется, он просто работает: -))

...