Reputation: 1376
Am trying to append a clone node lets say
<Property Id="3" Name="Deadline"></Property>
into the same document with class name "AlphaCertificationsIndividual"
but the compiler gives me this error: The node to be inserted is from a different document context
<Root>
<Class Name="ECMInstruction" Style="Top">
<Entity Id="1" Name="DocumentInformation" />
<Entity Id="2" Name="CustomerInformation" />
<Property Id="1" Name="DocumentTitle">
</Property>
<Property Id="2" Name="DateCreated">
<Lists>
<ListName>ws_Users</ListName>
<ListName>dfdfdfd</ListName>
</Lists>
</Property>
<Property Id="3" Name="Deadline">
</Property>
</Class>
<Class Name="AlphaCertificationsIndividual" Style="Top">
<Entity Id="1" Name="DocumentInformation" />
<Property Id="1" Name="DocumentTitle">
</Property>
<Property Id="2" Name="DateCreated">
<Lists>
<ListName>ws_Users</ListName>
<ListName>dfdfdfd</ListName>
</Lists>
</Property>
<Property Id="3" Name="Deadline">
</Property>
</Class>
</Root>
the code am using:
XmlDocument xmldoc = new XmlDocument();
xmldoc.Load("sample.xml");
foreach (string id in properties)
{
XmlNode props = xmldoc.DocumentElement.SelectSingleNode("//Class[@Name='" + curClass + "']/Property[@Id='" + id + "']");
XmlNode cloneNode = props.CloneNode(true);
foreach (var item in dcList.SelectedItems)
{
XmlNodeList classes = commonMethods.LoadDocument(xml).DocumentElement.SelectNodes("//Class[@Name='" + item + "']/Property[last()]");
foreach (XmlNode c in classes)
{
String propertyid = c.Attributes["Id"].Value.ToString();
int.TryParse(propertyid, out value);
value = value + 1;
cloneNode.Attributes["Id"].Value = value.ToString();
c.ParentNode.AppendChild(xmldoc.ImportNode(cloneNode,true));
xmldoc.Save("sample.xml");
}
}
}
Upvotes: 0
Views: 2280
Reputation: 3170
I took the liberty of rewriting your code to an extension method which allows you to put in the fileName, originalClassName, newClassName, the name of the node to copy and its ID-attributevalue.
public static bool CopyNode(string fileName, string originalClassName, string newClassName, string nodeName, string ID)
{
XDocument doc = XDocument.Load(fileName);
if(doc == null)
throw new ArgumentNullException("doc");
XElement originalClassElement = doc.Root.Descendants().FirstOrDefault(e => e.Name == "Class" && e.Attribute("Name").Value == originalClassName);
if (originalClassElement == null)
return false;
XElement elementToCopy = originalClassElement.Elements().FirstOrDefault(e => e.Name == nodeName && e.Attribute("Id").Value == ID);
if (elementToCopy == null)
return false;
XElement newClassElement = doc.Root.Descendants().FirstOrDefault(e => e.Name == "Class" && e.Attribute("Name").Value == newClassName);
if (newClassElement == null)
return false;
newClassElement.Add(elementToCopy);
doc.Save(fileName);
return true;
}
The method returns true if the node has been copied correctly. You have gained some extensibility and can copy nodes to and from classes with any names; and also any nodes you want to copy (note that they do have to have an ID).
Upvotes: 0
Reputation: 66
I'm not sure if it's a typo, but it seems that you are calling the commonMethods.LoadDocument method on a variable called xml and get classes variable. Then, ImportNode is being called on the xmlDoc before appending. Node needs to be imported into the document object that the child will be appended to. So, you should be importing into xmlDoc, if you want to append to xmlDoc.
Upvotes: 1