in

Dot Net Mafia

Group site for developer blogs dealing with (usually) .NET, SharePoint 2013, SharePoint 2010, Office 365, SharePoint Online, and other Microsoft products, as well as some discussion of general programming related concepts.

This Blog

Syndication

Archives

Corey Roth [MVP]

A SharePoint MVP bringing you the latest time saving tips for SharePoint 2013, Office 365 / SharePoint Online and Visual Studio 2013.

Using LINQ to XML to access the data of a form saved to a form library in a workflow

As I have mention in the past LINQ to XML is a great way to manipulate the XML data out of an InfoPath form.  I thought I would show how you can also use the same technique to work with the data of a form saved to a form library which launches a workflow (although you could apply this technique to the association or task forms as well).  The first thing we need to do is get the XML of the InfoPath initiation form, before we can work with it.

For the purpose of my example, my OnWorkflowActivated activity writes to a public SPWorkflowActivationProperties property called workflowProperties.  In my Invoked event handling method of my OnWorkflowActivated activity, we use the Item object on my workflowProperties to open the file and get the XML.  You can then use the File object along with OpenBinary() to get the raw bytes of the XML.

byte[] xmlBytes = workflowProperties.Item.File.OpenBinary();

You can then takes those bytes and read them into a regular string.

string xmlString = System.Text.Encoding.UTF8.GetString(xmlBytes);

if (xmlString[0] == (char)0xfeff)

    xmlString = xmlString.Substring(1);

If you are curious about the 0xfeff business that is used to deal with the byte-order mark character in Unicode.  I picked up this trick from another post somewhere, but I can’t remember where currently. 

Now we need to get the XML string into an XDocument class so that we can query it and manipulate it.  Since we have a string, we will need to create a StringReader to read it.

XDocument documentsXml = XDocument.Load(new System.IO.StringReader(xmlString));

If you wanted to work with the Association form instead of the form that started the workflow, you would use a line like the following.  The InitiationData property of the SPWorkflowActivationProperties object provides XML that can be loaded into the XDocument class.

XDocument documentsXml = XDocument.Load(workflowProperties.InitiationData);

InfoPath documents always have a namespace defined for my so we need to use the XNamespace object for any future references inside the InfoPath form.

XNamespace documentNamespace = "http://schemas.microsoft.com/office/infopath/2003/myXSD/2098-05-03T16:48:38";

At this point you can start using LINQ to XML to get the data you need out of the InfoPath form.  For example, if I had a field called my:FirstName at the root of the document.  I could use something like the following to get the value.

string firstName = documentsXml.Root.Element(documentNamespace + "FirstName").Value;

If you are working with other data types, you can always cast it like this.

int customerId = int.Parse(documentsXml.Root.Element(documentNamespace + "CustomerId").Value);

In my example from last week, you saw how you could use LINQ to XML to iterate through a repeating table.  As another example to iterate through a repeating table called Items with an element of Item, you could do something like the following:

var items = from item in documentsXml.Root.Element("Items").Elements("Item")

            select item;

 

foreach (var item in items)

{

    Console.WriteLine(item.Element("Field1").Value);

    Console.WriteLine(item.Element("Field2").Value);

}

In this case, I use LINQ to return an IEnumberable<XElement> representing each repeating item.  I can then use this in a foreach loop to print out the results.  Yes I know you wouldn’t use Console.Writeline in a workflow, but you get the point here.  LINQ to XML really offers a lot of flexibility to manipulate the XML data inside a form.  Hopefully, it will make your experience with InfoPath and workflow a better one.

Comments

 

Michael said:

Good article.

Thanks!

January 1, 2010 3:12 PM
 

amir said:

it was very useful and thnx

September 15, 2011 10:31 AM

Leave a Comment

(required)  
(optional)
(required)  
Add

About CoreyRoth

Corey Roth is an independent SharePoint consultant specializing in ECM, Apps, and Search.
2012 dotnetmafia.
Powered by Community Server (Non-Commercial Edition), by Telligent Systems