Skip to main content

Cloud

LINQ Querying of InfoPath 2010 Forms

Recently, I was asked to create an InfoPath 2010 form that would distribute user input into three different lists on a SharePoint 2010 site. To avoid using code within the InfoPath form itself and to make it easier to deploy into SharePoint, I created an event receiver on the forms library where the InfoPath form is submitted after completion.
The event receiver needed to extract all the data entered on the form and create items in the three different lists corresponding to the user’s entries. To my surprise, the XML that is created by InfoPath to store the data in the submitted forms cannot be queried via LINQ due to the namespace that is appended to the entry variables. The namespace for the general variables that are created by adding controls to the page is “my” and the ‘:’ character is not a valid character in a LINQ to XML query.
First, I looked into using the XmlNamespaceManager to get the “my” namespace to use in the descendants methods. However, the only namespace that was returned was the xml namespace, although the xml clearly shows that there are many namespaces on the root node. Another option I looked into was making the namespace a hard coded URL if it was static, but it seemed to be based on a date and time when the XSD was last updated. Therefore, if the XSD was updated, the URL would change and need to be updated in the code.
Ultimately, I chose to use a simple solution to find and replace the text function on the XML from the InfoPath form. I had to replace all of the colons in the namespace with a character or string that is valid in LINQ. The key must contain the namespace “my” followed by a ‘:’ to look like “my:”. However, there could potentially be multiple namespaces in the document based on the data connections used within the form. The function below allows you to replace all the namespaces at once with LINQ friendly strings.

public XDocument RemoveNamespaceFromXml(Stream fileStream, Dictionary<string,string> namespaceReplacing)
{
    StreamReader reader = new StreamReader(fileStream);
    string xml = reader.ReadToEnd();
    foreach(KeyValuePair<string,string> nsr in namespaceReplacing)
    {
        xml = xml.Replace(nsr.Key, nsr.Value);
    }
    return XDocument.Parse(xml);
}

After you run the function, the XDocument that is returned from this method can be queried by LINQ to get the data needed from the form to accomplish your task.

Thoughts on “LINQ Querying of InfoPath 2010 Forms”

  1. After a little jiggling around with the arguments for this method I finally got it to return a correct result. Having the same issue as the author with the prefixed “my:” in InfoPath documents, I must say this is an elegant solution. Thanks.

Leave a Reply

Your email address will not be published. Required fields are marked *

This site uses Akismet to reduce spam. Learn how your comment data is processed.

Follow Us