SharePoint Cross Site Word Document Properties

Recently I had a project where I was using SharePoint columns as document property fields in MS Word.  This is pretty straight forward when you have one library and some files but when you have a central repository of master files that are then pushed out to different sites across your farm it makes it a little more interesting.  We built our content types and columns in Visual Studio which were deployed on all sites and thus had the same contenttypeid’s and column guids.  One thing I noticed was that in the master library the document field would work correctly but once the file was copied to another site the document field would no longer work.  I was unable to find anything on the web about this scenario which is why I’m posting my findings here.

First thing I did was to open the copied file in one of the non-master sites and fix the field.  I just deleted the old one and re-added it and everything was fine.  Next I renamed both the fixed document and the master document to have a .zip extension.  This enables me to extract the contents of the word file so I could examine the differences.  What I found was that in the word\document.xml file where the document fields were inserted they had different GUIDs for the ns3 namespace attribute (see on line 21).  Also check out the xpath statement on line 23 and then notice how the namespace (ns3) for our document field (ProjectName) is the namespace where we have different GUIDs between the two documents.

<w:sdt>
	<w:sdtPr>
		<w:rPr>
			<w:b/>
			<w:smallCaps/>
			<w:snapToGrid w:val="0"/>
			<w:sz w:val="18"/>
		</w:rPr>
		<w:alias w:val="Project Name"/>
		<w:tag w:val="ProjectName"/>
		<w:id w:val="-1780325992"/>
		<w:lock w:val="sdtContentLocked"/>
		<w:placeholder>
			<w:docPart w:val="1BC5893A50C54E06B3DBC32132B17E14"/>
		</w:placeholder>
		<w:showingPlcHdr/>
		<w:dataBinding 
			w:prefixMappings="xmlns:ns0='http://schemas.microsoft.com/office/2006/metadata/properties' 
			xmlns:ns1='http://www.w3.org/2001/XMLSchema-instance' 
			xmlns:ns2='http://schemas.microsoft.com/office/infopath/2007/PartnerControls' 
			xmlns:ns3='b5fc2735-42dd-40f0-a521-255c535f6692' 
			xmlns:ns4='cb6c538f-4b29-4910-832a-74df7c62e784' " 
			w:xpath="/ns0:properties[1]/documentManagement[1]/ns3:ProjectName[1]" 
			w:storeItemID="{59580BC9-FAD5-4EB7-BF24-59B00B2B217C}"/>
		<w:text/>
	</w:sdtPr>
	<w:sdtEndPr/>
	<w:sdtContent>
		<w:r w:rsidR="00556E42" w:rsidRPr="00920EC6">
			<w:rPr>
				<w:rStyle w:val="PlaceholderText"/>
			</w:rPr>
			<w:t>[Project Name]</w:t>
		</w:r>
	</w:sdtContent>
</w:sdt>

So following a hunch I looked up the SPWeb.ID and sure enough, it was the same GUID as ns3.  So, when copying documents from one site to another, the document field xml data from SharePoint must be tied to the GUID of the site it came from.  I was able to verify this by looking at the customXml\item1.xml file (it’s always makes things a lot easier to be able to view your xml data when working with xpath queries) which showed all of my document fields coming from SharePoint and they all had a namespace of the SPWeb.ID GUID.

Since the namespace will be changing every time I copy the file I decided to update the xpath query to ignore the namespace.  Changing it from:

w:xpath="/ns0:properties[1]/documentManagement[1]/ns3:ProjectName[1]"

to:

w:xpath="/ns0:properties[1]/documentManagement[1]/*[local-name() = 'ProjectName'][1]"

This xpath trick will query only based on the name of the element and exclude any namespaces.  Sure enough, once I updated the file in my master site and did another copy down to a non-master site, the field updated correctly in word and everything was happy.  You can update the document.xml file using any text editor you’d like, and then just zip all of your files back up, and then rename the file to be a .docx and it should open correctly in word.