So I spent a little time cracking my head to write a number converter for roman numerals in XQuery. Most examples from java and such use a while loop to do the conversion. This is not possible in xquery so to simulate the while loop using recursion the solution is very simple just use a simulated queue that pops off the values while it builds the Roman Numerals.

declare variable

$romanAlpha as xs:string* :=

(“M”, “CM”, “D”, “CD”, “C”, “XC”, “L”, “XL”,“X”,“IX”, “V”, “IV”,“I”);

declare variable $romanNums as xs:integer* :=

(1000,900,500,400,100,90,50,40,10,9,5,4,1);(:~

converts arabic number to a roman numeral

~:)

declare function local:number-to-roman($num as xs:integer){

if($num eq 0) then

“”

else if($num gt 3999) then

fn:error(xs:QName(“INVALID_ARGUMENT”),“Cannot Convert Number Larger than 3999”)

else

local:recursive-roman($num,“”,$romanNums)

};

(:~

Recursion Method used to calculate the roman numeral

~:)

declare function local:recursive-roman(

$num as xs:integer,

$alpha as xs:string,

$sequences as xs:integer*){

let $i := $sequences[1]

let $rom-a := $romanAlpha[fn:index-of($romanNums,$i)]

return

if(fn:not($sequences) and $num eq 0) then

$alpha

else

if($num gt $i) then

local:recursive-roman($num – $i, fn:concat($alpha,$rom-a),$sequences)

else if($num lt $i) then

local:recursive-roman($num, $alpha,fn:remove($sequences,1))

else if($num eq $i) then

fn:concat($alpha,$rom-a)

else

$alpha

};