Как работает функция ОКРУГЛ в Orbeon Forms?

В Orbeon Forms (dev-post-3.7.1.200911140400) у нас есть код в XPL, который выполняет некоторые вычисления, и часть этих вычислений заключается в том, что мы ОКРУГЛЯЕМ результат до 2 знаков после запятой. Ниже приведен пример кода, который мы используем для расчета:

<xsl:when test="$total_c_w != 0">
    <gpa><xsl:value-of select="(round(($total_p_c_w div $total_c_w) * 100) div 100)"/></gpa>
</xsl:when>

Согласно стандартной документации XPATH по функции ОКРУГЛ; Округляет числовое значение до ближайшего целого числа, округляя x,5 до положительной бесконечности.

Но мы сталкиваемся со случаем, когда функция ОКРУГЛ округляет 237,5 до 237, а не 238. Это просто пример, есть и другие случаи, когда возникает аналогичная проблема с x.5.

Например, упомяните, что значения в расчете:

$total_p_c_w = 7.6, $total_c_w = 3.2

=====================================================

Алексей, спасибо за наводку. Я провел дополнительную отладку и обнаружил кое-что странное. Пожалуйста, обратитесь к следующему коду XSL, который я тестировал в последней версии Orbeon Forms 3.9.0.201105152046 CE.

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
    <xsl:template match="/">
    <main>
        <xsl:variable name="tppcw" select="/root/studentpcw/total_p_c_w" as="xs:double"/>
        <xsl:variable name="tccw" select="/root/studentpcw/total_c_w" as="xs:double"/>              
        <xsl:variable name="tpcw" select="sum(/root/studentpcw/total_p_c_w)"/>
        <xsl:variable name="tcw" select="sum(/root/studentpcw/total_c_w)"/>         
        <xsl:variable name="total_p_c_w" select="7.6"/>
        <xsl:variable name="total_c_w" select="3.2"/>       
    <var1><xsl:value-of select="sum(/root/studentpcw/total_p_c_w)"/></var1>
    <var2><xsl:value-of select="sum(/root/studentpcw/total_c_w)"/></var2>
    <var3><xsl:value-of select="$total_p_c_w"/></var3>
    <var4><xsl:value-of select="$total_c_w"/></var4>        
    <result1>

        <xsl:value-of select="round(($total_p_c_w div $total_c_w) * 100)"/>
    </result1>
    <result2>

        <xsl:value-of select="round(($tppcw div $tccw) * 100)"/>
    </result2>
    </main>
    </xsl:template>
</xsl:transform>

Примените приведенный выше код к этому образцу документа:

<root>
  <studentpcw>
  <total_p_c_w>7.6</total_p_c_w>
  <total_c_w>3.2</total_c_w>
  </studentpcw>
</root>

Результат довольно неожиданный;

<main xmlns:xs="http://www.w3.org/2001/XMLSchema">
   <var1>7.6</var1>
   <var2>3.2</var2>
   <var3>7.6</var3>
   <var4>3.2</var4>
   <result1>238</result1>
   <result2>237</result2>
</main>

Проблема в том, что если я назначу переменной буквальное число и использую эту переменную в функции округления, результат будет таким, как я ожидал. Если я выберу значение из узла, назначу его переменной и использую эту переменную в функции округления, результат будет неправильным или неожиданным.


person Hoi    schedule 18.07.2011    source источник


Ответы (1)


Я получаю результат 238 запуска следующей таблицы стилей в ночной сборке через песочницу XSLT (к которой, если у вас установлена ​​локальная версия Orbeon Forms, вы можете получить доступ через http://localhost:8080/orbeon/sandbox-трансформации/xslt/).

<xsl:transform xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" version="2.0">
    <xsl:template match="/">
        <result>
            <xsl:variable name="total_p_c_w" select="7.6"/>
            <xsl:variable name="total_c_w" select="3.2"/>
            <xsl:value-of select="round(($total_p_c_w div $total_c_w) * 100)"/>
        </result>
    </xsl:template>
</xsl:transform>

Я считаю, что это результат, которого вы ожидали, но вы можете получить что-то другое с версией, которую вы используете. Не могли бы вы попробовать приведенный выше пример в песочнице XSLT той версии, которую вы используете? Если вы получаете 237 вместо 238, то это признак того, что проблема была исправлена, и я бы порекомендовал вам перейти на более новую версию Orbeon Forms (в настоящее время 3.9).

(Обратите внимание, что это, скорее всего, происходит не в Orbeon Forms как таковом, а в реализации XSLT, которую Orbeon Forms использует, что является отличным саксонский.)

person avernet    schedule 18.07.2011
comment
Алекс, что вы думаете о моих выводах выше? Похоже на ошибку в том, как Orbeon Forms обрабатывает выбор числового значения, а затем использует его для последующего вычисления. - person Hoi; 20.07.2011
comment
Хой, это разница между xs:double и xs:decimal. Если вы просто запустите $tppcw div $tccw, вы получите 2.3749999999999996, а не 2.375, и это связано с тем, что вы используете xs:double, который в большинстве случаев не делает того, что вы хотите. Вместо этого используйте xs:decimal. В своем коде замените as="xs:double" на as="xs:decimal", и вы получите ожидаемый результат. - person avernet; 22.07.2011