Tuesday, April 29, 2008

Accessing Infopath 2007 XML Data Source using Infopath Deserialization

Usually, if we want to access Infopath data source , we can use XPathNavigator class. Take a look of this example. Suppose we have infopath form with this data source.


This infopath form template have 2 data source :
- name , data type : text(string) , default value : Carlos
- age, data type : whole number (integer), default value : 25

You can use this code to get the value of name / age :
public void FormEvents_Loading(object sender, LoadingEventArgs e)
{
// Write your code here.
XPathNavigator root = MainDataSource.CreateNavigator();
XPathNavigator nameNode = root.SelectSingleNode("/my:myFields/my:Name", NamespaceManager);
EventLog.WriteEntry("InfopathTest", "The name is " + nameNode.Value);
}

The result :


I found a nice way to navigate the infopath data source using deserialization. You can read the details in the Patrick Tisseghem's article here

I modify the code a bit to be usable in this example. The first thing you have to do is save the infopath form as source files (Click File - Save as Source Files in the Infopath menubar) or just use WinZip / WinRAR / other software archiver to extract the xsn files.

Save it to your harddisk (ex : C:\temp\Infopath\sourcefiles). There are some files that will be extracted by Infopath like this picture below.

The only file you have to use is the myschema.xsd. Close your Infopath form (if you don't do this, the program cannot generate the class). Open Visual Studio command prompt and navigate to the path you selected before (in my example : C:\temp\Infopath\sourcefiles ) and run this code
XSD myschema.xsd /c


This command will generate .NET classes from the schema we provided (in C# by default). In this example it will generate a file named myschema.cs

Next step, add this class to your infopath code


Then use this code to retrieve the value of name / age.

public void FormEvents_Loading(object sender, LoadingEventArgs e)
{
// Write your code here.
XPathNavigator root = MainDataSource.CreateNavigator();
XPathNavigator node = root.SelectSingleNode("/my:myFields", NamespaceManager);
myFields mf = new myFields();
XmlSerializer xs = new XmlSerializer(typeof(myFields));
UTF8Encoding encoding = new UTF8Encoding();
byte[] fileBytes = encoding.GetBytes(node.OuterXml);
MemoryStream ms = new MemoryStream(fileBytes);
mf = (myFields)xs.Deserialize(ms);
EventLog.WriteEntry("InfopathTest", mf.Name + " is " + mf.Age + " years old");
}

don't forget to add these codes to the using section

using System.Xml.Serialization;
using System.IO;
using System.Text;

The result :


In my opinion, this is a nice and cool way to access Infopath data source. We don't have to care about any XPath query again. Feel free to give your comment here.

2 comments:

Sanli Oktodinata said...

sangat berguna ini, memberikan tips and trik yg menarik.. mantep gus, lanjutkan perjuangan lu!!

btw, itu avatar profile mantep banget!!

agoesz said...

thx for your comment SA :D lu juga seharusnya pasang logo MCPD lu :))