[xquery-talk] Union types

Srdjan Djuricic sdjuricic at galdosinc.com
Fri Jan 12 14:18:58 PST 2007


Thank you for your reply.  Yes that is what I was looking for.  I was
looking for "castable" function.

Thank you once again,

Srdjan

-----Original Message-----
From: James A. Robinson [mailto:jim.robinson at stanford.edu] 
Sent: Friday, January 12, 2007 1:54 PM
To: Srdjan Djuricic
Cc: talk at x-query.com
Subject: Re: [xquery-talk] Union types 


> However, if I have unions I can not determine what my 'mask' should
be.
> As an approach I tried using "instance of" operator to check literal 
> values but that does not return the result that I was looking for.  As

> an example I used 1999-12-31T12:00:00 to check if it is xs:dateTime 
> and it gave me false.  I am a beginner when it comes to X-Query.

It may be that I don't understand what you want, my apologies if that is
the case.  My reading of your note made me think you want a way to cast
an unknown xs:string into the proper type for an attribute of element
value which is declared to be a union of the specific types you mention?

So, for example, a function to find the 'best match' for the variables
you listed might be something like:

declare namespace f="uri.local-functions";

declare function f:toMyType($u as xs:string) {
    if ($u castable as xs:dateTime)
    then xs:dateTime($u)
    else if ($u castable as xs:time)
    then xs:time($u)
    else if ($u castable as xs:date)
    then xs:date($u)
    else if ($u castable as xs:gYearMonth)
    then xs:gYearMonth($u)
    else if ($u castable as xs:gYear)
    then xs:gYear($u)
    else if ($u castable as xs:decimal)
    then xs:decimal($u)
    else if ($u castable as xs:anyURI)
    then xs:anyURI($u)
    else
      error(xs:QName("f:toMyType"), concat("unable to case ", $u)) };

And so calling

for $t in (
  trace(f:toMyType("2006-01-12T00:00:00Z"), "2006-01-12T00:00Z"),
  trace(f:toMyType("10:00:00Z"), "10:00:00Z"),
  trace(f:toMyType("2007-01-12"), "2007-01-12"),
  trace(f:toMyType("2007-01"), "2007-01"),
  trace(f:toMyType("2007"), "2007"),
  trace(f:toMyType("10.1"), "10.1"),
  trace(f:toMyType("http://foo.bar.com/"), "http://foo.bar.com/"))
return
  $t

Yeilds the following trace data:

2006-01-12T00:00Z [1]: xs:dateTime: 2006-01-12T00:00:00Z 10:00:00Z [1]:
xs:time: 10:00:00Z
2007-01-12 [1]: xs:date: 2007-01-12
2007-01 [1]: xs:gYearMonth: 2007-01
2007 [1]: xs:gYear: 2007
10.1 [1]: xs:decimal: 10.1
http://foo.bar.com/ [1]: xs:anyURI: http://foo.bar.com/

That kind of return would, I think, allow you to call things like

  attribute {'pbs:myProp'} {
    f:toMyType($u)
  }

in order to, in this case, get an attribute named pbs:myProp, assuming
it's been declared in a schema as being the simpleType union you
declared.

Is that what you needed?  If not, my apologies for wasting bandwidth.
I'm new at XQuery so I may be missing something in the description you
gave. :(


Jim
P.S. I'm not sure, is there any danger/overlap between having a union
which can take both xs:GYear and xs:decimal? I think the technique I
outline can give ambigious results if your input is something like
'1000' -- it could be cast to xs:gYear, in which case you'd need to be
performing an additional check on matches to 'castable as xs:gYear'.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
James A. Robinson                       jim.robinson at stanford.edu
Stanford University HighWire Press      http://highwire.stanford.edu/
+1 650 7237294 (Work)                   +1 650 7259335 (Fax)



More information about the talk mailing list