At 2010-10-21 10:12 -1000, Brooks Talley wrote:
I've been wresting with this, and my brain is melting. I need to get a
list of the surrounding years for an item -- zero to two years before,
the item itself, zero to two years after. There may be gaps in the
sequence, in which case I still need two items before and after (if
available).
Sample xml:
...
Desired output (or similar, the select is the hard part):
I couldn't do it in a single select assuming XSLT 1.0 ... if you are
using XSLT 2.0 then you can review the below and munge the tests into
predicates.
I created a second test file that tries to exercise more of your
requirements than did your given test file.
I hope this helps.
. . . . . . . . . . Ken
T:\ftemp>type brooks.xml
<root>
<item>
<id>12345</id>
<year>2005</year>
</item>
<otherYears>
<item>
<id>56789</id>
<year>2001</year>
</item>
<item>
<id>67890</id>
<year>2002</year>
</item>
<item>
<id>78901</id>
<year>2003</year>
</item>
<item>
<id>12345</id>
<year>2005</year>
</item>
<item>
<id>89012</id>
<year>2006</year>
</item>
<item>
<id>90123</id>
<year>2008</year>
</item>
</otherYears>
</root>
T:\ftemp>type brooks.xsl
<?xml version="1.0" encoding="US-ASCII"?>
<xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
version="1.0">
<xsl:output method="text"/>
<xsl:template match="/">
<xsl:for-each select="*/otherYears/item
[id=/*/item/id and year=/*/item/year]">
<xsl:variable name="before"
select="preceding-sibling::*[year >= current()/year - 2]"/>
<xsl:choose>
<xsl:when test="count($before) < 2">
<xsl:apply-templates select="preceding-sibling::*[position()
< 3]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$before"/>
</xsl:otherwise>
</xsl:choose>
<xsl:apply-templates select="."/>
<xsl:variable name="after"
select="following-sibling::*[year <=
current()/year +2]"/>
<xsl:choose>
<xsl:when test="count($after) < 2">
<xsl:apply-templates select="following-sibling::*[position()
< 3]"/>
</xsl:when>
<xsl:otherwise>
<xsl:apply-templates select="$after"/>
</xsl:otherwise>
</xsl:choose>
</xsl:for-each>
</xsl:template>
<xsl:template match="item">
<xsl:value-of select="year"/> = <xsl:value-of select="id"/>
<xsl:text>
</xsl:text>
</xsl:template>
</xsl:stylesheet>
T:\ftemp>call xslt brooks.xml brooks.xsl
2002 = 67890
2003 = 78901
2005 = 12345
2006 = 89012
2008 = 90123
T:\ftemp>call xslt brooks2.xml brooks.xsl
2003 = 78901
2004 = 44441
2005 = 12345
2006 = 89012
2007 = 77771
2007 = 77772
2007 = 77773
T:\ftemp>type brooks2.xml
<root>
<item>
<id>12345</id>
<year>2005</year>
</item>
<otherYears>
<item>
<id>56789</id>
<year>2001</year>
</item>
<item>
<id>67890</id>
<year>2002</year>
</item>
<item>
<id>78901</id>
<year>2003</year>
</item>
<item>
<id>44441</id>
<year>2004</year>
</item>
<item>
<id>12345</id>
<year>2005</year>
</item>
<item>
<id>89012</id>
<year>2006</year>
</item>
<item>
<id>77771</id>
<year>2007</year>
</item>
<item>
<id>77772</id>
<year>2007</year>
</item>
<item>
<id>77773</id>
<year>2007</year>
</item>
<item>
<id>90123</id>
<year>2008</year>
</item>
</otherYears>
</root>
T:\ftemp>rem Done!
--
XSLT/XQuery training: after http://XMLPrague.cz 2011-03-28/04-01
Vote for your XML training: http://www.CraneSoftwrights.com/s/i/
Crane Softwrights Ltd. http://www.CraneSoftwrights.com/s/
G. Ken Holman mailto:gkholman(_at_)CraneSoftwrights(_dot_)com
Male Cancer Awareness Nov'07 http://www.CraneSoftwrights.com/s/bc
Legal business disclaimers: http://www.CraneSoftwrights.com/legal
--~------------------------------------------------------------------
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>
--~--