XPathNavigator.Clone() not really cloning? - InfoPath Dev
in

InfoPath Dev

XPathNavigator.Clone() not really cloning?

Last post 05-19-2010 07:23 AM by colecg. 8 replies.
Page 1 of 1 (9 items)
Sort Posts: Previous Next
  • 04-09-2009 11:58 AM

    • jaskey
    • Not Ranked
    • Joined on 04-09-2009
    • Laramie, WY
    • Posts 1

    XPathNavigator.Clone() not really cloning?

    Hello everyone...

     Firstly, this site is *amazing* and I want to thank everyone for the past postings which has allowed me to get a fairly complex Infopath form up and running in couple of weeks...

     I am making a form with C# codebehind and I am programmatically adding a new row to my repeating table via a button click...

     I am using Clone to copy the first row (always exists) and then interating through each child and clearing the values for the new row. However, it seems that the return from Clone is still pointing to the original row as my end result is the original first row and the new row having cleared values. I was assuming that Clone() was making a copy of the original node but it seems that it is not in my case... 

     Any thoughts? 

     Thank you!! 

    jess

     

    public void ButtonAddSample_Clicked(object sender, ClickedEventArgs e)

    {

    // get a reference to the node the repeating table is bound to

    XPathNavigator row = MainDataSource.CreateNavigator().SelectSingleNode("/dfs:myFields/dfs:queryFields/tns:SubmitGroundwaterSamplingData/tns:data/tns:GroundwaterSamplingData/tns:SampleData/tns:SampleData", NamespaceManager);

     

    // make a copy of the node by cloning it

    XPathNavigator newrow = row.Clone();

    //remove all former values

    XPathNodeIterator iterator = newrow.SelectChildren(XPathNodeType.Element);while (iterator.MoveNext())

    {

    iterator.Current.SetValue(String.Empty);

    }

    //add it after

    newrow.InsertAfter(row);

    }

  • 04-09-2009 04:45 PM In reply to

    Re: XPathNavigator.Clone() not really cloning?

    I went and tried this for myself and was surprised to find the same thing as you did.  It turns out that like several members of XPathNavigator, Clone() functions differently from the member of the same name in the XmlNode class. However, if you read the documentation on MSDN, you will find this:

    XPathNavigator..::.Clone Method

    When overridden in a derived class, creates a new XPathNavigator positioned at the same node as this XPathNavigator.

    The Clone() method actually creates a copy of the XPathNavigator object, not a clone of the node.  If you want to add a copy of a node to your data source, you can:

    1. Append the node to the data source (no need to use Clone(); appending it will create a copy of the node).
    2. Select the new node using SelectSingleNode() or other selection methods
    3. Modify the new node

    I typically do not recommend adding rows to repeating groups by copying a node in the main data source because it leaves your strategy up the creek without a paddle if all the rows in the section happen to be deleted.

    Jimmy Rishe / Software Developer / Microsoft MVP
    Qdabra Software
  • 07-30-2009 05:54 AM In reply to

    Re: XPathNavigator.Clone() not really cloning?

    I am encountering the same situation - were you able to resolve this using the recommended solution?  I would be very interested in any info you can share - thanks!!

  • 05-17-2010 04:23 AM In reply to

    Re: XPathNavigator.Clone() not really cloning?

    did you ever suceed solving this issue?

     I have same problem and came accross your post

    Thanks

  • 05-17-2010 04:47 AM In reply to

    Re: XPathNavigator.Clone() not really cloning?

     I already described how to get around the issue.  Why don't you try it out for yourself?

    Jimmy Rishe / Software Developer / Microsoft MVP
    Qdabra Software
  • 05-18-2010 12:11 AM In reply to

    Re: XPathNavigator.Clone() not really cloning?

    Hi

    I have tried of course before I posted on here

    I tried following which gives me problem

    Case one 

    MainDataSource.CreateNavigator().AppendChild(); //This does not append anything

     Case two

    XPathNavigator newElement = MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:group3/my:group4", NamespaceManager);

    MainDataSource.CreateNavigator().AppendChild(newElement);

    //This gives me following error

    Unexpected XML declaration. The XML declaration must be the first node in the document, and no white space characters are allowed to appear before it. Line 1, position 9.

    Regards

  • 05-18-2010 12:43 AM In reply to

    Re: XPathNavigator.Clone() not really cloning?

    okay I have suceeded in appending the child

    But the reason I was using clone before was because I will have a list of  or more nodes and the new node has to be at top, not at the end of the list, because users who have 100 nodes will have to scroll and I have some spoiled users who do not want to do that.

    So, clone gave me possibility to do InsertAfter of cloned node but failed to give me possibility to change the values of attributes inside of cloned node without changing the original.

    Now, with using AppendChild, can you give me an advice how to quickly move that child that was appended at the end to be at first position?

    Thank you

  • 05-18-2010 08:51 AM In reply to

    Re: XPathNavigator.Clone() not really cloning?

     If you want to insert items to the front of the list:

    1. Select the first item in the list.

    2. Insert a copy of it after itself using InsertAfter().

    3. Modify the first item in the list (selected in step 1).

    I don't see any reason why you would need Clone() in order to do this.

    Jimmy Rishe / Software Developer / Microsoft MVP
    Qdabra Software
  • 05-19-2010 07:23 AM In reply to

    Re: XPathNavigator.Clone() not really cloning?

    Thank you.

    I followed your advice, but I had problem with one control text box that gets filled with System.Environment.UserName

    I ended up with following code for my purpose

    XPathNavigator firstElement = MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:group3/my:group4[1]", NamespaceManager);string userName = firstElement.SelectSingleNode("my:txtCreatedBy", NamespaceManager).Value; //had to add this because this would get written over when other user inserted new item

    firstElement.InsertAfter(firstElement);

    XPathNavigator newElement = MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:group3/my:group4[1]", NamespaceManager);

    newElement.SelectSingleNode("my:dtDate", NamespaceManager).SetValue("");

    newElement.SelectSingleNode("my:ddlStatus", NamespaceManager).SetValue("Draft");

    newElement.SelectSingleNode("my:ddlUpdateType", NamespaceManager).SetValue("Update Report");

    newElement.SelectSingleNode("my:ddlMonthOfMonthlyUpdate", NamespaceManager).SetValue("January 2010");

    newElement.SelectSingleNode("my:Update", NamespaceManager).SetValue("");

    newElement.SelectSingleNode("my:txtComment", NamespaceManager).SetValue("");

    newElement.SelectSingleNode("my:txtMonthlySummary", NamespaceManager).SetValue("");

    newElement.SelectSingleNode("my:txtAssessment", NamespaceManager).SetValue("");

    newElement.SelectSingleNode("my:txtAtt", NamespaceManager).SetValue("");newElement.SelectSingleNode("my:txtCreatedBy", NamespaceManager).SetValue(System.Environment.UserName);//this action was setting the user name of both new and orginial item to same user name

    newElement.MoveToNext();//I move to next to return the original user name on previous node

    newElement.SelectSingleNode("my:txtCreatedBy", NamespaceManager).SetValue(userName);

     

    Why does only this one field txtCreatedBy gets written over for node prior to newly inserted one? rest of the fields are untouched.

    Thank you again for all your help

Page 1 of 1 (9 items)
Copyright © 2003-2019 Qdabra Software. All rights reserved.
View our Terms of Use.