<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<HTML xmlns="http://www.w3.org/TR/REC-html40" xmlns:o = 
"urn:schemas-microsoft-com:office:office" xmlns:w = 
"urn:schemas-microsoft-com:office:word"><HEAD>
<META http-equiv=Content-Type content="text/html; charset=us-ascii">
<META content="MSHTML 6.00.6001.18157" name=GENERATOR>
<STYLE>@page Section1 {size: 595.3pt 841.9pt; margin: 72.0pt 90.0pt 72.0pt 90.0pt; }
P.MsoNormal {
        FONT-SIZE: 12pt; MARGIN: 0cm 0cm 0pt; FONT-FAMILY: "Times New Roman"
}
LI.MsoNormal {
        FONT-SIZE: 12pt; MARGIN: 0cm 0cm 0pt; FONT-FAMILY: "Times New Roman"
}
DIV.MsoNormal {
        FONT-SIZE: 12pt; MARGIN: 0cm 0cm 0pt; FONT-FAMILY: "Times New Roman"
}
A:link {
        COLOR: blue; TEXT-DECORATION: underline
}
SPAN.MsoHyperlink {
        COLOR: blue; TEXT-DECORATION: underline
}
A:visited {
        COLOR: purple; TEXT-DECORATION: underline
}
SPAN.MsoHyperlinkFollowed {
        COLOR: purple; TEXT-DECORATION: underline
}
SPAN.EmailStyle17 {
        COLOR: windowtext; FONT-FAMILY: Arial; mso-style-type: personal-compose
}
DIV.Section1 {
        page: Section1
}
</STYLE>
</HEAD>
<BODY lang=EN-GB vLink=purple link=blue>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff size=2>The nearest to a map() function is the "for" 
expression</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff size=2>count(distinct-values(for $x in //element(*, 
xs:date)&nbsp;return timezone-from-date($x), </FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
for $x in //element(*, xs:dateTime)&nbsp;return timezone-from-dateTime($x), 
</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff 
size=2>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; 
for $x in //element(*, xs:time)&nbsp;return timezone-from-time($x))) eq 
1</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff size=2>But there is also the "simple mapping operator" "/" 
-</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff 
size=2>//element(*,xs:date)/timezone-from-date(.)</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff size=2>It's rather tedious that there's no polymorphism (or 
support of union types) so that the different date/time types have to be 
enumerated like this.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff size=2>Note that if a dateTime has no timezone, 
timezone-from-dateTime() will return (), which is ignored in counting the 
distinct values.</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff size=2></FONT></SPAN>&nbsp;</DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff size=2>Michael Kay</FONT></SPAN></DIV>
<DIV dir=ltr align=left><SPAN class=635264111-12122008><FONT face=Arial 
color=#0000ff size=2><A 
href="http://www.saxonica.com/">http://www.saxonica.com/</A></FONT>&nbsp;</SPAN></DIV><BR>
<BLOCKQUOTE dir=ltr 
style="PADDING-LEFT: 5px; MARGIN-LEFT: 5px; BORDER-LEFT: #0000ff 2px solid; MARGIN-RIGHT: 0px">
  <DIV class=OutlookMessageHeader lang=en-us dir=ltr align=left>
  <HR tabIndex=-1>
  <FONT face=Tahoma size=2><B>From:</B> talk-bounces@x-query.com 
  [mailto:talk-bounces@x-query.com] <B>On Behalf Of </B>Matthew 
  Rawlings<BR><B>Sent:</B> 12 December 2008 11:27<BR><B>To:</B> 
  talk@x-query.com<BR><B>Subject:</B> [xquery-talk] count all the distinct 
  timezones in an XML documentusing XPath<BR></FONT><BR></DIV>
  <DIV></DIV>
  <DIV class=Section1>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">How can I count all the distinct 
  timezones in a single XML document using XPath?<o:p></o:p></SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">I have an XML document with many 
  elements and attributes with the type xs:date or xs:datetime. One of the rules 
  of the system receiving my document is that all timezones must be the same in 
  the document. Ideally I would like to express this constraint purely in XPath 
  2 rather than XQuery so I can put the constraint in a xs:assert 
  statement.<o:p></o:p></SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">If there was a map function in 
  XPath I would write something like this:<o:p></o:p></SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">count(distinct-values(map(fn:date-from-timezone(), 
  //(element(*, xs:date)|attribute(*, xs:date)|element(*, 
  xs:datetime)|attribute(*, xs:datetime))))) eq 1<o:p></o:p></SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">This XPath would return true if 
  all timezones were the same, and false otherwise.<o:p></o:p></SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">However there is no map function 
  in XPath, so how can I achieve the same thing without it? What is the nearest 
  I could get.<o:p></o:p></SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial"><o:p>&nbsp;</o:p></SPAN></FONT></P>
  <P class=MsoNormal><FONT face=Arial size=2><SPAN 
  style="FONT-SIZE: 10pt; FONT-FAMILY: Arial">- 
  Matthew<o:p></o:p></SPAN></FONT></P></DIV></BLOCKQUOTE></BODY></HTML>