Unravel the SharePoint Threaded Discussion

The SharePoint Threaded Discussion is a forum type of post.  Underneath, like all things SharePoint, it is a list.  By default that list is made up of two content types, Discussion and Message.  The content types have IDs of 0x012002 and 0x0107 respectively.  Following the content type inheritance chain this means that the Discussion content type inherits from folder and the Message content type from Item.  This gives us some clue about the structure of the list.

If you enter a top level item in a threaded discussion list it will be created as a folder.  In order to navigate each top level thread using the object model we use code similar to that shown below.

 using ( SPSite siteCollection = new SPSite( "http://moss.litwareinc.com/" ) ) {
    using ( SPWeb web = siteCollection.OpenWeb( "/SiteDirectory/mktg" ) ) {
        SPList list = web.Lists["Team Discussion"];

        foreach ( SPListItem folder in list.Folders ) {
            Console.WriteLine( "-- Folder --" );
            Console.WriteLine( folder.Title );
            Console.WriteLine( folder.UniqueId.ToString() );
            Console.WriteLine( folder.ID.ToString() );
            Console.WriteLine( folder.Xml );
            Console.WriteLine( "-- End Folder --" );
        }
    }
}

You can also iterate over the list items themselves using the typical foreach convention.  When you do this take a look at the Xml property for the List Item and you will see various items that we can use to find the context of our item within the threaded discussion.

 <?xml version="1.0" encoding="utf-8" ?>
<z:row xmlns:z='#RowsetSchema' 
       ows_ContentTypeId='0x010700135BC7419F95B04C8EA15325163C1444' 
       ows_Body='&lt;div class=ExternalClassAAF51B42E3834F8D90CA3A8DA7739064&gt;&lt;div&gt;second sample item&lt;br&gt;&lt;br&gt;&lt;hr&gt;&lt;b&gt;From: &lt;/b&gt;System Account&lt;br&gt;&lt;b&gt;Posted: &lt;/b&gt;Wednesday, June 04, 2008 5:14 PM&lt;br&gt;&lt;b&gt;Subject: &lt;/b&gt;sample item one&lt;br&gt;&lt;br&gt;&lt;div class=ExternalClassF19C451E2C284124AB09D103E8A70A18&gt;&lt;div&gt;first sample item&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;' 
       ows_TrimmedBody='&lt;div class=ExternalClass4D66DF23C3C649C4985CFE81A1E2E0E2&gt;&lt;div&gt;second sample item&lt;br&gt;&lt;/div&gt;&lt;/div&gt;' 
       ows_ParentFolderId='1' 
       ows_ID='2' 
       ows_ContentType='Message' 
       ows_Modified='2008-06-04 17:14:33' 
       ows_Created='2008-06-04 17:14:33' 
       ows_Author='1073741823;#System Account' 
       ows_Editor='1073741823;#System Account' 
       ows_owshiddenversion='1' 
       ows_WorkflowVersion='1'
       ows__UIVersion='512' 
       ows__UIVersionString='1.0' 
       ows_Attachments='0' 
       ows__ModerationStatus='0' 
       ows_SelectTitle='2' 
       ows_Order='200.000000000000' 
       ows_GUID='{8FAC9A20-6343-48A3-8BE3-CD7E17E45894}' 
       ows_FileRef='2;#SiteDirectory/mktg/Lists/TeamDiscussion/sample item one/2_.000' 
       ows_FileDirRef='2;#SiteDirectory/mktg/Lists/Team Discussion/sample item one' 
       ows_Last_x0020_Modified='2;#2008-06-04 17:14:33'
       ows_Created_x0020_Date='2;#2008-06-04 17:14:33' 
       ows_FSObjType='2;#0' 
       ows_PermMask='0x7fffffffffffffff' 
       ows_FileLeafRef='2;#2_.000' 
       ows_UniqueId='2;#{87C5CD04-7D68-4B26-B00C-DD76AE7B96D8}' 
       ows_ProgId='2;#' 
       ows_ScopeId='2;#{6ED2F3B8-3D0A-4B4F-B092-C9A6D1942AE2}' 
       ows__EditMenuTableStart='2_.000' 
       ows__EditMenuTableEnd='2'
       ows_LinkFilenameNoMenu='2_.000' 
       ows_LinkFilename='2_.000' 
       ows_ServerUrl='/SiteDirectory/mktg/Lists/Team Discussion/sample item one/2_.000' 
       ows_EncodedAbsUrl='http://moss.litwareinc.com/SiteDirectory/mktg/Lists/Team%20Discussion/sample%20item%20one/2_.000' 
       ows_BaseName='2_' 
       ows_MetaInfo='2;#' 
       ows__Level='1' 
       ows__IsCurrentVersion='1' 
       ows_ThreadIndex='0x01CA94B8313E972C16929A454ACFA141B2588F7291DB000004B927' 
       ows_ShortestThreadIndexIdLookup='1;#' 
       ows_DiscussionTitleLookup='1;#sample item one' 
       ows_DiscussionTitle='sample item one' 
       ows_ReplyNoGif='SiteDirectory/mktg/Lists/Team Discussion/sample item one' 
       ows_ThreadingControls='0x01CA94B8313E972C16929A454ACFA141B2588F7291DB000004B927' 
       ows_IndentLevel='0x01CA94B8313E972C16929A454ACFA141B2588F7291DB000004B927' 
       ows_Indentation='0x01CA94B8313E972C16929A454ACFA141B2588F7291DB000004B927' 
       ows_StatusBar='2008-06-05T00:14:33Z' 
       ows_BodyAndMore='&lt;div class=ExternalClassAAF51B42E3834F8D90CA3A8DA7739064&gt;&lt;div&gt;second sample item&lt;br&gt;&lt;br&gt;&lt;hr&gt;&lt;b&gt;From: &lt;/b&gt;System Account&lt;br&gt;&lt;b&gt;Posted: &lt;/b&gt;Wednesday, June 04, 2008 5:14 PM&lt;br&gt;&lt;b&gt;Subject: &lt;/b&gt;sample item one&lt;br&gt;&lt;br&gt;&lt;div class=ExternalClassF19C451E2C284124AB09D103E8A70A18&gt;&lt;div&gt;first sample item&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;' 
       ows_MessageBody='&lt;div class=ExternalClassAAF51B42E3834F8D90CA3A8DA7739064&gt;&lt;div&gt;second sample item&lt;br&gt;&lt;br&gt;&lt;hr&gt;&lt;b&gt;From: &lt;/b&gt;System Account&lt;br&gt;&lt;b&gt;Posted: &lt;/b&gt;Wednesday, June 04, 2008 5:14 PM&lt;br&gt;&lt;b&gt;Subject: &lt;/b&gt;sample item one&lt;br&gt;&lt;br&gt;&lt;div class=ExternalClassF19C451E2C284124AB09D103E8A70A18&gt;&lt;div&gt;first sample item&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;' 
       ows_BodyWasExpanded='{8FAC9A20-6343-48A3-8BE3-CD7E17E45894}' 
       ows_QuotedTextWasExpanded='{8FAC9A20-6343-48A3-8BE3-CD7E17E45894}' 
       ows_CorrectBodyToShow='&lt;div class=ExternalClass4D66DF23C3C649C4985CFE81A1E2E0E2&gt;&lt;div&gt;second sample item&lt;br&gt;&lt;/div&gt;&lt;/div&gt;' ows_FullBody='&lt;div class=ExternalClassAAF51B42E3834F8D90CA3A8DA7739064&gt;&lt;div&gt;second sample item&lt;br&gt;&lt;br&gt;&lt;hr&gt;&lt;b&gt;From: &lt;/b&gt;System Account&lt;br&gt;&lt;b&gt;Posted: &lt;/b&gt;Wednesday, June 04, 2008 5:14 PM&lt;br&gt;&lt;b&gt;Subject: &lt;/b&gt;sample item one&lt;br&gt;&lt;br&gt;&lt;div class=ExternalClassF19C451E2C284124AB09D103E8A70A18&gt;&lt;div&gt;first sample item&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;' 
       ows_LimitedBody='&lt;div class=ExternalClassAAF51B42E3834F8D90CA3A8DA7739064&gt;&lt;div&gt;second sample item&lt;br&gt;&lt;br&gt;&lt;hr&gt;&lt;b&gt;From: &lt;/b&gt;System Account&lt;br&gt;&lt;b&gt;Posted: &lt;/b&gt;Wednesday, June 04, 2008 5:14 PM&lt;br&gt;&lt;b&gt;Subject: &lt;/b&gt;sample item one&lt;br&gt;&lt;br&gt;&lt;div class=ExternalClassF19C451E2C284124AB09D103E8A70A18&gt;&lt;div&gt;first sample item&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;' 
       ows_MoreLink='2' 
       ows_LessLink='2' 
       ows_ToggleQuotedText='2' 
       ows_Threading='0x01CA94B8313E972C16929A454ACFA141B2588F7291DB000004B927' 
       ows_PersonImage='System Account' 
       ows_PersonViewMinimal='System Account' 
       ows_IsRootPost='0' 
       ows_ItemChildCount='2;#0' 
       ows_ServerRedirected='0'/>

