【发布时间】:2011-08-15 20:44:34
【问题描述】:
我正在尝试在 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 ()
)
};
【问题讨论】:
-
好问题,+1。请参阅我的答案以获得完整而简短的解决方案:)
-
标准 XPath 函数不需要使用任何命名空间前缀。如果您省略
"fn:"前缀,您的代码将更具可读性。另外,目前你的编码不一致:为什么你在concat()函数前加上前缀,而不是substring()函数前缀? -
@Dimitre:我通常不会为标准函数添加前缀,但我从上面提到的网站复制了这个函数。这是不一致的,因为我在进行修改时没有去掉前缀。我必须通过并清理它,以免混淆任何人。再次感谢。非常感谢您的帮助!
标签: xquery saxon number-formatting