Subject: Re: RE: [xsl] Collating riffled lists From: a.kielen@xxxxxxx Date: Tue, 30 Sep 2003 9:32:03 +0200 |
Hi Mat, Try this: <?xml version="1.0"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform"> <xsl:output omit-xml-declaration="yes"/> <xsl:template match="list"> <xsl:for-each select="item[contains(.,'a')]"> <xsl:variable name="number" select="position()"/> <xsl:value-of select="$number"/>. <xsl:text/> <xsl:value-of select="substring-after(.,' ')"/> <xsl:apply-templates select="../item[contains(.,'b')][contains(., $number)]" mode="b"/> <xsl:text>
</xsl:text> </xsl:for-each> </xsl:template> <xsl:template mode="b" match="item"> <xsl:text> </xsl:text> <xsl:value-of select="substring-after(.,' ')"/> </xsl:template> <xsl:template match="item"/> </xsl:stylesheet> You're real problem is probably more difficult, but I hope this gives a hint. Cheers, Agnes > > Van: "Mat Myszewski" <mmyszew@xxxxxxxxxxx> > Aan: <XSL-List@xxxxxxxxxxxxxxxxxxxxxx> > Datum: di 30 sep 03, 3:10 > Onderwerp: RE: [xsl] Collating riffled lists > > Michael > > Thanks for the info. I tried it and it works on the abstract problem as > advertised. > > And thanks for your XSLT book! It's been a great help to this XSLT newbie. > > Unfortunately, the real-life problem is less well-structured than the > abstraction. > > Here's another abstraction that better captures the (lack of) structure of > the problem. As before, I believe this runs O(n^2) and n is large. I'd like > to try to stick with XSLT 1.0 if possible. Any improvements are most > welcome. If this is as good as it gets, that would also be useful info. > > Here's what I'd like to be able to do: Create a recursive function to build > a node list of all the b's, then select from that with an index. I think > that would need 1.1 or processor-specific extensions, however. > > XML source: > > <?xml version="1.0"?> > <list> > <item>something else</item> > <item>a a1</item> > <item>a a2</item> > <item>something else</item> > <item>a a3</item> > <item>b b1</item> > <item>something else</item> > <item>b b2</item> > <item>a a4</item> > <item>b b3</item> > <item>a a5</item> > <item>b b4</item> > <item>a a6</item> > <item>b b5</item> > <item>b b6</item> > </list> > > A recursive solution: > > <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" > version="1.0"> > > <!-- match first a and make top level call to recursive template --> > <xsl:template match="item[1]"> > <xsl:call-template name="do_a"> > <xsl:with-param name="ix" select="0" /> > </xsl:call-template> > </xsl:template> > > <!-- recursive template counts a's --> > <xsl:template name="do_a"> > <xsl:param name="ix" /> > > <xsl:choose> > <xsl:when test="starts-with(., 'a')"> > <!-- Output the a --> > <xsl:text>
</xsl:text> > <xsl:value-of select="$ix + 1" /> > <xsl:text>: </xsl:text> > <xsl:value-of select="substring-after(.,' ')" /> > <xsl:text> </xsl:text> > > <!-- Output the corresponding b --> > <xsl:for-each select="//item[1]"> > <xsl:call-template name="do_b"> > <xsl:with-param name="ix" select="$ix + 1" /> > </xsl:call-template> > </xsl:for-each> > > <!-- process remaining a's --> > <xsl:for-each select="following::item[1]"> > <xsl:call-template name="do_a"> > <xsl:with-param name="ix" select="$ix + 1" /> > </xsl:call-template> > </xsl:for-each> > </xsl:when> > <xsl:otherwise> > <!-- Look for next a --> > <xsl:for-each select="following::item[1]"> > <xsl:call-template name="do_a"> > <xsl:with-param name="ix" select="$ix" /> > </xsl:call-template> > </xsl:for-each> > </xsl:otherwise> > </xsl:choose> > </xsl:template> > > <!-- recursive template outputs the ix-th b --> > <xsl:template name="do_b"> > <xsl:param name="ix" /> > > <xsl:choose> > <xsl:when test="starts-with(., 'b')"> > <xsl:choose> > <xsl:when test="$ix = 1"> > <xsl:value-of select="substring-after(.,' ')" /> > </xsl:when> > <xsl:otherwise> > <!-- Look for next b --> > <xsl:for-each select="following::item[1]"> > <xsl:call-template name="do_b"> > <xsl:with-param name="ix" select="$ix - 1" /> > </xsl:call-template> > </xsl:for-each> > </xsl:otherwise> > </xsl:choose> > </xsl:when> > <xsl:otherwise> > <!-- Look for next b --> > <xsl:for-each select="following::item[1]"> > <xsl:call-template name="do_b"> > <xsl:with-param name="ix" select="$ix" /> > </xsl:call-template> > </xsl:for-each> > </xsl:otherwise> > </xsl:choose> > </xsl:template> > <!-- suppress other output --> > <xsl:template match="text()" /> > > </xsl:stylesheet> > > Output: > > <?xml version="1.0" encoding="utf-8"?> > 1: a1 b1 > 2: a2 b2 > 3: a3 b3 > 4: a4 b4 > 5: a5 b5 > 6: a6 b6 > > Thanks, > Mat > > > 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] Re: Collating riffled lists, Dimitre Novatchev | Thread | RE: [xsl] Best way to use global pa, Kathy Burke |
Re: [xsl] how to match node set wit, S Woodside | Date | [xsl] Re: Collating riffled lists, Dimitre Novatchev |
Month |