saxon - How can I format a decimal in xquery? -


i'm trying format decimals in xquery. decimals currency, format should ,###.##.

for example:

5573652.23 should 5,573,652.23

and

352769 should 352,769 (or 352,769.00 if it's easier/cleaner)

right i'm using function http://www.xqueryhacker.com/2009/09/format-number-in-xquery/, can't use decimals it:

declare function local:format-int($i xs:int) xs:string {   let $input :=     if ($i lt 0) 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 :=     $c @ $i in $rev     return (       $c,       if ($i mod 3 eq 0 , fn:not($i eq count($rev)))       $comma else ()     )    return fn:concat(     if ($i lt 0) '-' else (),     fn:codepoints-to-string(fn:reverse($chars))   ) }; 

i'm using saxon 9he processor.

any appreciated.

----- update -----

based on dimitre's answer, modified function save decimal portion , add end of return string.

new function

declare function local:format-dec($i xs:decimal) 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 :=     $c @ $i in $rev     return (       $c,       if ($i mod 3 eq 0 , not($i eq count($rev)))       $comma else ()     )    return concat(if ($i lt 0) '-' else (),                 codepoints-to-string(reverse($chars)),                 if ($dec != '') concat('.',$dec) else ()                 ) }; 

use:

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

this produces wanted, correct result:

5,573,652.23 

Comments