Как сделать копию узла XML со всеми его дочерними узлами и значениями, но с другим именем С# .NET

Я пытаюсь сделать копию узла XML и всех его дочерних узлов, но с другим именем родительского узла XML, но выдает ошибку, это файл xml:

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

То, что я пытаюсь сделать, это копия MyServer со всеми их дочерними узлами и значениями, но с другим именем... что-то вроде этого

<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>

Я сделал следующее:

 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);            
 }

Исключение: в этом документе уже есть узел DocumentElement.

Есть идеи?


person Javier Salas    schedule 23.03.2016    source источник


Ответы (1)


Линия

xmldoc.AppendChild(deep);   

пытается добавить элемент в XmlDocument. Это означает, что он пытается добавить элемент корневого уровня. Проблема в том, что в вашем документе уже есть элемент корневого уровня (Серверы) и он не может добавить еще один, поэтому вы получаете исключение.

Другая проблема с вашим кодом заключается в том, что в строке

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

вы пытаетесь заменить имя сервера новым именем. К сожалению, InnerXml выглядит так:

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

поэтому имя вашего сервера никогда не заменяется.

Чтобы устранить проблемы, вы можете попробовать другой подход:

// 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);

Это должно дать вам нужный результат

person dotnetom    schedule 23.03.2016