我正在尝试在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 ()
)
};
答案 0 :(得分:3)
使用强>:
let $n := 5573652.23
return
concat(local:format-int(xs:int(floor($n))),
'.',
substring(string($n - floor($n)), 3)
)
这会产生所需的正确结果:
5,573,652.23
答案 1 :(得分:1)
答案 2 :(得分:0)
使用XQuery 3.0和Saxon-HE 9.7解析器,您可以执行以下操作:
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