locked
DeleteSelf() method does not trigger on an InfoPath Form RRS feed

  • Question

  • I am trying to trigger a WF on an InfoPath form to delete a row from a Repeating Table within the form, when a certain condition is met.
    The DeleteSelf() method does not throw any error/Exception, but does not execute as well. When I view the form after the WF completes (no exceptions again), all the rows in the repeating table are still there.
    Note: The WF is being manually started, for testing purposes.
    Am I missing something here?
    Here is the code that I use:
    **************************************************************************************************
    XmlDocument xml = new XmlDocument();
    //Open XML file and load it into XML document
    using (Stream s = workflowProperties.Item.File.OpenBinaryStream())
    {
        xml.Load(s);
    }
    //Setting up NSManager
    XmlNamespaceManager man = new XmlNamespaceManager(xml.NameTable);
    man.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
    man.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml");
    man.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-02-09T15:29:07");
    man.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-02-09T15:29:07");
    //Do your stuff with xml here. This is just an example of setting a boolean field to false.
    root = xml.CreateNavigator();
    // Count the amount of Repeating Table nodes
    XPathNodeIterator iter = root.Select("/my:myFields/my:grpRequest", man);
    int nodesCount = iter.Count;
    string app = GetSubstring(workflowProperties.Item["Title"].ToString(), "_", ".xml");
    for (int i = 1; i <= nodesCount; i++)
    {
    XPathNavigator currentNodeItem = root.SelectSingleNode("/my:myFields/my:grpRequest[" + i + "]/my:strApplication", man);
        string appName = currentNodeItem.Value;
        if (appName != app)
        {
            currentNodeItem.DeleteSelf();
        }
    }
    workflowProperties.Item.SystemUpdate(false);
    **************************************************************************************************
    Thanks for the help.
    SRP
    Tuesday, July 12, 2011 4:57 PM

Answers

  • It looks to me like you are reading the form xml into an XmlDocument object (which is creating a seperate copy of the form in memory), making the changes, but then not writing back to the form xml file. You'll need to write your changed xml back over the original file for it to be updated.
    • Marked as answer by RahulPonnala Friday, July 29, 2011 2:33 PM
    Wednesday, July 13, 2011 8:40 AM
  • Yes that's it Steven - thanks!  I made some changes to your code.  It may need some touching up as I didn't get to test it:

    SPWeb myWeb = new SPSite(workflowProperties.SiteId).OpenWeb(workflowProperties.WebId);
    SPListItem myItem = myWeb.Lists[workflowProperties.ListId].GetItemById(workflowProperties.ItemId);
    
    SPFile myFile = myItem.File;
    MemoryStream myInStream = new MemoryStream(myFile.OpenBinary());
    XmlDocument xml = new XmlDocument();
    xml.Load(myInStream);
    
    
    //Setting up NSManager
    
    XmlNamespaceManager man = new XmlNamespaceManager(xml.NameTable); 
    man.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 
    man.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml"); 
    man.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-02-09T15:29:07"); 
    man.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-02-09T15:29:07");
     
    
    //Do your stuff with xml here. This is just an example of setting a boolean field to false.
     
    root = xml.CreateNavigator();
     
    
    // Count the amount of Repeating Table nodes
     
    XPathNodeIterator iter = root.Select("/my:myFields/my:grpRequest", man);
     
    int nodesCount = iter.Count;
     
    
    string app = GetSubstring(workflowProperties.Item["Title"].ToString(), "_", ".xml");
     
    
    for (int i = 1; i <= nodesCount; i++)
     
    {
     
    XPathNavigator currentNodeItem = root.SelectSingleNode("/my:myFields/my:grpRequest[" + i + "]/my:strApplication", man);
     
      string appName = currentNodeItem.Value;
     
      if (appName != app)
     
      {
     
         XPathNavigator row = root.SelectSingleNode("//my:MyGroup/Option[" + i + "]", man);
         row.DeleteSelf();
    
     
      }
     
    }
    MemoryStream myOutStream = new MemoryStream();
    xml.Save(myOutStream);
    myFile.SaveBinary( myOutStream.ToArray());
     
    workflowProperties.Item.SystemUpdate(false);
    

    Wednesday, July 13, 2011 1:31 PM

