in

SharePoint Blogs

The Best Place for SharePoint-related Blogs

MOSS 2007 and Software Product Lines

Hi. My name is Alfred de Weerd. In this blog I will deal with MOSS 2007 and development professionalisation in general. I'm planning to write about subjects like a MOSS product line in general, reusable assets, software factories, processes and the like.

Generating Custom Site Columns and Custom Content Type features from the content database

I was looking for information on the generation of features, but I could not find any information yet. Splendid! Good start for some coding. What I wanted to do is:

  1. Create features by using the MOSS 2007 User Interface
  2. Generate features based on what I had created.

By the way, if you have never created a Content Type feature, it would help you understand the text below to glance over how its done, for example by reading this post by Ton Stegeman: http://www.sharepointblogs.com/tonstegeman/archive/2006/07/19/creating-contenttypes-in-sharepoint-2007-by-using-a-feature.aspx

Using custom site columns and custom content types as a start, it appeared to be possible to decrease development time significantly. I've not gone through a formal testing process, and I needed some hacks. So I expect that some more issues will come up. But I do not think I'll ever code columns or content type features from scratch again. It's also a handy tool for to study more complex content types like those inheriting from other content types.

Looking in the content database, I noticed that with a "select definition from ContentTypes where definition is not null" I could retrieve both columns I had create in the MOSS user interface, and content types I had created there. I was a little surprised that there was actually XML in the table, resembling closely the XML I used to type in to create my custom site columns and custom content types.It was easy enough to grab the data from the content database and generate feature.xml and elements.xml files from it (never try to write to the content database!). The files thus generated however refused to be activated. I had to tidy up the XML to get them working.

 

Well to describe what I did in a more organized manner:

1 Use Sql Server to retrieve the URL for the MOSS content database.

I used this connectionstring: "Data Source=VPCWIN2003R2;Initial Catalog=WSS_Content_8080;Integrated Security=SSPI";

 

2 Read the relevant data from the database, and fill two lists

Since both columns and content types are in the same table, I filtered them based on thier element name.

                SqlCommand cmd = new SqlCommand("select definition from ContentTypes where definition is not null", connection);
                SqlDataReader rdr = cmd.ExecuteReader();

                while (rdr.Read())
                {
                    string xmlString = (string)rdr[0];

                    string nodeType = XmlHelper.GetElementName(xmlString);
                    if (nodeType.Equals("Field"))
                    {
                        lstColumns.Items.Add(xmlString);
                    }
                    else
                    {
                        this.lstContentTypes.Items.Add(xmlString);
                    }
                }

3 Create a feature.xml file for the columns 

I used values I keyed in from a form to generate a valid feature.xml (more on the little tool I created below)

 

4 Create an elements.xml file for the columns

From all columns I created in the Moss User Interface, I had to filter those relevant for the selected content type. For this I could just iterate over the the <FieldRef> elements in the content type and verify select the column if there was a match.

         //returns the columns that are relevant for the content type
        private static string GetRelevantFields(string contentType, string[] columns)
        {
            string retVal = "";
            XPathNodeIterator it = GetRootNodeIteratorFromString(contentType);
            XPathNodeIterator it2 = it.Current.SelectDescendants("FieldRef","",false);
            while (it2.MoveNext())
            {
                string id=it2.Current.GetAttribute("ID", "");
                for (int i = 0; i < columns.Length; i++)
                {
                    if (columnsIdea.Contains(id))
                    {
                        string fieldString = columnsIdea.Insert(6, " xmlns = \"http://schemas.microsoft.com/sharepoint/\"");
                        retVal += fieldString;
                    }
                }
            }
            return retVal;
        }

Unfortunately, when I added the XML thus obtained to my elements.xml file, I received an error when installing the feature. It appeared that, when you do not add a xml namespace, an empty one is added to the xml when you add the node. That is why I had to insert the right namespace to the columns, before adding them to the return value.

 5 Create the content type feature.xml file

This was equivalent to the columns feature.xml file

 

6 Create the content type elements.xml file

This would have been just the creation of a xml file from the data in the content database, but then there proved to be some issues:

a) An empty namespace was added, as decribed in (4). I added a namespace as a property (I have not been doing XML in code for some years, there'll be a more elegant way, I bet)

b) For content types that derived from the Page content type, or a sub type of Page, a number of attributes were introduced with empty values (Customization, PIAttribute, PITarget, to name some). I did not understand these properties, so I removed them by using a regular expression

c) There seemed to be a problem with the xml of the <XmlDocument> nodes, so I removed them by using a regular expression

 

7 Install features

I copied the feature directories to Features folder and installed them by using stsadm as described on http://msdn2.microsoft.com/en-us/library/ms442691.aspx. I have not automated this part yet.

I tried a dozen or so content types, which could all be created and activated. I did not try using each and every column or content type from the User Interface, so just consider this a prove of concept. 

 

Since increasing productivity of MOSS solutions is one of my main interests, any feedback would be welcome.

Alfred

 

 

 

 

Comments

No Comments

Leave a Comment

(required )  
(optional )
(required )  
Add

Need SharePoint Training? Attend a SharePoint Bootcamp!

Posts (c) their respective authors. Everything else (c) 2007 SharePoint Experts