Subject: RE: [xsl] selecting node with longest data string From: "Sullivan, Dan" <dsullivan@xxxxxxxxxxx> Date: Sat, 25 Aug 2001 07:59:16 -0700 |
Here are two ways to find the item's with the longest text content. This first solution is using the same technique as you, but eliminates building the string and pulling it apart (watch for line breaks) The second solution is a bit more typing but eliminates sorting the input, so should be faster. (watch for line breaks) Note that in both solutions a key is used to pull out all of the longest item's, if there is more than one. If you only want a single longest item this could be eliminated. Of course there can't be two longest but you know what I mean.:) Dan First solution: <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="xml" indent="yes"/> <!-- used later to find all item's as long as the longest single item found --> <xsl:key name="length" match="/items/item" use="string-length(.)"/> <xsl:template match="/"> <longest> <!-- iterate through items in order of length, longest first --> <xsl:for-each select="items/item"> <xsl:sort select="string-length(.)" data-type="number" order="descending"/> <!-- only use the first on found --> <xsl:if test="position()=1"> <!-- copy out all of the items as long as this first one --> <xsl:copy-of select="key('length', string-length(.))"/> </xsl:if> </xsl:for-each> </longest> </xsl:template> </xsl:stylesheet> Second solution <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <!-- just to make output easy to read --> <xsl:output method="xml" indent="yes"/> <!-- used at end to find all item's that have the same length as longest one found --> <xsl:key name="length" match="/items/item" use="string-length(.)"/> <!-- keeps iterating through every item to find the longest one --> <xsl:template name="find-longest"> <!-- item currently being looked at --> <xsl:param name="item"/> <!-- longest one found so far --> <xsl:param name="longest"/> <!-- This is the next item to be looked at --> <xsl:variable name="next" select="$item/following-sibling::item[1]"/> <xsl:choose> <xsl:when test="$next"> <!-- if there are more items keep looking --> <xsl:call-template name="find-longest"> <!-- pass in the next item to be tested --> <xsl:with-param name="item" select="$next"/> <!-- pass in the current item as the longest if it is longer than the next one --> <xsl:with-param name="longest" select="$item[string-length(.)>=string-length($longest)]|$longest[not(st ring-length($item) >= string-length(.))]"/> </xsl:call-template> </xsl:when> <xsl:otherwise> <!-- nothing else to look at, $longest does have the longest now --> <xsl:value-of select="$longest"/> </xsl:otherwise> </xsl:choose> </xsl:template> <xsl:template match="/"> <!-- wrapper to make output well-formed --> <longest> <!-- holds longest item --> <xsl:variable name="longest"> <!-- start looking for longest by passing inline=" the first item as the longest --> <xsl:call-template name="find-longest"> <xsl:with-param name="item" select="/items/item[1]"/> <xsl:with-param name="longest" select="/items/item[1]"/> </xsl:call-template> </xsl:variable> <!-- since find-longest only finds one longest, use key to find all of them --> <xsl:copy-of select="key('length', string-length($longest))"/> </longest> </xsl:template> </xsl:stylesheet> -----Original Message----- From: Mayura Malagala [mailto:TS2664@xxxxxxxxxxxx] Sent: Saturday, August 25, 2001 7:17 AM To: 'xsl-list@xxxxxxxxxxxxxxxxxxxxxx' Subject: [xsl] selecting node with longest data string Hi All, I'm using MSXML3 sp1. I've got an XML that looks like : <?xml version="1.0" encoding="ISO8859-1"?> <items> <item>dd</item> <item>eeeee</item> <item>aaa</item> <item>ffffffffff</item> <item>c</item> <item>bbbb</item> </items> I want to get the item which has the longest data string as its value. I managed to do it with the following xsl, but it seems very crude. Could someone please tell me a more efficient way of doing this. <?xml version="1.0" ?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1. 0" > <xsl:output method='html' /> <xsl:template match="/"> <xsl:variable name="SortedItems" > <xsl:call-template name="SortItems" /> </xsl:variable> <xsl:variable name="FinalValue"> <xsl:value-of select="substring-before($SortedItems,'|') " /> </xsl:variable> longest = <xsl:value-of select="string-length($FinalValue)" /> </xsl:template> <xsl:template name="SortItems"> <xsl:for-each select="items/item"> <xsl:sort select="string-length(.)" data-type="number" order="descending" /> <xsl:value-of select="." />| </xsl:for-each> </xsl:template> </xsl:stylesheet> Thanks in advance, Mayura XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list XSL-List info and archive: http://www.mulberrytech.com/xsl/xsl-list
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
[xsl] selecting node with longest d, Mayura Malagala | Thread | [xsl] call-template with-param prob, Phillip Rhodes |
[xsl] selecting node with longest d, Mayura Malagala | Date | [xsl] call-template with-param prob, Phillip Rhodes |
Month |