0

I need a function that can remove all child nodes of some specific node. But only child nodes, not an attributes also. There is standard function in System.XML to remove all childs but it also removes all attributes that I have.

In result I write my own funcrtion that takes as parameters xmlDocument, my parent node (sector), and bool variable toRemoveAttributes. In this case I takes all attributes to one XmlAttributeCollection and then use RemoveAll function.

public void RemoveChild(XmlDocument xd, string sectorName, bool removeAttributes)
{
    XmlElement sector;
    if (sectorName == "root")
        sector = xd.DocumentElement;
    else
        sector = (XmlElement)xd.GetElementsByTagName(sectorName)[0];

    XmlAttributeCollection atr = sector.Attributes;            
    sector.RemoveAll();
    if(!removeAttributes)
    {
        for (int i = 0; i < atr.Count; i++)
            sector.SetAttribute(atr[i].Name, atr[i].Value);
    }
}

In result my attributes is still removed. When I debugged my code i saw that after RemoveAll() also everything is deleted from my 'atr' colection.

Deduplicator
  • 44,692
  • 7
  • 66
  • 118
pad0n
  • 187
  • 3
  • 17

1 Answers1

0

The answer and solution are already provided here:
How to remove all child nodes of an XmlElement, but keep all attributes?.


I just want to add a couple notes about your specific situation.

Garath provided a detailed explanation, including what that call is doing internally:

// Removes all specified attributes and children of the current node.
// Default attributes are not removed.
public override void RemoveAll()
{
    base.RemoveAll();
    this.RemoveAllAttributes();
}

Since your atr variable is referencing sector.Attributes, and the previous method just removed the attributes from sector, atr no longer has the attributes either. So atr.Count == 0 and the loop never runs. You could try verifying this by placing a breakpoint on sector.SetAttribute... and see if it's getting hit.

See the other answer in that question for a solution you could use instead.


There are a couple other calls you could make that would have a similar effect to RemoveAll without calling RemoveAllAttributes, but there may be unintended side-effects, so I'd stick with the answer in the other post.

sector.InnerXml = "";

Or:

sector.IsEmpty = true;
Community
  • 1
  • 1
Grant Winney
  • 65,241
  • 13
  • 115
  • 165