Perera1987
Perera1987

Reputation: 97

XSL display similar nodes same level

I have a xml data like this.

    <commentList>
     <item>
        <comment_id>2</comment_id>
        <discussion_id>3</discussion_id>
        <replyTo>0</replyTo>
        <Text>This is a test comment</Text>
     </item>
     <item>
        <comment_id>3</comment_id>
        <discussion_id>3</discussion_id>
        <replyTo>0</replyTo>
        <Text>Hello</Text>
     </item>
     <item>
        <comment_id>4</comment_id>
        <discussion_id>3</discussion_id>
        <replyTo>2</replyTo>
        <Text>Reply to This is a test comment</Text>
     </item>
    </commentList>

replyTo - parent comment id (0 = root)

replyTo goes maximum one level.

I just want to display comment and relevant replies first. then next comment and replies and so on. Is there a best way to archive this? Thanks in advance.

Expected output as per above question.

This is a test comment
- Reply to This is a test comment
Hello

Upvotes: 0

Views: 42

Answers (1)

michael.hor257k
michael.hor257k

Reputation: 117073

It's convenient to use a key to link items to their replies.

XSLT 1.0

<xsl:stylesheet version="1.0" 
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
<xsl:output method="text" encoding="UTF-8"/>
<xsl:strip-space elements="*"/>

<xsl:key name="replies" match="item" use="replyTo" />

<xsl:template match="/commentList">
    <!-- select starter items -->
    <xsl:apply-templates select="item[replyTo=0]"/> 
</xsl:template>

<xsl:template match="item">
    <xsl:if test="replyTo > 0">
        <xsl:text>- </xsl:text>
    </xsl:if>
    <xsl:value-of select="Text"/>
    <xsl:text>&#10;</xsl:text>
    <!-- append replies -->
    <xsl:apply-templates select="key('replies', comment_id)"/>  
</xsl:template>

</xsl:stylesheet>

This places no limit to the number of levels. For example, given the following test input:

XML

<commentList>
      <item>
        <comment_id>1</comment_id>
        <replyTo>0</replyTo>
        <Text>One</Text>
     </item>
     <item>
        <comment_id>2</comment_id>
        <replyTo>0</replyTo>
        <Text>Two</Text>
     </item>
     <item>
        <comment_id>3</comment_id>
        <replyTo>1</replyTo>
        <Text>Reply to One</Text>
     </item>
    <item>
        <comment_id>4</comment_id>
        <replyTo>2</replyTo>
        <Text>Reply to Two</Text>
     </item>
     <item>
        <comment_id>5</comment_id>
        <replyTo>1</replyTo>
        <Text>Reply to One</Text>
     </item>
     <item>
        <comment_id>6</comment_id>
        <replyTo>3</replyTo>
        <Text>Reply to Three</Text>
     </item>
     <item>
        <comment_id>7</comment_id>
        <replyTo>3</replyTo>
        <Text>Reply to Three</Text>
     </item>
     <item>
        <comment_id>8</comment_id>
        <replyTo>4</replyTo>
        <Text>Reply to Four</Text>
     </item>
</commentList>

the result will be:

One
- Reply to One
- Reply to Three
- Reply to Three
- Reply to One
Two
- Reply to Two
- Reply to Four

Upvotes: 1

Related Questions