locked
Populate Repeating Table from XPathNodeIterator in C# RRS feed

  • Question

  • I cannot seem to get the right syntax to populate a repeating table from an instance of XPathNodeIterator

     XPathNodeIterator AstroMissionNodes = AstroMission.Select(AstroMissionNodesQuery);
                foreach (XPathNavigator AstroID in AstroMissionNodes)
                {
                  XPathNavigator CrewTable = root.CreateNavigator().SelectSingleNode("/my:myFields/my:Crew", NamespaceManager);
                  CrewTable.MoveToChild("CrewID", NamespaceManager.LookupNamespace("my"));
                  CrewTable.AppendChildElement("/my:myFields/my:Crew", "CrewID", NamespaceManager.LookupNamespace("my"), AstroID.SelectSingleNode("AstronautID", NamespaceManager).Value);
                }
                XPathNavigator firstNode = root.CreateNavigator().SelectSingleNode("/my:myFields/my:Crew/my:CrewID[1]", NamespaceManager);
                firstNode.DeleteSelf();
    
    I have looked at different example codes and none of them seem to work.
    Charles Picco
    Friday, May 6, 2011 3:48 PM

Answers

  • Here is the solution!  You apparently can not add 2 levels if the top level is the root as S.Y.M. Wong-A-Ton suggested.  I put the repeating table Crew under the existing MissionData element and it worked.  Here is the code.

                XPathNodeIterator AstroMissionNodes = AstroMission.Select(AstroMissionNodesQuery);
                XPathNavigator CrewTable = root.CreateNavigator().SelectSingleNode("/my:myFields/my:MissionData/my:Crew/my:CrewID", NamespaceManager);
                if (CrewTable.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance"))
                  CrewTable.DeleteSelf();
                foreach (XPathNavigator AstroID in AstroMissionNodes)
                {
                  XmlDocument doc = new XmlDocument();
                  XmlNode group = doc.CreateElement("Crew", NamespaceManager.LookupNamespace("my"));
                  XmlNode field = doc.CreateElement("CrewID", NamespaceManager.LookupNamespace("my"));
                  XmlNode node = group.AppendChild(field);
                  node.InnerText = AstroID.Value;
                  doc.AppendChild(group);
                  MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:MissionData", NamespaceManager).AppendChild(doc.DocumentElement.CreateNavigator());
                }
                XPathNavigator firstnode = CrewTable.SelectSingleNode("/my:myFields/my:MissionData/my:Crew/my:CrewID[1]", NamespaceManager);
                if (firstnode.IsNode)
                  firstnode.DeleteSelf();
    
    Thanks for all of your help!
    Charles Picco
    • Marked as answer by Charles Picco Tuesday, May 10, 2011 4:25 PM
    Tuesday, May 10, 2011 4:24 PM

All replies

  • It is always best to try to understand what a piece of code is doing, rather than to just blindly copy and paste code and hope that it works for you. You can get started with InfoPath programming by reading this MSDN article.

    Because we generally have no idea how you set up your form template, you must always include more information about its structure. I'm guessing that you are trying to add a CrewID node under a Crew node?

    I'm not sure why you defined CrewTable within the foreach loop; you can move it outside the loop instead of redefining it every time. And it might be better to isolate the adding of the rows to the repeating table by creating a private AddRowToRepeatingTable() method with which a row can be added and then call this method repeatedly inside of the foreach loop while passing the values of the Current node to the method. You can use one of the 4 methods described in this article to add a row to a repeating table (unless you already found that article and the code did not work for you); I generally use method 2.


    S.Y.M. Wong-A-Ton, owner of the InfoPath Solutions Blog, and author of 100+ InfoPath articles and 40+ InfoPath - SharePoint integration articles
    Monday, May 9, 2011 6:46 AM
  • First of all, I was not blindly copying code.  I know how XPathNavigators work.

    Here is a more information:

    • The field I am trying to populate is in this xpath "/my:myFields/my:Crew/my:CrewID"
    • I am trying to populate it with data contained in the AstroMissionNodes XPathNodeIterator.
    • I tried using the example from method 2 and it is not working  Here is the code.
      XPathNodeIterator AstroMissionNodes = AstroMission.Select(AstroMissionNodesQuery);
      
            foreach (XPathNavigator AstroID in AstroMissionNodes)
      
            {
      
             XmlDocument doc = new XmlDocument();
      
             XmlNode group = doc.CreateElement("my:Crew", NamespaceManager.LookupNamespace("my"));
      
             XmlNode field = doc.CreateElement("my:CrewID", NamespaceManager.LookupNamespace("my"));
      
             XmlNode node = group.AppendChild(field);
      
             node.InnerText = AstroID.Value;
      
             doc.AppendChild(group);
      
             XPathNavigator nullcheck = root.CreateNavigator().SelectSingleNode("/my:myFields/my:Crew/my:CrewID", NamespaceManager);
      
             if (nullcheck.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance"))
      
              nullcheck.DeleteSelf();
      
             MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:Crew", NamespaceManager).AppendChild(doc.DocumentElement.CreateNavigator());
      
            }
      
      
      The node gets assigned the correct value but then it crashes when I try to append the child to "/my:myFields/my:Crew", it crashes.

    Any help you can provide will be greatly appreciated.

    Thanks


    Charles Picco
    Monday, May 9, 2011 5:06 PM
  • Try this:

        XmlNode group = doc.CreateElement("Crew", NamespaceManager.LookupNamespace("my"));
    
        XmlNode field = doc.CreateElement("CrewID", NamespaceManager.LookupNamespace("my"));
    
    


    http://alecpojidaev.wordpress.com
    Monday, May 9, 2011 8:53 PM
  • Hi Alec,

    I had that syntax originally but I was still getting the message "Schema validation found non-data type errors." with exception "InvalidOperationException".  I tried putting the prefix on them

    Here is the code

       XPathNodeIterator AstroMissionNodes = AstroMission.Select(AstroMissionNodesQuery);
    
    
    
       foreach (XPathNavigator AstroID in AstroMissionNodes)
    
    
    
       {
    
    
    
        XmlDocument doc = new XmlDocument();
    
    
    
        XmlNode group = doc.CreateElement("Crew", NamespaceManager.LookupNamespace("my"));
    
    
    
        XmlNode field = doc.CreateElement("CrewID", NamespaceManager.LookupNamespace("my"));
    
    
    
        XmlNode node = group.AppendChild(field);
    
    
    
        node.InnerText = AstroID.Value;
    
    
    
        doc.AppendChild(group);
    
    
    
        XPathNavigator nullcheck = root.CreateNavigator().SelectSingleNode("/my:myFields/my:Crew/my:CrewID", NamespaceManager);
    
    
    
        MessageBox.Show("nullcheck: " + nullcheck.OuterXml.ToString());
    
    
    
        if (nullcheck.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance"))
    
    
    
        nullcheck.DeleteSelf();
    
    
    
        MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:Crew", NamespaceManager).AppendChild(doc.DocumentElement.CreateNavigator());
    
    
    
       }
    
    
    
    

    Thanks for your help

    I have also tried

    XPathNodeIterator AstroMissionNodes = AstroMission.Select(AstroMissionNodesQuery); XPathNavigator CrewTable = root.CreateNavigator().SelectSingleNode("/my:myFields/my:Crew", NamespaceManager); foreach (XPathNavigator AstroID in AstroMissionNodes) { CrewTable.AppendChildElement("my", "CrewID", NamespaceManager.LookupNamespace("my"), AstroID.Value); }

     


     

    Charles Picco


    Monday, May 9, 2011 9:16 PM
  • The problem is here:

      XmlDocument doc = new XmlDocument();

    You are creating an empty document instead of referencing the document in your context.

     

    Here is how to do it in a proper way:

    http://microsoftechies.wordpress.com/2010/12/11/add-new-row-on-button-click-in-infopath-2007/

     


    http://alecpojidaev.wordpress.com
    Monday, May 9, 2011 10:03 PM
  • According to http://www.bizsupportonline.net/infopath2007/4-way-programmatically-add-row-repeating-table.htm (method 2) - you create a separate XML document that you append to the schema you already have.  Since I have already created the child node, I do not think this is the way to do it?

     


    Charles Picco
    Monday, May 9, 2011 10:39 PM
  • You said your structure is "/my:myFields/my:Crew/my:CrewID" ?

    I'm assuming that Crew is the repeating node? Usually repeating tables have an extra container group node, which you are missing in your structure.

    So the last line in your code should reference myFields instead of Crew. Something like:

    MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields", NamespaceManager).AppendChild(doc.DocumentElement.CreateNavigator());

    Try that and see whether it helps.


    S.Y.M. Wong-A-Ton, owner of the InfoPath Solutions Blog, and author of 100+ InfoPath articles and 40+ InfoPath - SharePoint integration articles
    Tuesday, May 10, 2011 7:18 AM
  • My stucture is "/my:myFields/my:Crew/my:CrewID".

    I tried your suggestion previously and it did not work.

    I have other fields under "/my:myFields/my:Crew".  Do I have to assign values to all of the other fields in order to make it work?

    Thanks


    Charles Picco
    Tuesday, May 10, 2011 2:18 PM
  • Here is the solution!  You apparently can not add 2 levels if the top level is the root as S.Y.M. Wong-A-Ton suggested.  I put the repeating table Crew under the existing MissionData element and it worked.  Here is the code.

                XPathNodeIterator AstroMissionNodes = AstroMission.Select(AstroMissionNodesQuery);
                XPathNavigator CrewTable = root.CreateNavigator().SelectSingleNode("/my:myFields/my:MissionData/my:Crew/my:CrewID", NamespaceManager);
                if (CrewTable.MoveToAttribute("nil", "http://www.w3.org/2001/XMLSchema-instance"))
                  CrewTable.DeleteSelf();
                foreach (XPathNavigator AstroID in AstroMissionNodes)
                {
                  XmlDocument doc = new XmlDocument();
                  XmlNode group = doc.CreateElement("Crew", NamespaceManager.LookupNamespace("my"));
                  XmlNode field = doc.CreateElement("CrewID", NamespaceManager.LookupNamespace("my"));
                  XmlNode node = group.AppendChild(field);
                  node.InnerText = AstroID.Value;
                  doc.AppendChild(group);
                  MainDataSource.CreateNavigator().SelectSingleNode("/my:myFields/my:MissionData", NamespaceManager).AppendChild(doc.DocumentElement.CreateNavigator());
                }
                XPathNavigator firstnode = CrewTable.SelectSingleNode("/my:myFields/my:MissionData/my:Crew/my:CrewID[1]", NamespaceManager);
                if (firstnode.IsNode)
                  firstnode.DeleteSelf();
    
    Thanks for all of your help!
    Charles Picco
    • Marked as answer by Charles Picco Tuesday, May 10, 2011 4:25 PM
    Tuesday, May 10, 2011 4:24 PM