Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to remove an XmlNode from XmlNodeList

Tags:

c#

xml

This should do the trick for you:

for (int i = nodeList.Count - 1; i >= 0; i--)
{
    nodeList[i].ParentNode.RemoveChild(nodeList[i]);
}

If you loop using a regular for-loop, and loop over it "backwards" you can remove items as you go.

Update: here is a full example, including loading an xml file, locating nodes, deleting them and saving the file:

XmlDocument doc = new XmlDocument();
doc.Load(fileName);
XmlNodeList nodes = doc.SelectNodes("some-xpath-query");
for (int i = nodes.Count - 1; i >= 0; i--)
{
    nodes[i].ParentNode.RemoveChild(nodes[i]);
}
doc.Save(fileName);

You can not easily use iterators (foreach-statement) to delete your nodes. As I see it you can do the following:

1) In your foreach-loop, save a list of all elements that should be removed. Then you loop through just those elements and remove them.

2) Use an ordinary for-loop and keep track of which is the next element to visit after you have deleted one item.

Edit: When using a for-loop do it the way Fredrik suggests, looping backwards.


If you're trying to remove a node from the XML DOM, this isn't the correct way. Because an XMLNodeList is just a list of nodes. Rather you want to remove the node from the parent node. Like this:

XmlNode parentNode = // some value
XmlNode drawNode = // some value
parentNode.ParentNode.RemoveChild(drawNode);

Isn't the following a little simpler:

XmlDocument doc = new XmlDocument(); 
doc.Load(fileName); 
XmlNodeList nodes = doc.SelectNodes("some-xpath-query"); 
while (nodes.FirstChild != null) {     
    nodes.RemoveChild(nodes.FirstChild); 
} 
doc.Save(fileName); 

Seems to me you're trying to just remove an entire XML Element...

If this is your XML...

<Xml1>
  <body>
    <Book>
      <Title name="Tom Sawyer" />
      <Author value="Mark Twain" />
    </Book>
    <Book>
      <Title name="A Tale of Two Cities" />
      <Author value="Charles Dickens" />
    </Book>
  </body>
</Xml1>

If you wanted to delete a book, you need to grab the first <Book> node. You can do that with:

XmlDocument doc = new XmlDocument();
doc.Load(fileName);

XmlNodeList nodes = doc.GetElementsByTagName("body");
XmlNode bodyNode = nodes[0];
XmlNode firstBook = bodyNode.ChildNodes[0];

Once you have the "first book" node, you can delete that from the body node using:

bodyNode.RemoveChild(firstBook);

This will automatically affect/update the XML Document variable, so doc will now only have:

<Xml1>
  <body>
    <Book>
      <Title name="A Tale of Two Cities" />
      <Author value="Charles Dickens" />
    </Book>
  </body>
</Xml1>

If you want to grab and delete the whole body, you should be able to do:

XmlNodeList xml1 = doc.GetElementsByTagName("Xml1");
XmlNode xmlNode = xml[0];
xmlNode.RemoveChild(bodyNode);

And the doc variable will be updated to no longer contain the body element, and can then be resaved to the file system:

doc.Save(fileName);

Where fileName is the full path to the XML Document on your computer.

Best of all, we aren't using doc.SelectNodes(), so we don't need to worry about using an XMLNamespaceManager.