All replies

  • Just looking at this briefly it looks like your code is just trying to delete the node "strApplicaation" not the row.  You need to add a reference to the group and delete that:

    XPathNavigator currentGroup = root.SelectSingleNode("/my:myFields/my:grpRequest[i]", man);

    Then for the delete:

    currentGroup.DeleteSelf();


    • Edited by Melissa Renton MCTS Tuesday, July 12, 2011 6:06 PM needed to replace 1 with i in selectsinglenode
    Tuesday, July 12, 2011 5:52 PM
  • I tried that as well....No success..

    Is there something on the xml side that I need to update after I make the changes to the XMLDOM...not just update the workflow item, but update the innerxml piece of it?

    Tuesday, July 12, 2011 5:58 PM
  • No, you shouldn't need to make any changes in the xml. I edited my original post, I accidently put a 1 instead of an i (which would cause the first row to be deleted). You could even try this: 

    XmlDocument xml = new XmlDocument();
     
    
    //Open XML file and load it into XML document
     
    using (Stream s = workflowProperties.Item.File.OpenBinaryStream())
     
    {
     
      xml.Load(s);
     
    }
     
    
    //Setting up NSManager
     
    XmlNamespaceManager man = new XmlNamespaceManager(xml.NameTable);
     
    man.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance");
     
    man.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml");
     
    man.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-02-09T15:29:07");
     
    man.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-02-09T15:29:07");
     
    
    //Do your stuff with xml here. This is just an example of setting a boolean field to false.
     
    root = xml.CreateNavigator();
     
    
    // Count the amount of Repeating Table nodes
     
    XPathNodeIterator iter = root.Select("/my:myFields/my:grpRequest", man);
     
    int nodesCount = iter.Count;
     
    
    string app = GetSubstring(workflowProperties.Item["Title"].ToString(), "_", ".xml");
     
    
    for (int i = 1; i <= nodesCount; i++)
     
    {
     
    XPathNavigator currentNodeItem = root.SelectSingleNode("/my:myFields/my:grpRequest[" + i + "]/my:strApplication", man);
     
      string appName = currentNodeItem.Value;
     
      if (appName != app)
     
      {
     
        XPathNavigator row = this.MainDataSource.SelectSingleNode("//my:MyGroup/Option[" + i + "]", man);
           row.DeleteSelf();
     
      }
     
    }
     
    workflowProperties.Item.SystemUpdate(false);

    Tuesday, July 12, 2011 6:15 PM
  • Thanks for the update Melissa.

    Just a small check here, as said in my original post, I am running a SharePoint WF on an InfoPath form hosted in a Forms lib...so the "this.MainDataSource" prop is NA here (referring to the if condition in the post above).

    But I tried the

    SelectSingleNode("//my:MyGroup/Option[" + i + "]", man)
    Even this doesnt do the trick.....

    A note....I am debugging my WF and inserted some counters before and after the delete..and the counter updates, as in, when the DeleteSelf() executes, the row is removed and
    the counter is reduced by 1. So the rows are getting deleted, I think, but somehow the forms state is not preserved....That is the only reason why I speculate it could be something else...
    some XML thing...I need to do, to update the Form Item..

    Makes sense?
    Tuesday, July 12, 2011 7:29 PM
  • It looks to me like you are reading the form xml into an XmlDocument object (which is creating a seperate copy of the form in memory), making the changes, but then not writing back to the form xml file. You'll need to write your changed xml back over the original file for it to be updated.
    • Marked as answer by RahulPonnala Friday, July 29, 2011 2:33 PM
    Wednesday, July 13, 2011 8:40 AM
  • Yes that's it Steven - thanks!  I made some changes to your code.  It may need some touching up as I didn't get to test it:

    SPWeb myWeb = new SPSite(workflowProperties.SiteId).OpenWeb(workflowProperties.WebId);
    SPListItem myItem = myWeb.Lists[workflowProperties.ListId].GetItemById(workflowProperties.ItemId);
    
    SPFile myFile = myItem.File;
    MemoryStream myInStream = new MemoryStream(myFile.OpenBinary());
    XmlDocument xml = new XmlDocument();
    xml.Load(myInStream);
    
    
    //Setting up NSManager
    
    XmlNamespaceManager man = new XmlNamespaceManager(xml.NameTable); 
    man.AddNamespace("xsi", "http://www.w3.org/2001/XMLSchema-instance"); 
    man.AddNamespace("xhtml", "http://www.w3.org/1999/xhtml"); 
    man.AddNamespace("xd", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-02-09T15:29:07"); 
    man.AddNamespace("my", "http://schemas.microsoft.com/office/infopath/2003/myXSD/2010-02-09T15:29:07");
     
    
    //Do your stuff with xml here. This is just an example of setting a boolean field to false.
     
    root = xml.CreateNavigator();
     
    
    // Count the amount of Repeating Table nodes
     
    XPathNodeIterator iter = root.Select("/my:myFields/my:grpRequest", man);
     
    int nodesCount = iter.Count;
     
    
    string app = GetSubstring(workflowProperties.Item["Title"].ToString(), "_", ".xml");
     
    
    for (int i = 1; i <= nodesCount; i++)
     
    {
     
    XPathNavigator currentNodeItem = root.SelectSingleNode("/my:myFields/my:grpRequest[" + i + "]/my:strApplication", man);
     
      string appName = currentNodeItem.Value;
     
      if (appName != app)
     
      {
     
         XPathNavigator row = root.SelectSingleNode("//my:MyGroup/Option[" + i + "]", man);
         row.DeleteSelf();
    
     
      }
     
    }
    MemoryStream myOutStream = new MemoryStream();
    xml.Save(myOutStream);
    myFile.SaveBinary( myOutStream.ToArray());
     
    workflowProperties.Item.SystemUpdate(false);
    

    Wednesday, July 13, 2011 1:31 PM