Assign Data from InfoPath form to Process Data Field


Badge +6

I have a Process Data Field that I need to populate from an XML field in InfoPath, Do I need to do this in code?  If so, how to I read the data from the XML Field to store the data to the Process Data Field.  I know I can set the value of the Process Data Field using K2.ProcessInstance.DataFields["ProcessDataField"].Value = .  I just don't know how to reference the XML field.


 Thanks


16 replies

Badge +10

Yes, you are probably going to have to break into some code.


 


You can get to the XML by using something like K2.ActivityInstanceDestination.XmlFields("K2InfoPathSchema")


I just went through doing this about 60days ago but cant find the code.  I will post as soon as i Find it

Badge +6
that would be great since I'm unsure of the complete syntax to drill down to the single XML field in the form
Badge +8

Hi,


It may look like what you want (this is what I use):


XmlDocument

xmlDoc = new XmlDocument();


xmlDoc.LoadXml(K2.ProcessInstance.XmlFields[

"SPEventsField"].Value);


XmlNode node = xmlDoc.SelectSingleNode("Items/Item/Item");


String documentTitle = node.InnerText;


K2.ProcessInstance.DataFields[

"DocTitle"].Value = documentTitle;

Badge +10

OK here is what we did.  Copying multiple values from an XML field in InfoPath to a datafield


public void Main(ServerEventContext K2)
{
   
 string SourceField  = "";
 string TargetField = "";
 int i;
 System.Xml.XmlNodeList XmlNodeList;
   
 XmlNodeList = SourceCode.K2Utilities.XMLFieldMod.GetXMLNodeList(K2.ProcessInstance.XmlFields["K2InfoPathSchema"].Value, "my:myFields/my:ImpactedApps/my:Apps");
         
 for (i = 0; i <= (XmlNodeList.Count - 1); i++) {
  SourceField = XmlNodeList.Item(i).InnerXml;
       
  if(TargetField!= "")
  {
   TargetField += ",";
  }


  TargetField += SourceField;
       
 }
   
 K2.ProcessInstance.DataFields["applications"].Value = TargetField;
   
 K2.Synchronous = true;
}

Badge +6

Hi Chrisg thanks for the sample code.  I'm having a little trouble following it so maybe you could help me out.  How would I modify this code if I only need to read one XML field from and InfoPath form into a single Process Data Field.  They both store a Date.

Badge +8
Hum... My code is perfect for one field, why don't you like it? :-) (3 posts above)
Badge +6
I actually just finished trying yours.  I recieved the following error though: "Namespace Manager or XsltContext needed.  This query has a prefix, variable, or user-defined function"  any ideas?
Badge +11

If your XML has namespaces, you need to pass a System.Xml.XmlNamespaceManager or XmlNameTable depending on which XML class your are using for the query.  They help the parser resolve namespaces.


 David

Badge +6

sorry, that went way over my head.


I have an InfoPath integrated workflow.  InfoPath file name is "Manufacturing Work Request IMG".  Process Data Field is named "Mfg Commit Date" so I copied the code above and did the following.


public

void Main(Project_ff218b079168429db7901350160f6386.EventItemContext_bd46df0ae8b745189ee07c19e08b863f K2)


{



XmlDocument xmlDoc = new XmlDocument();



xmlDoc.LoadXml(K2.ProcessInstance.XmlFields[

"New Manufacturing Work Request IMG"].Value);



XmlNode node = xmlDoc.SelectSingleNode("my:myFields/my:General/my:MfgCommitDate");



String commitDate = node.InnerText;



K2.ProcessInstance.DataFields[

"Mfg Commit Date"].Value = commitDate;


}


Also added "using System.XML" to the references.

Badge +3

Am I missing something here?  In K2.Net 2003 this was easily accomplished using the "Data Manipulation" event template. It was a simple drag 'n drop operation.  Why has this become so complicated in BP?  I tried using the Data Manipulation 2003 template in BP (as this is supposedly supported in SP1) and the process errors out with XPATH not found..


So, firstly why have we taken a step back in simplicity by now making a common need a code based solution in BP, and secondly is there a known issue with using the data manipulation template in BP?

Badge +6
Can anyone provide some help with this?
Badge +8
Can't you still assign a value to your Infopath field?
Badge +8

Give this a try.  Change the bolded stuff.


-------------------------------------------


            string xml = K2.ProcessInstance.XmlFields[0].Value.ToString();


            XmlDocument doc = new XmlDocument();
            doc.LoadXml(xml);


            XmlNamespaceManager nsMgr = new XmlNamespaceManager(doc.NameTable);
            nsMgr.AddNamespace("my", doc.DocumentElement.GetNamespaceOfPrefix("my"));


            doc.SelectSingleNode("//my:myFields/my:foo/my:bar", nsMgr).InnerText = "Complete";


            K2.ProcessInstance.XmlFields[0].Value = doc.OuterXml;

Badge +5
Nicely.

Random tip: not sure if this was mentioned before, but a quick way of making sure you have the correct xpath is to open your infopath form, go to the data source view, right-click your data field and select 'copy xpath'.

:)
Badge +2

With a lot of going back and forth I've got the perfect 2 lines of code to make this work:


System.Xml.

XmlNodeList xmlNodeList;


K2.ProcessInstance.DataFields[

"Role"].Value = SourceCode.Workflow.Common.XmlHelper.GetXPathValue(K2.ProcessInstance.XmlFields["Tivoli1"].Value, "my:myFields/my:System");


 Role = Datafield Name


Tivoli1 = Name of InfoPath forms


System = Infopath XML data Field


 

Badge +2

With a lot of going back and forth I've got the perfect 2 lines of code to make this work:


System.Xml.

XmlNodeList xmlNodeList;


K2.ProcessInstance.DataFields[

"Role"].Value = SourceCode.Workflow.Common.XmlHelper.GetXPathValue(K2.ProcessInstance.XmlFields["Tivoli1"].Value, "my:myFields/my:System");


 Role = Datafield Name


Tivoli1 = Name of InfoPath forms


System = Infopath XML data Field


 

Reply