How to delete a TableRow in WordProcessingML using OOXML?

Viewed 867

I have a super simple document with just a table with a few blank rows and I'm trying to remove all the rows. ( The purpose is to actually remove just the blank rows ultimately but I wasn't having any luck with removing any rows at all).

public static void SearchAndReplace(string document)
        {
            using (WordprocessingDocument doc = WordprocessingDocument.Open(document, true))
            {
               var body = doc.MainDocumentPart.Document.Body;
                foreach (var table in body.Elements<Table>())
                {
                    foreach (var row in table.Elements<TableRow>())
                    {
                        table.RemoveChild<TableRow>(row);
                        continue;

                    }
                }             
                doc.Save();
            }
        }

The document has a single page, with just one table with four rows but the above doesn't remove any rows for some reason.

I've also tried

row.Remove()

This has no effect either, i.e. after running this no row gets removed. Any ideas what is wrong with this? This is what my document looks like

enter image description here

Thanks

1 Answers

In your first attempt, you used the IEnumerable<TableRow> created by the OpenXmlElement.Elements<T>() method, which enumerates TableRow instances from the collection of ChildElements of your Table. That collection of ChildElements is computed dynamically and instances are returned using yield return. This happens while you change that collection of ChildElements by removing elements,

  1. which means you are breaking the links between children and their parents and siblings,
  2. which means you don't get the full set of TableRow elements,
  3. which means you can't delete the TableRow instances.

However, I'd guess you should be able to delete the first TableRow instance.

Using ToList(), you materialize the collection of TableRow instances and get hold of all of them in a separate List<TableRow>. This way, you are working on a fixed collection rather than one that is computed dynamically as you go. And this is why this works.

As a general rule, you should never change a collection (e.g., by deleting elements of the collection) that you enumerate.

Related