After a long time (was in a busy schedule of establishing family after my marriage ), I thought I will post this article for setting the XML mapping of content control in a Word document template for SharePoint Document Library. To be frank, in most of the cases, we are / will be using QuickParts Add-in to add the content controls which are already mapped with SharePoint ContentType
fields. But in this article, I will be explaining how to set up a document template for a document library without touching the QuickParts Add- in. Sometimes this will be helpful to the developers who are programmatic-ally/dynamically creating document templates or content controls to document templates. To make this article in one line, it's about setting XPath, Prefix Mapping for content controls using SetMapping
function of XMLMapping
property of content control, like contentControl.XMLMapping.SetMapping(Xpath,PrefixMapping)
.
These are things that you should have handy with you before starting this exercise.
- A Document Content Type with some site columns referred inside – Say, we will name it as “
ExpenseContentType
” that have 2 site columns (SC_ExpenseName
, SC_ExpenseCount
) - A Document Library created which will have content type that is mentioned on the above step (Step 1) – say,
ExpenseDocumentLibrary
. - Word Content Control Tool Kit – Download this toolkit. This is just for the analysis purpose of the template or to understand what is happening behind the scenes.
- Visual Studio – Just in case you need to code the logic for XML mapping (Code is embedded at the bottom of the post)
So, let's start from the document library (ExpenseDocumentLibrary
).
Step 1
Go the document library setting –> ContentType
(ExpenseContentType
) –> Advanced Settings
Here on the Advanced setting page of the Document library Content Type, click on the Edit Template link (see image below) . This will open a blank document template in Microsoft Word. Save this locally on your machine with any user friendly name, say ExpenseTemplate.docx.
Step 2
For analysis, open the locally saved blank template using the Word Content Control toolkit. We can see the content type fields on the custom XML parts of the document. This means the ContentType
related data like Fields, etc. are there in this document in XML(XSD) format. Since it's a blank document, there is no matter in the Content Controls section.
Step 3
Let us add some content controls to this document template. For that, open the Word document using Microsoft Word and from Developer tab, add 1 or 2 plain text content controls to the document as if it resembles a template. (See image below.) Name the content controls exactly as the Site Columns name in ContentType
. This means, name Expense Name content control as “SC_ExpenseName
”.
Save this document after adding the controls.
Step 4
Re-open the document in the Word Content Control Tool Kit. Now we can observe that on the content controls section, it is showing the control entries without having its XPath
set with ContentType
Fields inside the file. (See the image below). Basically, XPath
and Prefix mapping of the Custom XML parts shown on the right pane for the each field need to be mapped with content control.
Step 5
In this step, we will set the mapping between the content controls and ContentType
fields. Actually, we can set mapping using Word Content Control Toolkit itself, but it will become a manual process. Better we will do it “programmatic-ally” :).
For doing this, I am creating a Word Add-In project in Visual Studio. So open a Visual Studio Instance –> New Project –> Word Add – In (see image below).
Give any user friendly name to the project. After that, Add a “Ribbon
” into this Add- in project (Right Click on Project –> Add –> New Item –> Ribbon (see image below)).
Again, give a user friendly name to the ribbon. On the visual designer of the ribbon, add a button (label it as “Set Mapping”) and on the click event of button, we will write some code as shown below:
private void button1_Click(object sender, RibbonControlEventArgs e)
{
Document document = Globals.ThisAddIn.Application.ActiveDocument;
string nsURI = string.Empty;
ContentControls contentControls = document.ContentControls;
foreach (ContentControl cntntCtrl in contentControls)
{
var ctrlTitle = cntntCtrl.Title;
string xpath = "/ns0:properties[1]/documentManagement[1]/ns1:" +
ctrlTitle + "[1]";
nsURI = GetXSDNameSpaceURI(document, cntntCtrl);
bool isMapped = cntntCtrl.XMLMapping.SetMapping
("/ns0:properties[1]/documentManagement[1]/ns1:" +
ctrlTitle + "[1]",
"xmlns:ns0='http://schemas.microsoft.com/office/2006/metadata/properties'
xmlns:ns1='" + nsURI + "'", null);
if (isMapped == true)
{ MessageBox.Show("Mapping successfully done...!"); }
else
{ MessageBox.Show("Error in XML Mapping"); }
}
}
private string GetXSDNameSpaceURI(Document document, ContentControl control)
{
string nsURI = string.Empty;
CustomXMLParts xmlParts = document.CustomXMLParts.SelectByNamespace
("http://schemas.microsoft.com/office/2006/metadata/properties");
foreach (CustomXMLPart xmlPart in xmlParts)
{
XmlDocument XDoc = new XmlDocument();
XDoc.LoadXml(xmlPart.XML);
XmlNodeList result = XDoc.GetElementsByTagName(control.Title);
nsURI = result[0].NamespaceURI;
break;
}
return nsURI;
}
Build the project and press F5. This will open a default word document. Close that document and open our document library template where we have add content control. Find the ribbon that we have created on the opened document and press the button “Set mapping”. This will set the XPath
mapping for each content control and throw a message box saying “Mapping successfully done…!
”. (See image below.)
Now I will explain what actually the above code does. Basically, it iterates through the content controls collection and by using each content control’s title, it's creating an “XPath
” string
and “Prefix mapping” using the content type namespace URI. The key player is SetMapping
function of the content control’s XMLMapping
property. This function is used to set the mapping for the content control. The SetMapping
function can be called on the event after the control adding to make it more clean. But since this is a POC, we will use iteration logic. The entire article is based on the SetMapping
function to make link between content control and content type.
Now just open the document in the Word Content Control toolkit and see the XPath set against each content control. (See image below.)
This is the time to upload this document template back into SharePoint. Go to the Advanced settings of the Document library content type and upload the template using “upload a new document template”. After the uploading is over, try adding document files which have data inserted. You can see content control data getting binded with content type columns within the document library.
I hope you enjoyed/understood this article. Thanks for reading. Comments are invited.