|
Subject: Re: [xsl] using XSLT to transform a XML recordset From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Wed, 22 Aug 2001 17:44:24 +0100 |
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 |
|---|
|
| <- Previous | Index | Next -> |
|---|---|---|
| [xsl] using XSLT to transform a XML, Svend Ezaki Tofte | Thread | [xsl] XPath needed for getting the , Sanjay Pandey/Towers |
| Re: [xsl] A little cross referencin, Joerg Pietschmann | Date | Re: [xsl] namespace and XPath quest, Jeni Tennison |
| Month |