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 |