Monday, January 14, 2008

Microsoft Infopath 2007 Tips And Trick January 14, 2008

In my last project, I use Microsoft Infopath 2007 intensively. In the beginning, I have difficulties in navigating Microsoft Infopath 2007 data source because all data is stored in XML. Here are the codes I often use when dealing with Infopath.

Most of my codes use XPathNavigator class, so don't forget to add this reference in the using section.I assume you place this code in Infopath code( example : in Form Load event)

using System.Xml;
using System.Xml.XPath;

Common problem #1 : Get Microsoft Infopath 2007 Data Source XML value
Suppose you have a data source like this :To get the value of name, you can use this code.

XPathNavigator root = MainDataSource.CreateNavigator();
XPathNavigator nameNode = root.SelectSingleNode("/my:myFields/my:Name",NamespaceManager);

string name = nameNode.Value;

note : the parameter in SelectSingleNode method is a XPath query. You can get this by right-clicking the data source you want, click "Copy XPath"

Common problem #2 : Set A Microsoft Infopath 2007 Data Source XML Value
Suppose you want to set the name to a value "newvalue". You can use this code.

XPathNavigator root = MainDataSource.CreateNavigator();
XPathNavigator nameNode = root.SelectSingleNode("/my:myFields/my:Name",NamespaceManager);

nameNode.SetValue("newvalue");
Common problem #3 : Loop through a repeating table in Microsoft Infopath 2007
Suppose you have a data source like thisThen , to get the value of field1, field2, and field3 iteratively, use this code.

XPathNavigator domNav = MainDataSource.CreateNavigator();
XPathNodeIterator rows = domNav.Select("/my:myFields/my:table/my:row", NamespaceManager);

while (rows.MoveNext())
{
string field1 = rows.Current.SelectSingleNode("my:field1", NamespaceManager).Value;
string field2 = rows.Current.SelectSingleNode("my:field2", NamespaceManager).Value;
string field3 = rows.Current.SelectSingleNode("my:field3", NamespaceManager).Value;
}
Common problem #4 : Add a row to Microsoft Infopath 2007 repeating table

If you have a repeating table like thiswith this data sourceYou can add a row to this repeating table by using this code.

string myNamespace = NamespaceManager.LookupNamespace("my");
using (XmlWriter writer = MainDataSource.CreateNavigator().SelectSingleNode(
"/my:myFields/my:group1", NamespaceManager).AppendChild())
{
writer.WriteStartElement("group2", myNamespace);
writer.WriteElementString("field1", myNamespace, "Cell 1");
writer.WriteElementString("field2", myNamespace, "Cell 2");
writer.WriteElementString("field3", myNamespace, "Cell 3");
writer.WriteEndElement();
writer.Close();
}
Article #3 was taken from this great site . Article #4 was taken from the another great site.

Note that NamespaceManager is a property which exists only in Infopath code. To use these code in another place, such as K2 Blackpearl, you have to define the NamespaceManager by yourself. You can use this method.

public XmlNamespaceManager InitNamespaceManager(XmlDocument xmlDOMDoc)
{
XmlNamespaceManager xnmMan;
xnmMan = new XmlNamespaceManager(xmlDOMDoc.NameTable);
foreach (XmlAttribute nsAttr in xmlDOMDoc.DocumentElement.Attributes)
{
if (nsAttr.Prefix=="xmlns")
xnmMan.AddNamespace(nsAttr.LocalName,nsAttr.Value);
}
return xnmMan;
}
and use this code to create your NamespaceManager ( I assume you use K2 Blackpearl and Microsoft Infopath 2007)

XmlDocument doc = new XmlDocument();
string xmlString = K2.ProcessInstance.XmlFields["MyInfopathForm"].Value;
doc.LoadXml(xmlString);
XmlNamespaceManager NamespaceManager = InitNamespaceManager(doc);

I took this code from this great blog.
All credits should go to the original poster.

Hope this article helps:)

5 comments:

Cathy Ward said...

Good article

agoesz said...

Thank you for visiting , cathy :)

Русский Человек said...

How to do the loop for this /my:queryFields/my:dataFields/my:GetCustomersResponse/my:GetCustomersResult/my:DataSet1/my:FichaInternaDetallado/my:PlazaSubT

for this field "PlazaSubT"

I've try

/my:queryFields/my:dataFields/my:GetCustomersResponse/my:GetCustomersResult/my:DataSet1/my:FichaInternaDetallado/my:PlazaSubT

but It does't work

agoesz said...

Mr/Ms Русский Человек , could you give a clearer detail about your problem ? such as the structure of your data (or picture like the example above) so that I can help you better?

if your data is using repeating table , you should use XPathNodeIterator class. If not, use XPathNavigator class like the example I provided above

Anonymous said...

Thank you so much!
This code save my life!!!