Creating Site Columns Programmatically via XML

by Marcel Medina20. July 2010 15:45

Hi folks,

From now on I will also post some quick notes of SharePoint development. I believe they are going to be very useful in our daily activities.

In this post I demonstrate how to create Site Columns programatically via XML.

Consider the following Site Columns XML:

Code Snippet
  1. <Elements xmlns="http://schemas.microsoft.com/sharepoint/">
  2.   <Field Type="Choice" Description="List of countries" Required="TRUE" Format="Dropdown" FillInChoice="FALSE" Group="World Cup 2010 Columns" ID="{05A571AD-F9D1-4aab-A703-1AF3AE393FBF}" StaticName="Country" Name="Country" DisplayName="Country" Version="1">
  3.     <CHOICES>
  4.       <CHOICE>Algeria</CHOICE>
  5.       <CHOICE>Argentina</CHOICE>
  6.       <CHOICE>Australia</CHOICE>
  7.       <CHOICE>Brazil</CHOICE>
  8.       <CHOICE>Cameroon</CHOICE>
  9.       <CHOICE>Chile</CHOICE>
  10.       <CHOICE>Côte d'Ivoire</CHOICE>
  11.       <CHOICE>Denmark</CHOICE>
  12.       <CHOICE>England</CHOICE>
  13.       <CHOICE>France</CHOICE>
  14.       <CHOICE>Germany</CHOICE>
  15.       <CHOICE>Ghana</CHOICE>
  16.       <CHOICE>Greece</CHOICE>
  17.       <CHOICE>Honduras</CHOICE>
  18.       <CHOICE>Italy</CHOICE>
  19.       <CHOICE>Japan</CHOICE>
  20.       <CHOICE>Korea DPR</CHOICE>
  21.       <CHOICE>Korea Republic</CHOICE>
  22.       <CHOICE>Mexico</CHOICE>
  23.       <CHOICE>Netherlands</CHOICE>
  24.       <CHOICE>New Zealand</CHOICE>
  25.       <CHOICE>Nigeria</CHOICE>
  26.       <CHOICE>Paraguay</CHOICE>
  27.       <CHOICE>Portugal</CHOICE>
  28.       <CHOICE>Serbia</CHOICE>
  29.       <CHOICE>Slovakia</CHOICE>
  30.       <CHOICE>Slovenia</CHOICE>
  31.       <CHOICE>South Africa</CHOICE>
  32.       <CHOICE>Spain</CHOICE>
  33.       <CHOICE>Switzerland</CHOICE>
  34.       <CHOICE>Uruguay</CHOICE>
  35.       <CHOICE>USA</CHOICE>
  36.     </CHOICES>
  37.   </Field>
  38.   <Field Type="Choice" Description="List of host cities" Required="TRUE" Format="Dropdown" FillInChoice="FALSE" Group="World Cup 2010 Columns" ID="{AF008077-3A7E-41d9-AACA-2B0997BB5E25}" StaticName="HostCity" Name="HostCity" DisplayName="City" Version="1">
  39.     <Default>Johannesburg</Default>
  40.     <CHOICES>
  41.       <CHOICE>Cape Town</CHOICE>
  42.       <CHOICE>Durban</CHOICE>
  43.       <CHOICE>Johannesburg</CHOICE>
  44.       <CHOICE>Mangaung/Bloemfontein</CHOICE>
  45.       <CHOICE>Nelson Mandela Bay/Port Elizabeth</CHOICE>
  46.       <CHOICE>Nelspruit</CHOICE>
  47.       <CHOICE>Polokwane</CHOICE>
  48.       <CHOICE>Rustenburg</CHOICE>
  49.       <CHOICE>Tshwane/Pretoria</CHOICE>
  50.     </CHOICES>
  51.   </Field>
  52.   <Field Type="Choice" Description="List of players" Required="TRUE" Format="Dropdown" FillInChoice="FALSE" Group="World Cup 2010 Columns" ID="{EA4B814A-A18B-403a-A33A-8EA5436CB540}" StaticName="Position" Name="Position" DisplayName="Position" Version="1">
  53.     <CHOICES>
  54.       <CHOICE>Defensive Midfielder</CHOICE>
  55.       <CHOICE>Forward</CHOICE>
  56.       <CHOICE>Goalkeeper</CHOICE>
  57.       <CHOICE>Left Back</CHOICE>
  58.       <CHOICE>Left Midfielder</CHOICE>
  59.       <CHOICE>Right Back</CHOICE>
  60.       <CHOICE>Right Midfielder</CHOICE>
  61.       <CHOICE>Stopper</CHOICE>
  62.       <CHOICE>Striker</CHOICE>
  63.       <CHOICE>Sweeper</CHOICE>
  64.     </CHOICES>
  65.   </Field>
  66.   <Field Type="Text" Description="The name of the player" Required="TRUE" MaxLength="255" Group="World Cup 2010 Columns" ID="{04555083-EC04-4c20-A609-42A283428374}" StaticName="PlayerName" Name="PlayerName" DisplayName="Player Name"></Field>
  67.   <Field Type="Number" Description="The age of the player" Required="FALSE" Decimals="0" Group="World Cup 2010 Columns" ID="{2F2ABEB9-ED3D-41d9-BBDE-03D1150396A1}" StaticName="PlayerAge" Name="PlayerAge" DisplayName="Player Age"></Field>
  68.   <Field Type="DateTime" Description="The date of arrival" Required="FALSE" Format="DateOnly" Group="World Cup 2010 Columns" ID="{9910FA0D-C7E8-464a-9607-CABA1502B7DC}" StaticName="Arrival" Name="Arrival" DisplayName="Arrival" />
  69. </Elements>

 

