RE: First element with given attribute values
Just as I was about to hit send Mukul and Andreas already took care of business. Good morning guys! Not to take away from Mukul and Andreas excellent solutions but instead to show a slight variation which, when the situation is appropriate (using variables are great because you can utilize the results for grouping purposes throughout the lifecycle of the stylesheet. Mukul's for-each method will give you similar results to this apply-templates method. I find that a combination of both the variable and the for-each or apply-templates methods is a perfect combination if you want flexibility to do things like change the name of an element or attribute of each group member and then access the results using a variable reference later in your stylesheets(you will need to become familiar with your processors nodeset function first). For example this XSLT: <?xml version="1.0"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:key name="group" match="foo" use="concat(@name, '|' , @version)"/> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <xsl:apply-templates select="foobar/foo[generate-id() = generate-id(key('group', concat(@name, '|' , @version)))]"/> </xsl:template> <xsl:template match="foo"> <xsl:element name="group"> <xsl:attribute name="name"><xsl:apply-templates select="@*"/></xsl:attribute> </xsl:element> </xsl:template> <xsl:template match="@*"> <xsl:value-of select="."/> </xsl:template> </xsl:stylesheet> changes the name of the elements to "group" and then recursively creates a string value for the attribute "name" bringing all the attributes into one group name. So you get XML output that looks like this... <?xml version="1.0" encoding="UTF-8"?> <group name="a1"/> <group name="b1"/> <group name="b2"/> <group name="c1"/> By using Andreas method of creating a variable for later use (wrap an xsl:variable element around the apply-templates of the first template and give it a name for future reference) and then converting that variable to a node-set (using the select statement within another variable) will allow you access to that node-set for future use within your template(s). And now after writing all this Ive realized that I have probably confused more than ive done good. However, for future reference this may be helpful so I will go ahead and send it just in case it is. Best of luck! <M:D/> -----Original Message----- From: Nicolas Mailhot [mailto:Nicolas.Mailhot@xxxxxxxxxxx] Sent: Sunday, April 11, 2004 8:14 AM To: xsl-list@xxxxxxxxxxxxxxxxxxxxxx Subject: First element with given attribute values Hi, I find that very often I end up with lists of elements like: <foo name="a" version="1"/> <foo name="b" version="1"/> <foo name="a" version="1"/> <foo name="b" version="2"/> <foo name="c" version="1"/> <foo name="b" version="1"/> <foo name="b" version="1"/> Which I need to trim, keeping only the first element with an unique attibute value, or unique attribute values. For example, if I only wanted the first element with an unique name,version pair this would give : <foo name="a" version="1"/> <foo name="b" version="1"/> <foo name="b" version="2"/> <foo name="c" version="1"/> Is there a clean way to do it ? <xsl:template match="foo[@name=./@name and @version=./@version]"> only matches the first <foo name="a" version="1"/> Cheers, -- Nicolas Mailhot
PURCHASE STYLUS STUDIO ONLINE TODAY!
Purchasing Stylus Studio from our online shop is Easy, Secure and Value Priced!
Download The World's Best XML IDE!
Accelerate XML development with our award-winning XML IDE - Download a free trial today!
Subscribe in XML format