[xquery-talk] Xquery to xslt conversions

David Carlisle davidc at nag.co.uk
Wed Jan 11 16:08:55 PST 2006


[I changed the subject line as we seem to have moved off the test suite]


Michael

>   element x {
>   attribute a {3},
>   attribute a {4}
> }
> 
> How are you handling that?

Incorrectly.  Added it to my test files, thanks.

I could easily detect that case (with the names being qnames) at
conversion time and generate an error. In the general case where the
element names are constructed in an enclosed expression, detection in
XSLT is likely to be expensive need two passes, make a sequence of
qnames somehow in a variable and then check it doesn't have duplicates.
Hmm or I fail that test, I'll see what's reasonable to do and will add
the test for attributes names given by qname or by direct attribute
constructors anyway, as that's fairly easy.

> Also, how are you handling the XQuery "order by" problem: what XSLT code do
> you generate for pathological cases like
> 
> for $x in 1 to 10, $y in 100 to 200
> order by $y, $x
> return $x + $y


I've got _much_ more pathological test cases than that for flwor;-)
As far as I can see, I get the right answer here from the code below.
I have three different mappings of FLWOR expressions.
1) an identity transform if the stylesheet detects that it's an XPath for.
2) as a "natural" mapping to a nested set of xsl:for-each if there
   is no order by or only one bound variable,
3) the version below which models a tuple as a sequence of integers
   which index into an existing xpath sequence, and models sequences of
   tupes as sequences of strings where the string is an encoding of the
   integer sequence that models the tuple. (essentially the integer
   sequence is just taken as the unicode code point, shifted by 32 to
   avoid banned characters). As I only use one character per integer I'm
   restricted to sequences with less than hex 10FFFF items, but that's
   enough for me. I could easily change this to use two characters per
   integer if someone had some really long sequences to handle.


David



<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xq="java:Xq2xml"
                xmlns:xs="http://www.w3.org/2001/XMLSchema"
                xmlns:local="http://www.w3.org/2005/xquery-local-functions"
                xmlns:fn="http://www.w3.org/2005/xpath-functions"
                xmlns:xdt="http://www.w3.org/2005/xpath-datatypes"
                xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
                version="2.0"
                extension-element-prefixes="xq"
                exclude-result-prefixes="xq xs xsi xdt local fn">
   <xsl:param name="input" as="item()" select="1"/>
   <xsl:output indent="yes"/>
   <xsl:template name="main">
      <xsl:for-each select="$input">
         <xsl:variable name="xq:here" select="."/>
         <xsl:variable name="xq:forc" as="xs:string*">
            <xsl:for-each select="( 1  to  10 )">
               <xsl:variable name="x" select="."/>
               <xsl:variable name="xq:p1" select="position()"/>
               <xsl:for-each select="( 100  to  200 )">
                  <xsl:variable name="y" select="."/>
                  <xsl:variable name="xq:p2" select="position()"/>
                  <xsl:sequence select="codepoints-to-string(($xq:p1+32,$xq:p2+32))"/>
               </xsl:for-each>
            </xsl:for-each>
         </xsl:variable>
         <xsl:for-each select="$xq:forc">
            <xsl:sort select="xq:orderby_d1e76(.)"/>
            <xsl:sort select="xq:orderby_d1e91(.)"/>
            <xsl:variable name="xq:index" select="for $i in string-to-codepoints(.) return($i - 32)"/>
            <xsl:for-each select="$xq:here">
               <xsl:variable name="xq:p1" select="$xq:index[1]"/>
               <xsl:variable name="x" select="(( 1  to  10 ))[$xq:p1]"/>
               <xsl:variable name="xq:p2" select="$xq:index[2]"/>
               <xsl:variable name="y" select="(( 100  to  200 ))[$xq:p2]"/>
               <xsl:sequence select="($x + $y)"/>
            </xsl:for-each>
         </xsl:for-each>
      </xsl:for-each>
   </xsl:template>

   <xsl:function name="xq:orderby_d1e76" as="item()*">
      <xsl:param name="xq:here"/>
      <xsl:for-each select="$xq:here">
         <xsl:variable name="xq:index" select="for $i in string-to-codepoints(.) return($i - 32)"/>
         <xsl:variable name="xq:p1" select="$xq:index[1]"/>
         <xsl:variable name="x" select="(( 1  to  10 ))[$xq:p1]"/>
         <xsl:variable name="xq:p2" select="$xq:index[2]"/>
         <xsl:variable name="y" select="(( 100  to  200 ))[$xq:p2]"/>
         <xsl:sequence select="$y"/>
      </xsl:for-each>
   </xsl:function>
   <xsl:function name="xq:orderby_d1e91" as="item()*">
      <xsl:param name="xq:here"/>
      <xsl:for-each select="$xq:here">
         <xsl:variable name="xq:index" select="for $i in string-to-codepoints(.) return($i - 32)"/>
         <xsl:variable name="xq:p1" select="$xq:index[1]"/>
         <xsl:variable name="x" select="(( 1  to  10 ))[$xq:p1]"/>
         <xsl:variable name="xq:p2" select="$xq:index[2]"/>
         <xsl:variable name="y" select="(( 100  to  200 ))[$xq:p2]"/>
         <xsl:sequence select="$x"/>
      </xsl:for-each>
   </xsl:function>
</xsl:stylesheet>

________________________________________________________________________
This e-mail has been scanned for all viruses by Star. The
service is powered by MessageLabs. For more information on a proactive
anti-virus service working around the clock, around the globe, visit:
http://www.star.net.uk
________________________________________________________________________


More information about the talk mailing list