Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>Rather than using an <strong>xsl:for-each</strong> and then a call to a named template, you could consider combining the two into one <strong>xsl:apply-templates</strong> call. Firstly, you would select the comments with a ResponseCommentID attribute of 0.</p> <pre><code>&lt;xsl:apply-templates select="in:inputs/in:result[@name='XML_Comment']/root/Comments[@ResponseCommentID='0']" /&gt; </code></pre> <p>Then, you would have a template to match the <strong>Comments</strong> attribute, where you would output the comment details. You could then recursively get the response comments like so:</p> <pre><code>&lt;xsl:apply-templates select="../Comments[@ResponseCommentID = current()/@CommentID]" /&gt; </code></pre> <p>This would just recursively call the same <strong>Comments</strong> template until there are no more reponses.</p> <p>Here is the full XSLT in this case (I am outputting the comments as list items in HTML just as an example)</p> <pre><code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" exclude-result-prefixes="in"&gt; &lt;xsl:output method="xml" indent="yes"/&gt; &lt;xsl:template match="/"&gt; &lt;ul&gt; &lt;xsl:apply-templates select="in:inputs/in:result[@name='XML_Comment']/root/Comments[@ResponseCommentID='0']" /&gt; &lt;/ul&gt; &lt;/xsl:template&gt; &lt;xsl:template match="Comments"&gt; &lt;li&gt; &lt;xsl:value-of select="@Comment" /&gt; &lt;xsl:if test="../Comments[@ResponseCommentID = current()/@CommentID]"&gt; &lt;ul&gt; &lt;xsl:apply-templates select="../Comments[@ResponseCommentID = current()/@CommentID]" /&gt; &lt;/ul&gt; &lt;/xsl:if&gt; &lt;/li&gt; &lt;/xsl:template&gt; &lt;/xsl:stylesheet&gt; </code></pre> <p>This gives the following output</p> <pre><code>&lt;ul&gt; &lt;li&gt;test comment!!!! &lt;ul&gt; &lt;li&gt;my response &lt;ul&gt; &lt;li&gt;I don't agree with Norman. Terrible response.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;I've got something to say!&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;test comment2!!!!&lt;/li&gt; &lt;li&gt;Not impressed... &lt;ul&gt; &lt;li&gt;I'm impressed.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;blah blah blah. &lt;ul&gt; &lt;li&gt;this is a response to blah blah blah.&lt;/li&gt; &lt;/ul&gt; &lt;/li&gt; &lt;li&gt;dfsfs&lt;/li&gt; &lt;/ul&gt; </code></pre> <p>However, it would be more efficient to use an <strong>xsl:key</strong> here to look up the responses to comments:</p> <pre><code>&lt;xsl:key name="Comments" match="Comments" use="@ResponseCommentID" /&gt; </code></pre> <p>Then to get the top-level comments you would do this:</p> <pre><code>&lt;xsl:apply-templates select="key('Comments', '0')" /&gt; </code></pre> <p>And to get the responses to a given comment in your matching template, you would do this</p> <pre><code>&lt;xsl:apply-templates select="key('Comments', @CommentID)" /&gt; </code></pre> <p>The following XSLT also gives the same results</p> <pre><code>&lt;xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:in="http://www.composite.net/ns/transformation/input/1.0" exclude-result-prefixes="in"&gt; &lt;xsl:output method="xml" indent="yes"/&gt; &lt;xsl:key name="Comments" match="Comments" use="@ResponseCommentID" /&gt; &lt;xsl:template match="/"&gt; &lt;ul&gt; &lt;xsl:apply-templates select="key('Comments', '0')" /&gt; &lt;/ul&gt; &lt;/xsl:template&gt; &lt;xsl:template match="Comments"&gt; &lt;li&gt; &lt;xsl:value-of select="@Comment" /&gt; &lt;xsl:if test="key('Comments', @CommentID)"&gt; &lt;ul&gt; &lt;xsl:apply-templates select="key('Comments', @CommentID)" /&gt; &lt;/ul&gt; &lt;/xsl:if&gt; &lt;/li&gt; &lt;/xsl:template&gt; &lt;/xsl:stylesheet&gt; </code></pre>
 

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