简体   繁体   中英

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

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?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM