It’s been a while since I last blogged, mainly because there has been many great articles written by all the Office 2007 System gurus out there. However, for the past couple of weeks I have been battling to find information on using Word 2007 Content Controls and custom XML. I am sure that many people will run into the same issues that I have had, and hence I thought it would be a good idea to document my learnings. I am certainly not the expert in this area, but you might find my stuff helpful.

In this blog I am going to focus on how to use a custom defined XML schema with Word 2007 Content Controls. Specifically I am going to look at how to map your custom XML to Word 2007 Content Controls without writing any code. I have seen several examples that use code, however I wanted to initially stay away from adding code to my Word 2007 template. In future blogs I will add to this scenario by looking at the coding options you have that can help manipulate the content of the document.

Note: I am using Word 2007 Beta 2.

Often businesses want a locked down template that prevents the user from changing the look, feel and layout of the document. Even though we could to some degree do this in previous versions of Word it was difficult and often the user could change the XML schema of the document which then made using the content as XML extremely difficult and error-prone for us programmers. This is where Content Controls and the XML datastore in Word 2007 come the rescue.

A Content Control is essentially a control that is added to a Word template or document that facilitates a user inputting content into a potentially locked down document / template. There are several that come with Word 2007 e.g. text control, rich text control, picture control, drop-down list control and my favorite the calendar control.

The datatsore is essentially an XML file that is stored inside the Word document. Remember that in Word 2007 the new file format is actually a series of files in single compressed (zipped) file. You can add one or more custom XML files into the Word document, these custom XML files allow you to inject or extract data from your document easily.

The following steps are going to show you how to:

  1. Add Content Controls into the Word 2007 document
  2. Add a custom XML file into the Word 2007 document (zipped file)
  3. Map the content controls to elements in the XML document (using XPATH and no code)
  4. Demonstrate that changing content in the Content Controls will update the custom XML file and visa-versa.

Step 1: Create the Word 2007 Document and Add Content Controls

Create a new Word 2007 document and insert the appropriate Content Controls. Content Controls are added to the document by using the developer tab. If you don’t see the developer tab it should be enabled through Word Options. It is easier to work in Design Mode while working with Content Controls, so select the “Design Mode” button in the developer tab. The diagram below shows the developer tab with the content controls available.

ribbon

It is a good idea to view the properties of your Content Controls so that you can give each control a friendly name and set is properties appropriately. The diagram below shows a very small example of a document with several content controls

word

The following controls were added:

  • ConsultantName: Text
  • Region: Drop-down list
  • DateAssigned: Calendar
  • Title: Text
  • Duration: Text
  • Summary: Rich text

Save the document and close Word. You are now going to add your custom XML file into the document.

Step 2: Add custom XML file into Word document

You should prepare your custom xml file and other supporting files in a temporary folder before adding them to the document. Specifically create the following folder structure and files.

customXml – folder, this is the root folder with the following directly inside

    item1.xml – this contains your custom XML

itemProps1.xml – this contains properties for you custom XML, specifically this is going to hold a unique ID that can be used to reference the custom XML from code or from the document itself.

_rels – folder, this folder contains relationship files. Specifically in this example we will have one file inside it i.e.

    item1.xml.rels – this file specifies that itemProps1.xml should be used

item1.xml sample:

<projectDoc xmlns="http://www.contoso.com/2006/schemas/workdoc">

<project>

        <consultantName />

        <region />

        <dateAssigned />

        <title />

        <duration />

        <summary />

    </project>

</projectDoc>

The schema of this XML is entirely up to you. Note that I have added a namespace to the document, although it’s not strictly required it is of course best practice.

itemProps1.xml sample:

<?xml version="1.0" encoding="UTF-8" standalone="no"?>

<ds:datastoreItem ds:itemID="{C66AC4F1-97D3-4D10-8D07-51E6CC79AD91}" xmlns:ds="http://schemas.openxmlformats.org/officedocument/2006/2/customXml">

<ds:schemaRefs>

<ds:schemaRef ds:uri="http://www.contoso.com/2006/schemas/workdoc"/>

</ds:schemaRefs>

</ds:datastoreItem>

The itemID should be a unique ID that you should choose, it will be used later to reference the datastore. I used VS .Net 2005 to generate a GUID. Also ensure your schema reference is that which is found in your custom XML file.

item1.xml.rels sample:

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>

<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">

<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXmlProps" Target="itemProps1.xml"/>

</Relationships>

Once this has all been prepared, change the file extension of your Word 2007 document from “.docx” to “.zip”. Open the zip file and copy the customXml folder (with all its contents) into the root of the zip file.

You now need to add a reference to your custom XML file to the Word 2007 document. In other words, just adding the customXML folder doesn’t finish the job, you need to tell Word that this custom XML file exists. To do this you need to copy the “word\_rels\document.xml.rels” file out of the zip file, modify it and add it back again.

document.xml.rels sample:

Insert the following relationship node into the file. You will need to change the id attribute to a value that isn’t already in use. For example, mine was changed to 8, as there was a 7 already.

<Relationship Id="rId8" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/customXml" Target="../customXml/item1.xml"/>

Once you have added this reference, add the file back into the zip file where it was copied from.

Step 3: Map Content Control to XML element in custom XML file

The final step that needs to be done is to map each Content Control to an element in the custom XML file that was inserted. To do this you need to copy the “word\document.xml” file from the zip file, modify it and add it back again. The document.xml file is the actual document content.

In this file you need to locate the content control that you wish to map. It will be imbedded in a <w:placeholder> element and shortly before this you will find an alias element which holds the friendly name for the Content Control.

For example, my Consultant Name controls has the following XML.

<w:alias w:val="ConsultantName"/>

<w:id w:val="4261751"/>

<w:lock w:val="sdtLocked"/>

<w:placeholder>

<w:docPart w:val="DefaultPlaceholder_22610167"/>

</w:placeholder>

<w:showingPlcHdr/>

Immediately after the closing <w:showingPlcHdr/> element add a mapping element which maps the control to a node in the custom XML file. E.g.

<w:dataBinding w:prefixMappings="xmlns:ns0='http://www.constoso.com/2006/schemas/workdoc’" w:xpath="/ns0:projectDoc[1]/ns0:project[1]/ns0:consultantName[1]" w:storeItemID="{C66AC4F1-97D3-4D10-8D07-51E6CC79AD91 }"/>

Note how there is a reference to the namespace being used in the custom xml file and a reference to the GUID that identifies the custom xml file. The Xpath, must be a valid expression that can reference an element or attribute value.

Do this for each control. Save the document.xml file and add it back to the zip file. That’s it, you can rename your zip file back to “.docx”.

Step 4: Test you work

You can now open your Word 2007 document and fill in the content controls. When you save your document the values from those controls will be added into your custom XML file. Test it.

Similarly, you can manually inject values into the custom XML file by renaming the document back to zip and inserting values into your custom XML file. When you open the document back in Word 2007 you will see those values in the Content Controls.

What Next?

Well you can see that the framework is in place to either inject or extract content based on business scenarios. For example; you can now add content to Word documents server side by injecting XML using code. Perhaps producing thousands of documents based on content from a customer database. In my following posts I will show how you can injecting or extracting XML from your documents via code, either server side or client side. We will also look at programmatically inserting datastore(s) and creating mappings. Lastly I hope to look at the integration of InfoPath into your Word 2007 document as a document properties panel and how this can impact your XML in the document.

You can download the sample Word 2007 document that was used in this post from here.

And just for interest sakes, I used Word 2007 to blog this post…cool!