Re: RE: [xsl] Collating riffled lists

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>&#xa;</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>&#xA;</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