Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>The reason that context does not increase when you call the template "item" recursively is that xs:call-template always passes the current context item as context. So as you probably saw, the transform just enters infinite recursion.</p> <p>Assuming that you always need to produce exactly three attributes, you don't even need recursion. </p> <p>Try this:</p> <pre><code>&lt;xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"&gt; &lt;xsl:template match="table"&gt; &lt;groups&gt; &lt;xsl:apply-templates select="tbody/tr[th]"/&gt; &lt;/groups&gt; &lt;/xsl:template&gt; &lt;xsl:template match="tr[th]"&gt; &lt;xsl:variable name="id" select="generate-id(.)"/&gt; &lt;group name="{string(th)}"&gt; &lt;xsl:apply-templates select="following-sibling::tr[not(th)][generate-id(preceding-sibling::tr[th][1]) = $id]"/&gt; &lt;/group&gt; &lt;/xsl:template&gt; &lt;xsl:template match="tr"&gt; &lt;item attribute1="{td[1]}" attribute2="{td[2]}" attribute3="{td[3]}" /&gt; &lt;/xsl:template&gt; &lt;/xsl:stylesheet&gt; </code></pre> <p>This works by applying templates to each header row. Each of those template uses that complicated xpath to call "its" following rows, which are any following sibling rows that have that specific row as it's first preceding row with a header.</p> <p>Of course, if the number of attributes vary, then you will need to recurse there and increase pass a parameter indicating the position. </p> <p>There are a couple of established methods for XSLT grouping, one of which is recursive, like you were doing. Another method is called Muenchian grouping. A good write-up is <a href="http://www.jenitennison.com/xslt/grouping/index.html" rel="nofollow noreferrer">here</a>.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload