Это можно сделать в одном выражении XPath.
Использовать :
floor(.) + round(10*(. -floor(.))) div 10
Проверка с использованием XSLT в качестве хоста XPath :
<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()[contains(.,'.')]">
<xsl:value-of select=
"floor(.) + round(10*(. -floor(.))) div 10"/>
</xsl:template>
</xsl:stylesheet>
, когда это преобразование применяется к следующему документу XML :
<t>
<n>12.5</n>
<n>100.123</n>
<n>5.26445</n>
</t>
желаемый, правильный результат:
<t>
<n>12.5</n>
<n>100.1</n>
<n>5.3</n>
</t>
Пояснение : Использование стандартных функций XPath floor()
, round()
и оператор XPath div
и ваша логика.
Обобщенное выражение :
floor(.) + round($vFactor*(. -floor(.))) div $vFactor
где $vFactor
равно 10^N
, где N
- количество цифр после запятой, которое мы хотим.
Используя это выражение, модифицированное XSLT-преобразование будет таким :
<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:param name="pPrecision" select="4"/>
<xsl:variable name="vFactor" select=
"substring('10000000000000000000000',
1, $pPrecision+1
)
"/>
<xsl:template match="node()|@*">
<xsl:copy>
<xsl:apply-templates select="node()|@*"/>
</xsl:copy>
</xsl:template>
<xsl:template match="text()[contains(.,'.')]">
<xsl:value-of select=
"floor(.) + round($vFactor*(. -floor(.))) div $vFactor"/>
</xsl:template>
</xsl:stylesheet>
когда это преобразование применяется к тому же XML-документу (см. Выше), мы создаем требуемый вывод для любого значащего значения $pPrecision
. В приведенном выше примере оно установлено на4
ирезультат содержит все числа, округленные до четырех цифр после десятичной точки:
<t>
<n>12.5</n>
<n>100.123</n>
<n>5.2645</n>
</t>