xsl-list
[Top] [All Lists]

RE: [xsl] Filter by id and date

2011-09-05 09:55:13
Thanks to yourself, Andrew and Wolfgang for your suggestions, which I received 
after I sent my own solution (stupid work Exchange server :). I knew about 
max() but had a temporary brain freeze as I was trying to do three things at 
once on a deadline this morning!

I did add the [1] as well to filter out identical duplicates. I would have 
considered adding this to the bundle of keys I'm using elsewhere in the 
transform, but since performance wasn't significantly affected, I didn't 
bother. But I'll definitely do that if the files get any larger - I'm a big fan 
of keys. :)

So thanks to everyone and sorry I didn't see your responses sooner!


-----Original Message-----
From: Tony Graham [mailto:tgraham(_at_)mentea(_dot_)net]
Sent: 05 September 2011 11:19
To: xsl-list(_at_)lists(_dot_)mulberrytech(_dot_)com
Subject: Re: [xsl] Filter by id and date

On Mon, September 5, 2011 10:36 am, Emma Burrows wrote:
...
<items>
  <item id='1' date='2011'>Item1</item>
  <item id='2' date='2009'>Item2</item>
  <item id='3' date='2002'>Item3</item>
  <item id='2' date='2011'>Item2</item>
  <item id='3' date='2002'>Item3</item>
</items>

For example, the Xpath in question looks like this right now (long-winded
but more efficient path-finding syntax simplified to // for this example,
and $idref obviously contains a valid id):

<xsl:value-of select="normalize-space(//item[@id=$idref])"/>

What is the best way to filter that to return only the item whose @date is
the highest for all items with @id=$idref?

The one-line solution is:

normalize-space(//item[@id=$item][@date = max(../item[@id=$item]/@date)][1])

Note the '[1]' to get rid of duplicates such as 'Item3' in your example.

You've already received a solution from Andrew Welch that first makes a
variable for all the possible matching values.  That would generally be
clearer and easier to understand when you come back to it in six months
time.

If you have a lot of data with a lot of duplicates in any order, it may be
simplest to process the data once to sort it by date and then change your
@select to "normalize-space(//item[@id=$idref][1])".

BTW, have you looked at using xsl:key?  Would it be possible to replace
the long and complicated XPath with a xsl:key that indexes the <item> with
a key based on, say, the string-join() of the significant variable data
from the XPath so you can just lookup the <item>s?)

Regards,


Tony Graham                                   tgraham(_at_)mentea(_dot_)net
Consultant                                 http://www.mentea.net
Mentea       13 Kelly's Bay Beach, Skerries, Co. Dublin, Ireland
 --  --  --  --  --  --  --  --  --  --  --  --  --  --  --  --
    XML, XSL FO and XSLT consulting, training and programming


--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--


______________________________________________________________________
This email has been scanned by the MessageLabs Email Security System.
For more information please visit http://www.messagelabs.com/email
______________________________________________________________________

--~------------------------------------------------------------------
XSL-List info and archive:  http://www.mulberrytech.com/xsl/xsl-list
To unsubscribe, go to: http://lists.mulberrytech.com/xsl-list/
or e-mail: <mailto:xsl-list-unsubscribe(_at_)lists(_dot_)mulberrytech(_dot_)com>
--~--

<Prev in Thread] Current Thread [Next in Thread>