diff --git a/OpenXMLTemplates/Documents/TemplateDocument.cs b/OpenXMLTemplates/Documents/TemplateDocument.cs
index e81c37a..64d7602 100644
--- a/OpenXMLTemplates/Documents/TemplateDocument.cs
+++ b/OpenXMLTemplates/Documents/TemplateDocument.cs
@@ -1,6 +1,7 @@
 using System;
 using System.Collections.Generic;
 using System.Linq;
+using DocumentFormat.OpenXml;
 using DocumentFormat.OpenXml.Packaging;
 using DocumentFormat.OpenXml.Wordprocessing;
 using OpenXMLTemplates.Utils;
@@ -113,25 +114,57 @@ internal void AddControl(ContentControl control, bool isFirstOrder)
 
         public void RemoveControlsAndKeepContent()
         {
-            foreach (var control in allContentControls)
-            {
-                var sdtElement = control.SdtElement;
-
-                var contentElement = sdtElement.Descendants()
-                    .FirstOrDefault(d => d is SdtContentBlock || d is SdtContentRun);
-                if (contentElement != null)
-                    foreach (var contentElementChildElement in contentElement.ChildElements.ToList())
-                    {
-                        contentElementChildElement.Remove();
-                        sdtElement.InsertBeforeSelf(contentElementChildElement);
-                    }
+            var contentControls = WordprocessingDocument.MainDocumentPart.Document.Descendants<SdtElement>().ToList();
 
-                sdtElement.Remove();
+            // Process each content control from innermost to outermost
+            foreach (var sdt in contentControls.OrderByDescending(s => s.Ancestors<SdtElement>().Count()))
+            {
+                if (sdt is SdtBlock sdtBlock)
+                {
+                    HandleSdtContent(sdtBlock, sdtBlock.SdtContentBlock);
+                }
+                else if (sdt is SdtRun sdtRun)
+                {
+                    HandleSdtContent(sdtRun, sdtRun.SdtContentRun);
+                }
+                else if (sdt is SdtRow sdtRow)
+                {
+                    HandleSdtRow(sdtRow);
+                }
             }
 
             allContentControls.Clear();
             innerContentControls.Clear();
             firstOrderContentControls.Clear();
         }
+
+        private static void HandleSdtContent(SdtElement sdt, OpenXmlElement content)
+        {
+            if (content != null)
+            {
+                var parent = sdt.Parent;
+                var elementsToMove = content.ChildElements.ToArray(); // Make a copy to avoid modifying the collection during iteration
+                foreach (var elem in elementsToMove)
+                {
+                    parent.InsertBefore(elem.CloneNode(true), sdt);
+                }
+                // Remove the content control itself
+                sdt.Remove();
+            }
+        }
+        private static void HandleSdtRow(SdtRow sdtRow)
+        {
+            if (sdtRow.SdtContentRow != null)
+            {
+                var tableRow = sdtRow.SdtContentRow.GetFirstChild<TableRow>();
+                if (tableRow != null)
+                {
+                    var parent = sdtRow.Parent; // This should be the Table
+                    parent.InsertBefore(tableRow.CloneNode(true), sdtRow);
+                    sdtRow.Remove();
+                }
+            }
+        }
+
     }
 }
