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

Re: Executing variable XPath queries in XSLT

Subject: Re: Executing variable XPath queries in XSLT
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Fri, 22 Jun 2001 18:53:35 +0100
variable xpath
Hi Joe,

> And I would like to then execute this query using $xpath-query in a
> select statement. I would like to do this entirely in XSLT using no
> extension mechanisms. I'm wondering if there are any tricks, known
> ways to execute these kinds of expressions.

You've identified the two best ways: a two-phase transformation and an
extension function.

You *can* do it in one XSLT instead, and it might be worthwhile to
avoid the downsides of the other two methods, as long as the paths
that you're using aren't at all complicated (like they don't involve
predicates).  Basically, you can work through the string, traversing
the document as you go.  Create a template that matches an element and
takes a path as a parameter:

<xsl:template match="/|*" mode="path">
   <xsl:param name="path" />
   ...
</xsl:template>

If the $path parameter contains a '/' then you need to walk down to
the child element that's named before the '/' in the $path, passing
down the $path parameter after the '/':

<xsl:template match="/|*" mode="path">
   <xsl:param name="path" />
   <xsl:choose>
      <xsl:when test="contains($path, '/')">
         <xsl:apply-templates
               select="*[name() = substring-before($path, '/')]">
            <xsl:with-param name="path"
                            select="substring-after($path, '/')" />
         </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
         ...
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>

If there isn't a '/' in the $path, then you're one step away from your
destination.  You want to then somehow activate the rule.  I guess the
easiest way to do this would be to be passing the rule down along with
the path, and then apply templates to the rule with the relevant node
passed as a parameter:

<xsl:template match="/|*" mode="path">
   <xsl:param name="rule" select="/.." />
   <xsl:param name="path" select="substring($rule/expression, 2)" />
   <xsl:choose>
      <xsl:when test="contains($path, '/')">
         <xsl:apply-templates
               select="*[name() = substring-before($path, '/')]">
            <xsl:with-param name="path"
                            select="substring-after($path, '/')" />
            <xsl:with-param name="rule" select="$rule" />
         </xsl:apply-templates>
      </xsl:when>
      <xsl:otherwise>
         <xsl:apply-templates select="$rule">
            <xsl:with-param name="node"
                            select="*[name() = $path]" />
         </xsl:apply-templates>
      </xsl:otherwise>
   </xsl:choose>
</xsl:template>

Note that the above template leaves a lot to be desired - it only
deals with element hierarchies, not attributes, doesn't handle
predicates at all, doesn't deal well with whitespace and so on.
Really I'm giving it as an example of the kind of thing that you have
to do to interpret XPaths dynamically within XSLT without using an
extension function.

Cheers,

Jeni

---
Jeni Tennison
http://www.jenitennison.com/


 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.