How to make a copy of a XML node with all their child nodes and values but different name C# .NET

12,386

The line

xmldoc.AppendChild(deep);   

tries to append an element to an XmlDocument. This means that it is trying to add a root level element. The issue is that your document already has root level element (Servers) and it cannot add another one, so you get an exception.

Another issue with your code is that in line

deep.InnerXml = deep.InnerXml.Replace(ServerToCopy, NewServer);

you are attempting to replace the name of the server with the new name. Unfortunatelly InnerXml looks like this:

<Host>0.0.0.0</Host>
<Port>12</Port>
<User>USER</User>

so your server name is never replaced.

To fix the issues you can try different approach:

// Fint the node you want to replace
XmlNode NodeToCopy = xmldoc.SelectSingleNode("Servers/" + ServerToCopy);

// Create a new node with the name of your new server
XmlNode newNode = xmldoc.CreateElement(NewServer);

// set the inner xml of a new node to inner xml of original node
newNode.InnerXml = NodeToCopy.InnerXml;

// append new node to DocumentElement, not XmlDocument
xmldoc.DocumentElement.AppendChild(newNode);

This should give you the result you need

Share:
12,386
Javier Salas
Author by

Javier Salas

I like to learn, travel and discover new things and places. Music is my passion and programming has become one of the things that I like to do!

Updated on June 04, 2022

Comments

  • Javier Salas
    Javier Salas almost 2 years

    I'm trying to make a copy of a XML node and all their child nodes but different XML parent node name, but is throwing me an error, this is the xml file:

    <Servers>
      <MyServer>
        <Host>0.0.0.0</Host>
         <Port>12</Port>
         <User>USER</User>
      </MyServer>
    </Servers>
    

    What I'm trying to do is a copy of MyServer with all their child nodes and values but different name... something like this

    <Servers>
      <MyServer>
        <Host>0.0.0.0</Host>
         <Port>12</Port>
         <User>USER</User>
      </MyServer>
      <MyCopyofMyServer>
        <Host>0.0.0.0</Host>
         <Port>12</Port>
         <User>USER</User>
      </MyCopyofMyServer>
    </Servers>
    

    What I did was this:

     public void CopyInterface(string NewServer, string ServerToCopy)
     {
        xmldoc.Load(XMLInterfacesFile);
        XmlNode NodeToCopy = xmldoc.SelectSingleNode("Servers/" + ServerToCopy);
        XmlNode deep = NodeToCopy.CloneNode(true);    
        deep.InnerXml = deep.InnerXml.Replace(ServerToCopy, NewServer);
        xmldoc.AppendChild(deep);   //Throwing an exception here!
        xmldoc.Save(XMLInterfacesFile);            
     }
    

    Exception: This document already has a 'DocumentElement' node.

    Any Idea?