Greetings,
I have encountered some peculiar behavior which I can neither explain nor find referenced in the documentation. I am using InfoPath 2010 on Windows 7 and am developing a C# form. The structure of the underlying data is something like:
<Submission>
<Patient>
<Isolation />
</Patient>
</Submission>
What I am attempting to do is programmatically add an Isolation to a Patient when a user clicks a button. (For debugging purposes I have simulated this event in the FormEvents_Loading method to eliminate other factors...the results are the same.) At present, the patient initializes with 1 Isolation from the default template.
I can get an XPathNavigator to a Patient just fine, and even inspect and change attributes if I please. When it comes time to call AppendChild() to add an Isolation I make sure the NodeType is Element and then call AppendChild(). Now, in the absence of any exceptions, I would expect a new Isolation to be created and added under Patient; but alas, this is not the case. What appears to be happening is that the new Isolation is created but instead of appending to the list of Isolations in Patient, the original Isolation from the default template is replaced with the new one. I can find no documentation regarding this behavior whether it be about methodologies for calling AppendChild() or invalid states of XPathNavigators where the method does nothing. So, does anyone have an idea on what could be happening?
Below is some code which shows what I am doing. I have tried using various overloads of AppendChild(); this example just shows one case:
const string ATTR_1 = NODE_NAME_PATIENT_ISOLATIONS_PATIENT;
const string ATTR_2 =
NODE_NAME_PATIENT_ISOLATIONS_ISOLATION;
for (int i = 1; i <= 2; i++)
{
string
localName = NODE_NAME_PATIENT_ISOLATIONS.Substring(2);
XmlDocument doc = new XmlDocument();
XmlElement ele = doc.CreateElement(DATA_PREFIX,
localName, DATA_NAMESPACE);
ele.Attributes.Append(doc.CreateAttribute(ATTR_1));
ele.Attributes.Append(doc.CreateAttribute(ATTR_2));
if( i == 1 )
ele.SetAttribute(ATTR_1, "99");
ele.SetAttribute(ATTR_2, i.ToString());
XPathNavigator
n1 = ele.CreateNavigator();
if (patient.NodeType != XPathNodeType.Element) patient.MoveToParent();
patient.AppendChild(n1);
XPathNodeIterator
kids = patient.Select(NODE_NAME_PATIENT_ISOLATIONS, nsManagerMain);
MessageBox.Show("Total Kids = " + kids.Count);
}
In this scenario I create a loop to apend 2 Isolation elements to an existing Patient. When the loop starts the patient already has 1 isolation (from the template). I would therefore expect 3 total isolations after the loop finished. The first isolation added sets 2 attributes, one to the counter value and the other to an example value of 99. After the first iteration the OuterXml for the patient looks as follows (notice only 1 Isolation):
<d:Daily_Audit_Form_-_Patients xmlns:d=\"http://schemas.microsoft.com/office/infopath/2003/ado/dataFields\" >
<d:Daily_Audit_Form_-_Patient_Isolations Patient_ID="99" Isolation_ID="1"/>
</d:Daily_Audit_Form_-_Patients>
The second iteration only sets the attribute with the counter value and does not use the example value of 99. After the second iteration the OuterXml looks as follows:
<d:Daily_Audit_Form_-_Patients xmlns:d=\"http://schemas.microsoft.com/office/infopath/2003/ado/dataFields\" >
<d:Daily_Audit_Form_-_Patient_Isolations Patient_ID="" Isolation_ID="2"/>
</d:Daily_Audit_Form_-_Patients>
In this case, in addition to there only being 1 Isolation node, notice also that the example value of 99 is missing. This tells me that the AppendChild() method is not a no-op and that in fact the new Isolation node is replacing the existing node, or, at the very least, is merely overcopying the original attributes.
The only thing I can suspect this point is that Isolations do have optional child elements but the schema defines the occurrences as being from 0 to unbounded. And, there are also repeating tables bound to these children elements on the form but as this is not a GUI issue I can't fathom that that is material to what is happening...
So, any clues?
Thanks,
Tony