So, I had been asked to write some code to update an Infopath form’s data as it passed through a workflow. This data was being declared as a column in SharePoint, and we wanted the columns value to update. A long struggle ensued…
Right, so, I started with some code to get a SharePoint column, update the column, and save the changes.
SPWeb myWeb = new
SPSite(workflowProperties.SiteId).OpenWeb(workflowProperties.WebId);
SPListItem myItem =
myWeb.Lists[workflowProperties.ListId].
GetItemById(workflowProperties.ItemId);
myItem.Properties["Column Name"] = “Column Value”;
myItem.Update();
This worked a treat - but only for columns defined normally. Columns being read from the form lost their values as soon as the update() function was run.
And that was the problem - the values were being read from the form data, the XML. I had hoped that SharePoint would be clever enough to write back into the XML - it isn’t. Instead, it appears you have to do this by hand…
First, get the SharePoint Listitem
SPWeb myWeb = new SPSite(workflowProperties.SiteId).
OpenWeb(workflowProperties.WebId);
SPListItem myItem = myWeb.Lists[workflowProperties.ListId].
GetItemById(workflowProperties.ItemId);
Then get the File for that ListItem - i.e. the XML data
SPFile myFile = myItem.File;
MemoryStream myInStream = new MemoryStream(myFile.OpenBinary());
XmlDocument myDoc = new XmlDocument();
myDoc.Load(myInStream);
Then make your changes to the XML in here - below is what I did, as an example
XmlNode myRoot = myDoc.DocumentElement;
XmlNamespaceManager xmlNSManager = new
XmlNamespaceManager(myDoc.NameTable );
xmlNSManager.AddNamespace("myNameSpace",
"http://schemas.microsoft.com/office/infopath/2003/myXSD/2006-06-08T14:13:41");
XmlNode myColumnToAlter = myRoot.
SelectSingleNode("/myNameSpace:WFTaskForm/myNameSpace:myColumn", xmlNSManager);
myColumnToAlter.InnerText = "This has been changed";
When you’ve finished changing your XML data, save the XmlDocument object back into SharePoint as a file.
MemoryStream myOutStream = new MemoryStream();
myDoc.Save(myOutStream);
myFile.SaveBinary( myOutStream.ToArray());
Took me a ridiculous amount of time to figure all that out. It’s a good job that SharePoint makes it so easy…
Actually, I can see why they did it this way - but throwing an exception when I tried to write to the columns being read from the form would be useful. And maybe some instructions somewhere about how to do this. Still, maybe this will prove useful to someone…
Thanks for your help! Writing back to Infopath xml should be simple, but has proven rather difficult. Your article saved me hours of work!
Thanks for the great post!
What is the NamespaceManager for InfoPath 2007 Form?
“http://schemas.microsoft.com/office/infopath/2003/myXSD/2006-06-08T14:13:41″);”
You can find this from the form itself. I think it’s one of the properties of the .XSN file itself. Try opening the .XSN in Infopath and checking for properties (under the file menu) there.
As you’ve rightly noticed, Infopath creates a unique namespace for your form - based on it’s creation/update date, I think.
(I’m no Infopath expert!)
EDIT: Took a look, and the namespace under the File>Properties isn’t quite right - some colons have been replaced by underscores.
There is some good advice from Madhur - which is how I think I’ve done this in the past, actually (a long, long time ago):
Hi there,
Have anyone experience where the schema has change?
I used the code and the workflow run somehow the InfoPath Schema of the xml file has change.
Regards,
Linda.
Hmm. Sounds weird. Have you updated the Infopath form maybe? I’ve had issues where we’ve updated the Infopath form - versioning on Infopath forms in SharePoint can be a bit hit and miss. We ended up installing our latest version for as an entirely new form…
The code works fine for simple field updates. I tried it for just a text box on a sample form.
But, when I have a Contact Selector on the infopath form I get the dreaded “Schema validation found non-datatype errors”. This is a repeating object that allows the lookup of a person. If I have this control on the page, and I read and save the form (even without an update) I get the above mentioned error. I have read up on the error and most people experience it when they set a nil value to an object and don’t remove the attribute.
Any help is appreciated