Subject: Re: problem sorting uniquely w/transform() From: Jeni Tennison <mail@xxxxxxxxxxxxxxxx> Date: Sun, 10 Sep 2000 19:01:33 +0100 |
Shane, >i am having a problem sorting uniquely on an element name... i'm >translating the <LEAGUE NAME="..."> element to uppercase and seeing if it >matches any preceding elements. In the comparison that does not involve case-insensitive translation, you select: //LEAGUE[not(@NAME = preceding::*/@NAME)] Within equality tests, the way the result is worked out depends on the type of the nodes that are involved. When they involve node sets (as in this case), the equality expression returns true if there are nodes within the node set(s) for which the equality expression will be true. In other words, "@NAME = preceding::*/@NAME" returns true if *any* of the preceding elements has a NAME attribute that matches the NAME attribute of the current node. When you select with the translation: //LEAGUE[not(translate(@NAME,$lower,$upper) = translate(preceding::*/@NAME,$lower,$upper))] things work differently because the translate() function returns a string. Doing: translate(preceding::*/@NAME, $lower, $upper) translates the string value of the node set preceding::*/@NAME from lower case to upper case, and returns this string. The string value of a node set is the string value of the first node in the node set - the value of the first preceding element's NAME attribute. That means that you're testing the equality of the translated @NAME of the current element with the translated @NAME of the first preceding element, not comparing it with all the other preceding element's @NAMEs. I don't *think* it's possible to do the selection you're after with a single select expression, but you could get around it by doing a xsl:for-each on all the //LEAGUE elements, and containing within it an xsl:if that only retrieved those who don't have a preceding element with the same (translated) name: <xsl:for-each select="//LEAGUE"> <xsl:sort select="@NAME" /> <xsl:variable name="name" select="translate(@NAME, $lower, $upper)" /> <xsl:if test="not(preceding::*[translate(@NAME, $lower, $upper) = $name])"> <!-- do stuff --> </xsl:if> </xsl:for-each> If possible, for efficiency, you should probably give a more exact indication of the LEAGUE elements you're interested in (e.g. '/SCORES/LEAGUE') and if you're only interested in the preceding-sibling::LEAGUE elements, you should use this rather than the general preceding::*. Generally, more specific XPath expressions are more efficient. I hope that this 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 -> |
---|---|---|
problem sorting uniquely w/transfor, Shane Knapp | Thread | RE: problem sorting uniquely w/tran, Kay Michael |
Re: XSLT V 1.1, Eric van der Vlist | Date | Re: parameter count in xsl:number, Jeni Tennison |
Month |