[xquery-talk] XPath/XQuery equivalent of xsl:number?

Joe Wicentowski joewiz at gmail.com
Fri Nov 18 07:25:36 PST 2011


Thanks everyone for your helpful ideas!  

Joe

Sent from my iPhone

On Nov 17, 2011, at 7:53 PM, "G. Ken Holman" <gkholman at cranesoftwrights.com> wrote:

> At 2011-11-17 19:14 -0500, Michael Sokolov wrote:
>> You might also someday be interested in the inverse function (roman numeral to decimal); here is what we use.  It might be interesting for the group to compare the iterative approach here with the recursive approach to a similar problem in Ken's version?
> 
> Interesting thought, Mike!
> 
>> declare namespace ifp="http://www.ifactory.com/press";
>> 
>> define function ifp:roman-number-to-decimal ($roman-number as xs:string)
>> {
>>  let $roman-tokens := <roman-tokens>
>> <tok sym='M'>1000</tok>
>> <tok sym='D'>500</tok>
>> <tok sym='C'>100</tok>
>> <tok sym='L'>50</tok>
>> <tok sym='X'>10</tok>
>> <tok sym='V'>5</tok>
>> <tok sym='I'>1</tok>
>> </roman-tokens>
>>  let $l := string-length($roman-number)
>>  return  sum (
>>    for $i in (0 to $l - 1)
>>      let $t := substring($roman-number, $l - $i, 1)
>>      let $s := substring($roman-number, $l - $i + 1, 1)
>>      let $tv := number($roman-tokens/tok[@sym=$t])
>>      let $sv := number($roman-tokens/tok[@sym=$s])
>>    return if ($sv and $sv gt $tv) then $tv * -1 else number($tv)
>>  )
>> };
> 
> I just modified my module as below in order to offer the inverse of Roman numeral to decimal, using the same lookup table as I use for the initial direction.  Interestingly, the solution has very much the same shape!
> 
> . . . . . . . . . . . . Ken
> 
> xquery version "1.0";
> 
> (:
>  A library to transform a number less than 4000 to a sequence of Roman digits.
> 
>  Crane Softwrights Ltd. XQuery Training
> :)
> 
> module namespace n2r = "urn:X-Crane:n2roman";
> 
> (:the basis of transformation is a series of strings for components:)
> declare variable $n2r:values as element(value)+ :=
> (
>  <value num="1"    char="I" />,
>  <value num="4"    char="IV"/>,
>  <value num="5"    char="V" />,
>  <value num="9"    char="IX"/>,
>  <value num="10"   char="X" />,
>  <value num="40"   char="XL"/>,
>  <value num="50"   char="L" />,
>  <value num="90"   char="XC"/>,
>  <value num="100"  char="C" />,
>  <value num="400"  char="CD"/>,
>  <value num="500"  char="D" />,
>  <value num="900"  char="CM"/>,
>  <value num="1000" char="M" />
> );
> 
> (:return the concatenation of strings by continuous reduction:)
> declare function n2r:n2roman ( $num as xs:integer ) as xs:string
> {
>  (:as long as we have a number, keep going:)
>  if ( $num ) then
>    (:reduce by the largest number that has a string value:)
>    for $val in $n2r:values[@num <= $num][fn:last()] return
>      (:using the highest value:)
>      fn:concat( $val/@char,n2r:n2roman( $num - xs:integer( $val/@num ) ) )
>  (:nothing left:)
>  else ""
> };
> 
> (:return the sum of numbers by continuous addition:)
> declare function n2r:roman2n ( $str as xs:string ) as xs:integer
> {
>  (:as long as we have a string, keep going:)
>  if ( $str ) then
>    (:reduce by the largest number that has a string value:)
>    for $val in $n2r:values[starts-with($str, at char)][fn:last()] return
>      (:using the highest value:)
>      xs:integer( $val/@num ) + n2r:roman2n(substring-after($str,$val/@char))
>  (:nothing left:)
>  else 0
> };
> 
> (:test all numbers up to but not including 4000:)
> declare function n2r:test ( ) as xs:integer*
> {
>  for $each in 1 to 3999 return if( $each != n2r:roman2n(n2r:n2roman($each)) )
>                                then $each else ()
> };
> 
> (:end of file:)
> 
> 
> --
> Contact us for world-wide XML consulting and instructor-led training
> Free 5-hour video lecture: XSLT/XPath 1.0 & 2.0 http://ude.my/t37DVX
> Crane Softwrights Ltd.            http://www.CraneSoftwrights.com/q/
> G. Ken Holman                   mailto:gkholman at CraneSoftwrights.com
> Google+ profile: https://plus.google.com/116832879756988317389/about
> Legal business disclaimers:    http://www.CraneSoftwrights.com/legal
> 
> _______________________________________________
> talk at x-query.com
> http://x-query.com/mailman/listinfo/talk



More information about the talk mailing list