[XSL-LIST Mailing List Archive Home]
[By Thread]
[By Date]
RE: [xsl] Collating riffled lists
Subject: RE: [xsl] Collating riffled lists From: "Mat Myszewski" <mmyszew@xxxxxxxxxxx> Date: Mon, 29 Sep 2003 21:10:33 -0400 |
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
Current Thread |
---|
|
<- Previous | Index | Next -> |
---|---|---|
RE: [xsl] Collating riffled lists, Michael Kay | Thread | [xsl] Re: Collating riffled lists, Dimitre Novatchev |
RE: [xsl] How should I structure a , Michael Kay | Date | Re: [xsl] how to match node set wit, G. Ken Holman |
Month |