6

我正在尝试在 XQuery 中格式化小数。小数是货币,所以格式应该是,###.##.

例如:

5573652.23应该5,573,652.23

352769应该是352,769(或者352,769.00如果它更容易/更清洁)

现在我正在使用来自http://www.xqueryhacker.com/2009/09/format-number-in-xquery/的这个函数,但我不能使用小数:

declare function local:format-int($i as xs:int) as xs:string
{
  let $input :=
    if ($i lt 0) then fn:substring(fn:string($i), 2)
    else fn:string($i)
  let $rev := fn:reverse(fn:string-to-codepoints(fn:string($input)))
  let $comma := fn:string-to-codepoints(',')

  let $chars :=
    for $c at $i in $rev
    return (
      $c,
      if ($i mod 3 eq 0 and fn:not($i eq count($rev)))
      then $comma else ()
    )

  return fn:concat(
    if ($i lt 0) then '-' else (),
    fn:codepoints-to-string(fn:reverse($chars))
  )
};

我正在为我的处理器使用 Saxon 9HE。

任何帮助将不胜感激。

- - - 更新 - - -

根据 Dimitre 的回答,我修改了函数以保存小数部分并将其添加到返回字符串的末尾。

新功能

declare function local:format-dec($i as xs:decimal) as xs:string
{
  let $input := tokenize(string(abs($i)),'\.')[1]
  let $dec := substring(tokenize(string($i),'\.')[2],1,2)
  let $rev := reverse(string-to-codepoints(string($input)))
  let $comma := string-to-codepoints(',')

  let $chars :=
    for $c at $i in $rev
    return (
      $c,
      if ($i mod 3 eq 0 and not($i eq count($rev)))
      then $comma else ()
    )

  return concat(if ($i lt 0) then '-' else (),
                codepoints-to-string(reverse($chars)),
                if ($dec != '') then concat('.',$dec) else ()
                )
};
4

3 回答 3

3

使用

let $n := 5573652.23
 return
      concat(local:format-int(xs:int(floor($n))),
             '.',
             substring(string($n - floor($n)), 3)
             )

这会产生所需的正确结果

5,573,652.23
于 2011-05-01T17:57:41.047 回答
1

这对你不起作用?:

format-number(5573652.23,",###.##")

你可以在这里玩这个。我很确定撒克逊人支持这个功能。

编辑:撒克逊不支持此功能(请参阅下面的评论)。

于 2011-04-30T20:11:12.560 回答
0

使用 XQuery 3.0 和 Saxon-HE 9.7 Parser,您可以执行以下操作:

declare decimal-format local:de decimal-separator = "," grouping-separator = ".";
declare decimal-format local:en decimal-separator = "." grouping-separator = ",";
let $numbers := (1234.567, 789, 1234567.765)
for $i in $numbers
return (
   format-number($i,"#.###,##","local:de"),
   format-number($i,"#,###.##","local:en")
)

输出是:

<?xml version="1.0" encoding="UTF-8"?>1.234,57 1,234.57 789,0 789.0 1.234.567,76 
1,234,567.76
于 2019-03-06T07:03:13.217 回答