Subject: Re: [xsl] cross-reference & xsl:sort - MSXML3 vs MSXML4 From: Jeni Tennison <jeni@xxxxxxxxxxxxxxxx> Date: Tue, 16 Apr 2002 09:53:18 +0100 |
Hi David, > I want to pass in a collection/@name and get a list of all the > corresponding part elements (cross refence). Then I want to sort the > data first by part/@type, then by part/@name. I lifted the sample > xml from a similar note posted to this list in October 2001. That > email is duplicated at the bootom. I never did see that problem > answered. Whenever you're dealing with cross references, the first thing you should do is set up a key that indexes the things that you want to get access to by the value through which you want to access them. In this case, you want to access the part elements by their id attribute: <xsl:key name="parts" match="part" use="@id" /> You can then get a part with a particular id through the key function. For example, the following gets the part with id '3': key('parts', '3') One of the useful features of the key function is that if you pass in a node set as the second argument, the XSLT processor goes through each of the nodes, using their string value to retrieve nodes from the key, and then unions the results together. So for example, if you're on a collection element then you can get all the parts referenced by all the ref element children (through their refid attributes) with: key('parts', ref/@refid) This is really powerful in your case because it immediately gives you the list of the parts that you want to sort. Your code becomes a lot simpler: <xsl:template match="/large-collection/collection"> <xsl:if test="@name = $MyGroup"> <xsl:for-each select="key('parts', ref/@refid)"> <xsl:sort select="@type" /> <xsl:sort select="@name" /> <xsl:value-of select="concat('type: ', @type, ' name: ', @name, ' id: ', @id, '
')" /> </xsl:for-each> </xsl:if> </xsl:template> By the way, I'd usually only apply templates to the nodes that I was interested in; in your example, you could apply templates directly to the collection element whose name is equal to $MyGroup, from within a template matching the large-collection element: <xsl:template match="large-collection"> <xsl:apply-templates select="collection[@name = $MyGroup]" /> </xsl:template> Then you wouldn't need the xsl:if within the template matching collection elements. 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] cross-reference & xsl:sort - , David Chryst | Thread | [xsl] XML file not able to view on , tanska |
[xsl] RE: untitled from Biray Giray, TSchutzerWeissmann | Date | Re: [xsl] Unique list of all linked, Jeni Tennison |
Month |