Subject: Re: [xsl] Problem to place data into a specific <TD> From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Thu, 21 Dec 2000 11:43:38 +0000 |
Hi Roel, > I want this as output (with xsl) > > A B C > 1 1 2 3 > 2 1 3 > > with a for-each the problem is the last code is placed under B like: > > A B C > 1 1 2 3 > 2 1 3 This is kind of a grouping problem. You need to know what the possible code types are within your document as a whole and then, for each of the rows, cycle through those code types, giving the value for that code type if there is one, and nothing if there isn't. You can get the unique code types by getting all the codes that are first of their type, and then looking at their types. To select all the codes, use: /Root/code To filter those codes to select only those that are first of their type, you can check whether there are any preceding code elements that have the same type: if there are, then that particular type has already been counted: /Root/code[not(preceding-sibling::code/@type = @type)] This method of filtering can be quite inefficient if you've got lots of codes. An alternative is to use the Muenchian method to get a list of the code types. First, define a key to index all the 'code' elements according to their 'type' attribute: <xsl:key name="code-types" match="code" use="@type" /> This means that you can retrieve all the 'code' elements with a specific type using the key() function. For example, key('code-types', 'A') will give you all the codes with a type attribute equal to 'A'. So you can find out whether the particular code is the first with a particular type by seeing if it's the first in the list retrieved by the key for that type. You can do this with: /Root/code[generate-id() = generate-id(key('code-types', @type)[1])] [i.e. select those codes whose unique ID is the same as the unique ID of the first code with the same type retrieved from the code-types key] or: /Root/code[count(. | key('code-types', @type)[1]) = 1] [i.e. select those codes such that a union of the code with the first code with the same type retrieved from the code-types key gives a node list that is only one node long]. So, you can set up a list of the unique code types within your document in a variable: <xsl:variable name="code-types" select="/Root/code[generate-id() = generate-id(key('code-types', @type)[1])]/@type" /> Do this at the top level, or at least not within any of the xsl:for-eaches: you only want and need to do it once. Now, when you go through each set of codes to create a row, you can use the $code-types variable to drive the creation of the cells. Within the xsl:for-each that's creating each row, have a xsl:for-each that iterates over the $code-types variable: <xsl:for-each select="$code-types"> ... </xsl:for-each> Let's say that the code elements for a particular row are in a variable called $codes. For each of the code types, you want to pick out the code that has the same type as the type you're currently looking at. If there is such a code, you want to give its value; if there isn't, then you want an empty cell in the table. Within the xsl:for-each on the $code-types, the current node is a 'type' attribute. To get the codes within the $codes variable with a matching type, you use: $codes[@type = current()] So, to give that value within the cell, use: <xsl:for-each select="$code-types"> <td> <xsl:value-of select="$codes[@type = current()]" /> </td> </xsl:for-each> By the way, if you're not already, you might find it helpful to use keys to group the codes by ID, something like: <xsl:key name="codes-by-ID" match="code" use="preceding-sibling::ID[1]" /> and then: <xsl:for-each select="ID"> <xsl:variable name="codes" select="key('codes-by-ID', .)" /> <tr> <xsl:for-each select="$code-types"> <td> <xsl:value-of select="$codes[@type = current()]" /> </td> </xsl:for-each> </tr> </xsl:for-each> I hope that helps, 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] Problem to place data into a , Roel Mertens | Thread | Re: [xsl] Problem to place data int, Dimitre Novatchev |
Re: AW: [xsl] Template priority, David Carlisle | Date | [xsl] Dynamic sort order.., Ian Sparks |
Month |