One of the more important properties is the ows_ParentFolderId.  By leveraging this property we can establish the parent thread or discussion, in this case the folder, that is the host for the item. This will always be the top level folder item, not the item that was responded to originally. While this does allow you to figure out which items go with which folder, it does not provide order or hierarchy.

If you examine the default 'Threaded' view that comes with an instance of the Team Discussion you will notice that it contains one column, 'Threading (threaded)'.  This column is used for display and also used to sort the items.  There is a group of properties that provide a structure that enabling you to figure out he thread hierarchy.  Notice the ows_ThreadIndex, ows_Threading, ows_ThreadingControls, ows_IndentLevel, etc.  These properties all have the same value for an item, but as you navigate from item to item notice that a hierarchy of sorts is formed.  The base item has a thread value and then the children have this same thread value, but with some additional random text after the base item.  This begins to form a hierarchy. 

ows_ThreadingIndex='0x01CA94B8313E972C16929A454ACFA141B2588F7291DB’

|_ows_ThreadingIndex='0x01CA94B8313E972C16929A454ACFA141B2588F7291DB000004B927'

                |_ows_ThreadingIndex='0x01CA94B8313E972C16929A454ACFA141B2588F7291DB000004B9270000026E29'

When reviewing the Xml attributes another item looks promising, ows_Order.  It has a format of xxx.xxxxxx.  This leads one to believe that this would control the order of the items in the thread.  I was hoping to find a pattern that was parent.childorder or something to that affect, but that is not the case.  Upon further examination this is simply the item id.  It is probably reserved for some future use.