我现在遇到一个问题,我们连接的系统希望接收XML,其中包含三个格式化为一个小数位的双字段。就我个人而言,我觉得我们的系统应该能够以默认格式发送值,然后由其他系统根据需要格式化自己的表示形式,但是这似乎不是一种选择。
我的基于Java的系统目前正在通过使用XStream将对象转换为XML。我们有一个伴随XML的XSD,并将各种元素定义为string,double,dateTime等。
我有三个双字段,其中包含12.5,100.123,5.23445等值。现在它们几乎被转换为XML。我需要的是将这些值格式化为XML到一个小数位; 12.5,100.1,5.2等
我已经简要地想出了实现这个目标的选项:
我会挑选你的集体大脑,了解在这种情况下使用的“接受”方式/最佳做法。
谢谢, 戴夫。
答案 0 :(得分:4)
XStream有converters(tutorial)。您必须注册自己的Double转换器来处理这个问题。在转换器中使用DecimalFormat
来限制小数位数。
答案 1 :(得分:4)
这可以在单个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
的任何有意义的值生成所需的输出。在上面的示例中,它设置为{{ 1}}并且结果包含小数点后四位数的所有数字:
4