2010-07-29 5 views
2

Для этого XSLT:Сохранил количество цифр при обработке вход-> number-> выход во время обработки XSLT

<xsl:variable name="source0" select="number(num2)"/> 
    <xsl:variable name="source1" select="number(num3)"/> 
    s0 plain: <xsl:value-of select="$source0"/> 
    s1 plain: <xsl:value-of select="$source1"/> 
    test11: <xsl:value-of select="format-number($source0, '#.#')"/> 
    test12: <xsl:value-of select="format-number($source0, '#.###############')"/> 
    test21: <xsl:value-of select="format-number($source1, '#.#')"/> 
    test22: <xsl:value-of select="format-number($source1, '#.###############')"/> 

Для XML:

<num2>123456.1234</num2> 
<num3>1234567.1234</num3> 

я получаю этот выход (с помощью Saxon 9.2, XSLT 2.0)

s0 plain: 123456.1234 
    s1 plain: 1.2345671234E6 
    test11: 123456.1 
    test12: 123456.123399999996764 
    test21: 1234567.1 
    test22: 1234567.123399999924004 

Прежде всего ... Мне любопытно, почему он внезапно переключается между стандартными и научными обозначениями, когда он выходит eds 6 цифр слева от десятичной точки? Это моя проблема, я хочу избежать научной нотации. После различных других вопросов я обнаруживаю, что, по-видимому, я застрял в заполнении формата.

Но формат-формат также не работает. Несмотря на то, что вывод «s1 plain» доказывает, что число значимых цифр известно процессору (я понимаю, что преобразование в double и назад может потерять точность, но после такого преобразования есть правильное число, поэтому ...?), похоже, не существует способа вывода этого значения в стандартную ненаучную нотацию. Здесь?

+0

Хороший вопрос (+1). См. Мой ответ для решения, которое обеспечивает максимальную точность. –

+0

Спецификация XSLT 2.0 для преобразования в две строки> строка означает, что экспоненциальная нотация должна использоваться, если значение находится за пределами диапазона 1е-6 до 1е + 6. Разумеется, эти точки отсечения совершенно произвольны, но вы не захотите, чтобы 1e215 выписался длинным ... –

+0

Неправильно думать, что «количество важных цифр известно процессору». Если вы хотите узнать больше об используемых алгоритмах, преобразование Саксона основано на этой знаменитой статье: http://portal.acm.org/citation.cfm?id=93559, адаптированной к требованиям спецификации XPath. –

ответ

2

Это моя проблема, я хочу избежать научной нотации. После различных других вопросов я обнаруживаю, по-видимому, Я застрял с помещением формата-номера всюду.

Но формат-номер не отображается .

Видимо вы не используете соответствующие функции XSLT 2.0/XPath 2.0.

Это преобразование:

<xsl:stylesheet version="2.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform" 
xmlns:xs="http://www.w3.org/2001/XMLSchema"> 
<xsl:output method="text"/> 

<xsl:template match="/*"> 
    <xsl:variable name="vs0" as="xs:decimal" 
    select="xs:decimal(num2)"/> 

    <xsl:variable name="vs1" as="xs:decimal" 
    select="xs:decimal(num3)"/> 

    s0 plain: <xsl:value-of select="$vs0"/> 
    s1 plain: <xsl:value-of select="$vs1"/> 
    test11: <xsl:value-of select="format-number($vs0, '#.#')"/> 
    test12: <xsl:value-of select="format-number($vs0, '#.###############')"/> 
    test21: <xsl:value-of select="format-number($vs1, '#.#')"/> 
    test22: <xsl:value-of select="format-number($vs1, '#.###############')"/> 

</xsl:template> 
</xsl:stylesheet> 

при нанесении на этом XML-документ:

<nums> 
    <num2>123456.1234</num2> 
    <num3>1234567.1234</num3> 
</nums> 

производит точные результаты:

s0 plain: 123456.1234 
s1 plain: 1234567.1234 
test11: 123456.1 
test12: 123456.1234 
test21: 1234567.1 
test22: 1234567.1234 

Заключение: При необходимости хорошей точности всегда старайтесь использовать тип данных xs:decimal.

+0

+1 хороший ответ! @taotree: это то, что я написал в другом вопросе как «кастинг» и использование «встроенных конструкторов типов данных». – 2010-07-30 13:42:00

+0

На самом деле вам не нужно использовать номер формата вообще при использовании xs: decimal.Все, что вам нужно сделать, это отбросить его на xs: decimal и будет выводиться в десятичной (ненаучной) нотации всегда. Мне нужно было проверить пустую строку, потому что number() прощает, но xs: decimal() - нет. if (длина строки (normalize-space ($ value))> 0) then xs: decimal ($ value) else number ($ value) – mentics

 Смежные вопросы

  • Нет связанных вопросов^_^