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

Re: using XSLT to transform a XML recordset

Subject: Re: using XSLT to transform a XML recordset
From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx>
Date: Wed, 22 Aug 2001 17:44:24 +0100
xslt row count
Hi Svend,

> notice how, each bundle, being the main identifier, doesn't always
> have the same number of resources. the idea being, that we want the
> base to be flexible, so no set amount of values have been defined.
> Just that it always contains a reskey (resourcekey), and a resvalue
> (resourcevalue), and these properties/values are tied to a bundle
> name, in the above example, "svendtofte" and "mikkel".

Say that you knew the name of the bundle, and that it was held in the
$bundle variable. In order to create the relevant attributes on the
element for that bundle, you'd need a quick way of getting the row
elements whose bundle attribute was $bundle. Once you got those, it
would be easy to use a predicate to find the one with the appropriate
reskey.

A 'quick way' of getting the row elements for a particular bundle is
to use xsl:key. Set up the key to index the row elements by their
bundle attribute, with an xsl:key top-level element, as follows:

<xsl:key name="rows" match="row" use="@bundle" />

With the key defined, you can find the rows for the $bundle bundle
with:

  key('rows', $bundle)

So you could create the element for the bundle with something like:

  <xsl:variable name="rows" select="key('rows', $bundle)" />
  <element bundle="{$bundle}"
           description="{$rows[@reskey = 'description']/@resvalue}"
           title="{$rows[@reskey = 'title']/@resvalue}"
           link="{$rows[@reskey = 'link']/@resvalue}"
           de="{$rows[@reskey = 'de']/@resvalue}"
           blah="{$rows[@reskey = 'blah']/@resvalue}" />

You can use the same key to get the possible values for the $bundle
variable using the Muenchian Method. If you go through each of the row
elements, you can find the ones that are the first with each
particular value for $bundle by seeing whether the row is the first
node that's returned by the key for their particular bundle. You can
do this with:

  <xsl:for-each select="row[count(.|key('rows', @bundle)[1]) = 1]">
    <xsl:variable name="bundle" select="@bundle" />
    <xsl:variable name="rows" select="key('rows', $bundle)" />
    <element bundle="{$bundle}"
             description="{$rows[@reskey = 'description']/@resvalue}"
             title="{$rows[@reskey = 'title']/@resvalue}"
             link="{$rows[@reskey = 'link']/@resvalue}"
             de="{$rows[@reskey = 'de']/@resvalue}"
             blah="{$rows[@reskey = 'blah']/@resvalue}" />
  </xsl:for-each>


You can use the same method to work out what possible values there are
for the @reskey attributes, store them in a global variable, and then
iterate over them when you need to create the element, if that's
necessary.
  
To improve performance, you could also use a separate key to retrieve
the resvalue attribute for a particular bundle+reskey combination, if
you wanted:

<xsl:key name="resvalues" match="row/@resvalue"
         use="concat(../@bundle, ':', ../@reskey)" />

and then retrieve the relevant values as follows:

  <xsl:for-each select="row[count(.|key('rows', @bundle)[1]) = 1]">
    <xsl:variable name="bundle" select="@bundle" />
    <element bundle="{$bundle}"
             description="{key('resvalues',
                               concat($bundle, ':description'))}"
             title="{key('resvalues', concat($bundle, ':title'))}"
             link="{key('resvalues', concat($bundle, ':link'))}"
             de="{key('resvalues', concat($bundle, ':de'))}"
             blah="{key('resvalues', concat($bundle, ':blah'))}"
  </xsl:for-each>

So yes, it's possible, and in a one-pass solution, though it's not
particularly straightforward (hopefully XSLT 2.0 will help with that
eventually).
  
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.