In order to add the Site Columns above, the code snippet below must be used:

Code Snippet
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using System.Xml;
  6. using System.IO;
  7. using Microsoft.SharePoint;
  8.  
  9. namespace SiteColumns
  10. {
  11.     public class Program
  12.     {
  13.         public static void Main(string[] args)
  14.         {
  15.             using (SPSite site = new SPSite("http://localhost/"))
  16.             {
  17.                 XmlDocument xmlDoc = new XmlDocument();
  18.  
  19.                 xmlDoc.Load(Path.GetFullPath("SiteColumns.xml"));
  20.  
  21.                 foreach (XmlElement fieldNode in xmlDoc.DocumentElement.ChildNodes)
  22.                 {
  23.                     site.RootWeb.Fields.AddFieldAsXml(fieldNode.OuterXml);
  24.                 }
  25.             }
  26.         }
  27.     }
  28. }

 

In the end the Site Columns will be created according the Figure below:


Figure 1 – Creating Site Columns

Download the solution here.

Cheers

Marcel Medina

Click here to read the same content in Portuguese.

Tags: ,

Quick Notes

Comments (11) -

12/16/2010 1:42:30 AM #

Vincent

Hi Marcel,

I am trying to write some code to update "unghosted" site columns from a Field defintion file (in a Feature), I have been trying to duplicate your approach for content types ("Load(xrdr...") but it does quite work for Fields, does it?, I wonder this technique above, if a site column already exists and in use, an exception is thrown prompting for removing "all instances", is there an easier way to update (potentially unghosted) fields from a given Xml defintion?

Thx, Vincent

Vincent  | Reply

12/17/2010 8:50:02 PM #

Marcel Medina

Why don't you try to redeploy an updated feature? I think that approach using Reflection is not feasible.

Marcel Medina  | Reply

1/14/2011 7:29:01 PM #

Pat

Marcel, I'm scripting the creation of fields and content types to avoid using a feature in my hub.  

I'm running into an issue in that every content type I publish fails if it includes a site column created using this approach.  The columns and content types all get created fine and are usable until I try and publish.  Any ideas?  The error is:

The element 'FieldTemplate' in namespace 'urn:deployment-manifest-schema' has invalid child element 'Field' in namespace 'http://schemas.microsoft.com/sharepoint/'. List of possible elements expected: 'Field' in namespace 'urn:deployment-manifest-schema'.

Not that I think it matters, but I'm using PowerShell to do this, not a console app.

Thanks in advance

Pat  | Reply

1/17/2011 8:19:31 AM #

