如何在xquery中格式化十进制数?

如何在xquery中格式化十进制数?,xquery,saxon,number-formatting,Xquery,Saxon,Number Formatting,我正在尝试在XQuery中格式化小数。小数是货币,因此格式应该是,##### 例如: 5573652.23应该是5573652.23 及 352769应该是352769(或者352769.00如果更容易/更干净) 现在我使用的是来自的函数,但不能使用小数: declare function local:format-int($i as xs:int) as xs:string { let $input := if ($i lt 0) then fn:substring(fn:stri

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

例如:

5573652.23
应该是
5573652.23

352769
应该是
352769
(或者
352769.00
如果更容易/更干净)

现在我使用的是来自的函数,但不能使用小数:

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))
  )
};
我的处理器用的是萨克森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 ()
                )
};

这不适合你吗

format-number(5573652.23,",###.##")
你可以玩这个。我很确定saxon支持这个函数

编辑:saxon不支持此功能(请参见下面的注释)

使用

let $n := 5573652.23
 return
      concat(local:format-int(xs:int(floor($n))),
             '.',
             substring(string($n - floor($n)), 3)
             )
5,573,652.23
这正好产生所需的正确结果

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

使用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
1.234,57 1234.57 789,0 789.0 1.234.567,76
1,234,567.76

No,
format-number()
不受支持。这是我尝试的第一件事。我尝试将HE更改为PE&EE,但仍然出现错误:
F[Saxon EE XQuery 9.3.0.4]系统函数格式编号#2不适用于此主机语言
+对于一个好的建议,在XQuery3.0和Saxon中尝试了
fn:format number($myelement/*:betrag转换为xs:decimal,“#,###0.00”)
和9.7解析器,它可以工作。好问题,+1。有关完整而简短的解决方案,请参见我的答案:)标准XPath函数不需要使用任何名称空间前缀。如果省略
“fn:”
前缀,代码的可读性会更高。此外,目前您的编码不一致:为什么您在
concat()
函数前面加前缀,而不是
substring()
函数?@Dimitre:我通常不在标准函数前面加前缀,但我是从上面提到的网站复制了这个函数。这是不一致的,因为我做修改时没有去掉前缀。我得检查一下,把它清理干净,这样就不会把任何人搞糊涂了。再次感谢。非常感谢你的帮助!非常感谢你,迪米特里。根据这个答案,我更新了我正在使用的函数+1.答案被接受。