\ No newline at end of file
diff --git a/OpenXMLTemplatesTest/ControlRemovalTest/Doc.docx b/OpenXMLTemplatesTest/ControlRemovalTest/Doc.docx
new file mode 100644
index 0000000..f4af6ff
Binary files /dev/null and b/OpenXMLTemplatesTest/ControlRemovalTest/Doc.docx differ
diff --git a/OpenXMLTemplatesTest/ControlRemovalTest/Tests.cs b/OpenXMLTemplatesTest/ControlRemovalTest/Tests.cs
new file mode 100644
index 0000000..2ae53d9
--- /dev/null
+++ b/OpenXMLTemplatesTest/ControlRemovalTest/Tests.cs
@@ -0,0 +1,57 @@
+using System.IO;
+using System.Linq;
+using NUnit.Framework;
+using OpenXMLTemplates;
+using OpenXMLTemplates.ControlReplacers;
+using OpenXMLTemplates.Documents;
+using OpenXMLTemplates.Engine;
+using OpenXMLTemplates.Variables;
+namespace OpenXMLTempaltesTest.ControlRemovalTest
+{
+    public class Tests
+    {
+        private TemplateDocument GetDoc => new TemplateDocument(this.CurrentFolder() + "Doc.docx");
+        private string GetData => File.ReadAllText(this.CurrentFolder() + "data.json");
+
+        [Test]
+        public void TestControlRemoval()
+        {
+            using var doc = GetDoc;
+            var data = GetData;
+
+            var src = new VariableSource();
+            src.LoadDataFromJson(data);
+
+            var engine = new DefaultOpenXmlTemplateEngine
+            {
+                KeepContentControlAfterReplacement = false
+            };
+            engine.ReplaceAll(doc, src);
+
+            doc.SaveAs(this.CurrentFolder() + "result.docx");
+
+            // confirm new content has been included in document
+            string? docText = null;
+
+            using (StreamReader sr = new StreamReader(doc.WordprocessingDocument.MainDocumentPart.GetStream()))
+            {
+                docText = sr.ReadToEnd();
+            }
+
+            Assert.IsTrue(docText != null);
+            var replacedText = src.GetVariable<string>("nested.[1].nestedList.[1]");
+            Assert.IsTrue(docText.Contains(replacedText));
+
+            // confirm controls have been removed
+            Assert.AreEqual(0,
+                doc.WordprocessingDocument.ContentControls().Count(cc =>
+                    cc.GetContentControlTag() != null && cc.GetContentControlTag().StartsWith("repeatingitem")));
+
+            Assert.AreEqual(0,
+                doc.WordprocessingDocument.ContentControls().Count(cc =>
+                    cc.GetContentControlTag() != null && cc.GetContentControlTag() == "repeating_nestedList"));
+
+            doc.WordprocessingDocument.AssertValid();
+        }
+    }
+}
diff --git a/OpenXMLTemplatesTest/ControlRemovalTest/data.json b/OpenXMLTemplatesTest/ControlRemovalTest/data.json
new file mode 100644
index 0000000..c7ade24
--- /dev/null
+++ b/OpenXMLTemplatesTest/ControlRemovalTest/data.json
@@ -0,0 +1,35 @@
+{
+  "items": [
+    "Item 1",
+    "Item 2",
+    "Item 3",
+    "Item 4"
+  ],
+  "complexItems": [
+    {
+      "name": "First Name",
+      "address": "First Address"
+    },
+    {
+      "name": "Second name",
+      "address": "Second address"
+    }
+  ],
+  "nested": [
+    {
+      "name": "List 1",
+      "nestedList": [
+        "item1-1",
+        "item1-2",
+        "item1-3"
+      ]
+    },
+    {
+      "name": "List 2",
+      "nestedList": [
+        "item2-1",
+        "item2-2"
+      ]
+    }
+  ]
+}
\ No newline at end of file
diff --git a/OpenXMLTemplatesTest/ControlRemovalTest/~$Doc.docx b/OpenXMLTemplatesTest/ControlRemovalTest/~$Doc.docx
new file mode 100644
index 0000000..37c76e1
Binary files /dev/null and b/OpenXMLTemplatesTest/ControlRemovalTest/~$Doc.docx differ
diff --git a/OpenXMLTemplatesTest/OpenXMLTemplatesTest.csproj b/OpenXMLTemplatesTest/OpenXMLTemplatesTest.csproj
index f0358e7..2a2c441 100644
--- a/OpenXMLTemplatesTest/OpenXMLTemplatesTest.csproj
+++ b/OpenXMLTemplatesTest/OpenXMLTemplatesTest.csproj
@@ -18,6 +18,12 @@
         <ProjectReference Include="..\OpenXMLTemplates\OpenXMLTemplates.csproj" />
     </ItemGroup>
     <ItemGroup>
+        <None Update="ControlRemovalTest\data.json">
+          <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+        </None>
+        <None Update="ControlRemovalTest\Doc.docx">
+          <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+        </None>
         <None Update="ControlReplacersTests\PictureControlReplacerTests\data.json">
             <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
         </None>