格式化 XML 的十进制值

发布于 2024-11-17 15:20:44 字数 622 浏览 3 评论 0原文

我目前遇到一个问题,我们连接的系统期望接收 XML,其中包含三个格式化为小数点后一位的双精度字段。就我个人而言,我认为我们的系统应该能够以默认格式发送值,然后由其他系统根据需要格式化自己的表示形式,但可惜这似乎不是一个选项。

我的基于 Java 的系统当前正在通过使用 XStream 将对象转换为 XML。我们有一个 XSD,它伴随着 XML 并将各种元素定义为字符串、双精度、日期时间等。

我有三个双精度字段,它们保存 12.5、100.123、5.23445 等值。现在它们几乎按原样转换为XML。我需要将这些值在 XML 中格式化为小数点后一位; 12.5、100.1、5.2 等。

我简要地想出了实现此目的的选项:

  • 在这些值进入 XML 之前,以某种方式让 Java 将这些值格式化为这种精度。也许 NumberFormat 可以做到这一点,尽管我认为这主要用于字符串输出。
  • 希望XSD能为我做这件事;我知道您可以在 XSD 中对精度进行限制,但我不确定它是否真正处理舍入本身,或者只是说“123.123 的值对此模式无效”?
  • 使用 XSLT 以某种方式为我完成此任务。

我想请大家集思广益,看看在这种情况下使用什么是“可接受的”方式/最佳实践。

谢谢, 戴夫.

I have a problem currently where a system we are connecting to expects to receive XML which contains, among other things, three double fields formatted to one decimal place. Personally I feel that our system should just be able to send values in default format and then it's up to other systems to format their own representation as they please, but alas this doesn't seem to be an option.

My Java-based system is currently converting objects to XML through the use of XStream. We have an XSD which accompanies the XML and defines the various elements as string, double, dateTime, etc.

I have three double fields which hold values like 12.5, 100.123, 5.23445 etc. Right now they are converted pretty much as-is into the XML. What I need is these values to be formatted in the XML to one decimal place; 12.5, 100.1, 5.2, etc.

I have briefly thought up options to accomplish this:

  • Somehow have Java format these values to this precision before it goes to the XML. Perhaps NumberFormat can do this, although I thought that was mainly for using with String output.
  • Hope that the XSD can do this for me; I know you can place limits on precision in the XSD, but I am unsure whether it actually handles the rounding itself or will just say 'this value of 123.123 is invalid for this schema'?
  • Use XSLT to somehow accomplish this for me.

I'd to pick your collective brains as to what would be the 'accepted' way / best practice to use in a situation like this.

Thanks,
Dave.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

夏至、离别 2024-11-24 15:20:44

XStream 有转换器 (教程)。您必须注册自己的 Double 转换器来处理此问题。在转换器中使用 DecimalFormat< /a> 限制小数位数。

XStream has converters (tutorial). You would have to register your own Double converter that will handle this. In the converter use DecimalFormat to limit the number of decimal places.

似梦非梦 2024-11-24 15:20:44

这可以在单个 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

其中$vFactor10^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>

This can be done in a single XPath expression.

Use:

floor(.) + round(10*(. -floor(.))) div 10

Verification using XSLT as a host of 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>

when this transformation is applied on the following XML document:

<t>
 <n>12.5</n>
 <n>100.123</n>
 <n>5.26445</n>
</t>

the wanted, correct result is produced:

<t>
   <n>12.5</n>
   <n>100.1</n>
   <n>5.3</n>
</t>

Explanation: Use of the standard XPath functions floor(), round() and the XPath operator div and your logic.

Generalized expression:

floor(.) + round($vFactor*(. -floor(.))) div $vFactor

where $vFactor is 10^N, where N is the number of digits after the decimal point we want.

Using this expression, the modified XSLT transformation is this:

<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>

when this transformation is applied on the same XML document (above), we produce the wanted output for any meaningful value of $pPrecision. In the above example it is set to 4 and the result contains all numbers rounded up to four digits after the decimal point:

<t>
   <n>12.5</n>
   <n>100.123</n>
   <n>5.2645</n>
</t>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文