[XSL-LIST Mailing List Archive Home] [By Thread] [By Date] [Recent Entries] [Reply To This Message]

Side-effect and PROGN, example JDBC in XSLT

Subject: Side-effect and PROGN, example JDBC in XSLT
From: Gunther Schadow <gunther@xxxxxxxxxxxxxxxxxxxxxx>
Date: Fri, 20 Jun 2003 01:12:02 -0500
saxon jdbc
Hi, on the issue of side-effects, I rediscovered the PROGN form
that we know from LISP as the thing that's needed in order to
handle inevitable side-effects in non-trivial XSLT applicaitons.
I guess all of that was mentioned in our earlier thread about
this. But I have now a bunch of experience with it and it may
be useful for others to share this again.

Use case: an XSLT application that retrieves or updates data from
a database. With SAXON one can easily script any JDBC work right
in XSLT and it works beautifully. But one needs to make sure the
extension-functions are called in the proper sequence. The way
to do that is to relate variables with dependencies to other
variables AND to specify short sequences that need to be evaluated
in order. The latter is known from LISP as the PROGN form.
PROGN was a primitive and simply a list that was evaluated right
to left and whose result was the last element (n-th element,
hence PROG-N.)

In Saxon 7.5.1 (XSLT/XPath 2.0) this can currently be emulated
with the sequence form:

  <xsl:param name="driversToLoad">
    <class name="org.postgresql.Driver"/>
    <class name="oracle.jdbc.OracleDriver"/>
  </xsl:param>

  <xsl:variable name="driversLoaded"
    xmlns:class="java:java.lang.Class"
    select="for $className in $driversToLoad/class/@name
              return class:forName(@name)"/>

  <xsl:variable name="newConnection"
    xmlns:dm="java:java.sql.DriverManager"
    select="($driversLoaded,
             dm:getConnection($url,$username,$password))[last()]"/>

  <xsl:variable name="connection"
    xmlns:c="java:java.sql.Connection"
    select="(c:setAutoCommit($newConnection, false()),
             $newConnection)[last()]"/>

  <xsl:variable name="SQL">
     SELECT FOO, BAR, BAZ FROM FOOBAR WHERE KNOX=? AND KOUTS=>
  </xsl:variable>

  <xsl:variable name="statement"
    xmlns:c="java:java.sql.Connection"
    select="c:prepareStatement($connection, $SQL)"/>

  <xsl:template match="foobar[@knox and @kouts]">
    <xsl:variable name="resultSet"
      xmlns:st="java:java.sql.PreparedStatement"
      select="(st:setLong($statement, 1, @knox),
               st:setString($statement, 1, @kouts),
               st:executeQuery())[last()]"/>
    <saxon:while test="rs:next($resultSet)">
      <foobar knox="{@knox}" kouts="{@kouts}"
         foo="{rs:getString($resultSet,'FOO')}"
         bar="{rs:getString($resultSet,'BAR')}"
         baz="{rs:getString($resultSet,'BAZ')}"/>
    </saxon:while>
  </xsl:template>

Notice how the dependencies on those variables, NOT
the order of appearence of the xsl:variable elements
forms the execution sequence like a string of pearls.
Also, notice how the same object (here the Connection)
appears under different names (newConnection and connection)
to reflect the different states (new and initialized.)

This works currently because (a) the Saxon optimizer isn't
so smart as to perform lazy-evaluation of sequence
elements or (b) to refuse to evaluate extension functions
that return void.

On that matter I would say that I am prepared for (a) and
(b) should just never happen. If lazy-evaluation of
sequence elements becomes reality (it's a great idea), so
that in a sequence ($x1, $x2, $x3, ..., $xn)[last()] only
the $xn will ever be evaluated, I will introduce my own
extension function, called progn(any*) that will evaluate
every argument left to right and return the last. No big
deal.

I think that (b) the optimizer should never refuse to
evaluate extension functions returning void because there
would be no point in doing this. It would be a piece of
code designed specifically to make people like me unhappy
and would serve no other purpose. I shall be prepared to
take such code out of whatever XSLT processor will do
this.

thanks
-Gunther

PS: Interestingly even Saxon 7.5.1 sometimes
evaluates variables/@select expressions even though the
variable is never actually referenced. But I would never
exploit such odd behavior, actually it is now even
hurting me.

--
Gunther Schadow, M.D., Ph.D.                    gschadow@xxxxxxxxxxxxxxx
Medical Information Scientist      Regenstrief Institute for Health Care
Adjunct Assistant Professor        Indiana University School of Medicine
tel:1(317)630-7960                         http://aurora.regenstrief.org



XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list


Current Thread

PURCHASE STYLUS STUDIO ONLINE TODAY!

Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!

Buy Stylus Studio Now

Download The World's Best XML IDE!

Accelerate XML development with our award-winning XML IDE - Download a free trial today!

Don't miss another message! Subscribe to this list today.
Email
First Name
Last Name
Company
Subscribe in XML format
RSS 2.0
Atom 0.3
Site Map | Privacy Policy | Terms of Use | Trademarks
Free Stylus Studio XML Training:
W3C Member
Stylus Studio® and DataDirect XQuery ™are products from DataDirect Technologies, is a registered trademark of Progress Software Corporation, in the U.S. and other countries. © 2004-2013 All Rights Reserved.