0

In the following snippet the final string "removed" still has the deleted elements. I am converting to byte[] first because the final implementation input will be in that form. I am looping thru the saved nodes and deleting them for element document. What gives? All ideas greatly appreciated.

        static void Main(string[] args)
        {
            var str =
                    @"
<CustomerCareReport xmlns='http://schemas.datacontract.org/2004/07/Foo.Bar.Frameworks.Reporting.Stack.Infrastructure.DataObjects.FireEms' xmlns:i='http://www.w3.org/2001/XMLSchema-instance'>
  <OtherInformation>
    <Documents xmlns:a='http://schemas.datacontract.org/2004/07/Foo.Bar.Frameworks.Reporting.Stack.Infrastructure.DataObjects.Documents'>
      <a:Document>
        <a:Contents>Z2dn</a:Contents>
        <a:Description>yoyo</a:Description>
          <a:Id>1</a:Id>
      </a:Document>
      <a:Document>
        <a:Contents>ZmhmaA0KZmZmDQpmamZqZmpmDQo=</a:Contents>
        <a:Description>test 2</a:Description>
          <a:Id>2</a:Id>
      </a:Document>
    </Documents>
  </OtherInformation>
</CustomerCareReport>
";
            var element = XElement.Parse(str);
            XNamespace ns = element.Name.Namespace;
    // convert to bytes firstbecause final implementation input is byte array  
            byte[] bytes = Encoding.ASCII.GetBytes(str);
            using (var stream = new MemoryStream(bytes))
            {
                var deleteMarked = new List<XElement>();
                var xelement = XElement.Load(stream);

                var docs = xelement
                        .Descendants(ns + "Documents");

                foreach (XElement doc in docs.Descendants())
                {
                    if (doc.Name.LocalName.Equals("Document"))
                    {
                        var delDoc = doc;
                        deleteMarked.Add(delDoc);
                    }
                }

                foreach (var deldoc in deleteMarked)
                {
                    foreach (var node in deldoc.Elements())
                    {
                        node.Remove();
                    }
                }
                if (deleteMarked.Count > 0)
                {
                    stream.Close();
                    bytes = stream.ToArray();
                }
                var removed = System.Text.Encoding.Default.GetString(bytes);
                Console.WriteLine(removed);
            }
        }
  • Possible duplicate of [How to delete node from XML file using C#](https://stackoverflow.com/questions/919645/how-to-delete-node-from-xml-file-using-c-sharp) – MethodMan May 25 '17 at 14:35
  • Please reduce this to a [mcve]. We don't need huge amounts of XML - just enough to demonstrate the problem. – Jon Skeet May 25 '17 at 14:38
  • 1
    It's not clear how you expect `bytes` to change though... after removing nodes, you don't do anything with the document. – Jon Skeet May 25 '17 at 14:39
  • Never delete inside a for loop that increments. When you delete an item in a list the next item gets skipped. So remove in reverse : for(int i = deldoc.Elements().Count() - 1; i >= 0; i--){deldoc.Elements[i].Remove;} – jdweng May 25 '17 at 15:04
  • 1
    I think the key thing you're missing is the fact that when you deserialize and object from a memory stream, operations made to that object will be done independently of the stream. If you want the changes to the object to reflect the stream, you need to write it back to that stream. – Jeff Mercado May 27 '17 at 16:28

0 Answers0