Marcel Medina

Use SharePoint Manager to compare the current XML field with one that is valid. Then you can find where the problem is.

Marcel Medina  | Reply

9/16/2011 12:29:22 PM #

Bharat Pandey

Hello Brother,

You have created a file named SiteColumns.xml,Why I write this code to deploy the content types to the site. Could It not be possible to do the same using the feature.
I will deploy only this feature to a site level or web level and whenever i activate this feature the fields will be deployed on the site. same i can do with contenttype.xml?
for further accuracy, i can create a feature dependency for contenttype.xml as sitecolumn.xml should be activated before activating the contenttype.xml??

will it not be a feasible solution. rather than writing this much of code?

what are your suggestion? please provide feedback on my blog/site...

Thanks and Regards,
bharat

Bharat Pandey  | Reply

9/19/2011 1:19:13 AM #

Marcel Medina

Hi,

You can do it with features, the purpose of this post is different. It creates site columns without a feature dependency. In this approach I am using a script, not a feature.

There is no such contenttype.xml in this post, but you can create it and define a feature activation dependency, or even better, deploy the site columns and content types all together.

Cheers,

Marcel Medina  | Reply

11/9/2011 9:03:13 PM #

Timo Pitk&#228;ranta

This is probably something you might want to do when localizing CAML in sandboxed solutions

Timo Pitkäranta  | Reply

1/11/2012 5:56:15 AM #

Jatin

Thanks for the solution above, however there is a slight problem i'm facing. Using this i am able to add new site columns and they appear in the site settings > site columns page.

The problem is with the site columns of type 'Choice'. If i click on any column of type choice to open up its edit page, it does not show me the usual edit page for a Choice column. It takes me to a normal column edit page as if it was a 'Single line of text' field and not a choice field. I am not able to see/edit the choices in the edit page.

any hints here?

Thanks

Jatin  | Reply

2/27/2012 12:32:13 AM #

Marcel Medina

Hi,
Try to edit the columns at the root level of the Site Collection, then you will be able to see the choice values.

Cheers,

Marcel Medina  | Reply

1/13/2012 8:47:39 PM #

cbankx

I appreciate this article.I'm half way there

I have a question...

I created this and tossed it in a feature...

Now when I activate and deactive the feature it creates the columns if the list doesn't exist or deletes it if I deactive the feature.

The problem I have is...If we have admins that go in and create fields from the front end how would I go about looking at the list columns programatically on my feature(activation into another farm(Test/Stage/DEV/PROD) to see if something new has been added and if it's new add it to my default template so that every time the feature was Deactivated/Activated it would not lose the columns that weren't in my default XML template? I consider the default template much like the one you have above- a starting place...if you will. Since that XML document is static, how would I go about updating it with new values so that I don't erase everything that's new that is generated from the fron end.

Thanks in advance

cbankx  | Reply

2/27/2012 12:29:27 AM #

Marcel Medina

Hi,

I understand what you want to do by updating the XML, but this is not a best practice.
A more robust solution is if you use the Content Type Hub for that, so Administrators can create/delete columns and publish them to Site Collection subscribers. The Hub automatically syncs the Content Types and Site Columns.
You can use the feature you created as a start point. Make sure you just implement the Activation method. Let the Deactivate method empty and hide the feature to avoid "accidents".

Have a look at this:
www.sharepoint4developers.net/.../...type-hub.aspx

Cheers,

Marcel Medina  | Reply

Add comment

  Country flag

biuquote
  • Comment
  • Preview
Loading

Profile



Marcel Medina is a specialist in .NET/SharePoint development.

Currently working as Microsoft Consultant and Trainer in these technologies.

He has 13 years of experience in the IT area and the following certifications: MCP, MCDBA, MCAD, MCSD, MCTS (including WSS 3.0, MOSS 2007 & SharePoint 2010, Application Development), MCITP (SharePoint Administrator 2010), MCPD (Enterprise Application Developer 2.0/3.5 & SharePoint Developer 2010) and MCT.

Support this site

If you want to keep this site running, please donate:

 

Thanks!

 

 

 

 

Month List


Site Meter