Skip to content

Instantly share code, notes, and snippets.

Created May 28, 2021
What would you like to do?
This is some crazy old code from back in the day
xquery version "1.0";
module namespace r = "";
(: Thanks to Marko Schulz for seeding this idea with his JavaScript version at :)
declare function r:roman( $input as xs:string ) as xs:integer
(: I'd like to fail fast here if the string is empty. What's the best way? :)
let $characters as xs:string* := r:convert-string-to-characters(upper-case($input))
let $numbers as xs:integer* :=
for $i in $characters
let $total as xs:integer* :=
for $i at $count in $numbers
if($i lt $numbers[$count + 1]) then (-$i) (: Handles subtractive principle of Roman numerals. :)
else $i
return sum($total)
(: Saxon didn't seem to like my use of local: here. Why? What am I missing? :)
declare function r:convert-string-to-integer( $input as xs:string ) as xs:integer
(: Seems like a hacky way to implement a switch-like statement. Is there a better way?
My earlier version was for $i in 1 to 1 return ...
A reviewer suggested two sequences and then ($numbers[index-of($letters, 'I')], 0)[1] :)
let $results as xs:integer+ :=
if($input eq "I") then 1
else if($input eq "V") then 5
else if($input eq "X") then 10
else if($input eq "L") then 50
else if($input eq "C") then 100
else if($input eq "D") then 500
else if($input eq "M") then 1000
else 0
return $results
(: From :)
declare function r:convert-string-to-characters( $input as xs:string ) as xs:string*
for $c in string-to-codepoints($input)
return codepoints-to-string($c)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment