Copy an existing XML element into the same document - c#

I am building up an XML document using c#. I use AppendChild to add an element called say "test" to a parent element in the document.
I then build up more of the xmlDocument but further down the same document I wish to append the same element "test" to a different node.
I have tried using AppendChild but it added it to the new node and removed it from the existing one. Which I guess is expected. I was just wondering is there anything available that I can use to copy the existing element and add it to a new node without removing it from the existing position?
To perhaps help explain the following code results in the test element only appearing in parentElement2.
parentElement1.AppendChild(test)
...
parentElement2.AppendChild(test)
Is there anyway I can insert test into both parent elements?
Hope this makes sense.

This should be possible with the CloneNode method. It lets you create a (possibly deep) copy of a node, which you can then insert wherever you like in your document.

Related

How to insert the new element on XMLNode in C#

I am trying to insert a new element into the XmlNode in C# code,
How to insert the <delimiter>##<delimiter> element in inside the "/TestBooks/template/field" root. (Screenshot1)
enter image description here
Inside the <field> element, i need to insert the <delimiter> element, based on id element <Id>11-09-2020-505</Id>. (Screenshot2)
enter image description here
First of all you really shouldn't use pictures in questions -- we are taking the time to type you an answer you can take the time to use copy and paste and format your questions.
I'd like to answer your questions but I'm concerned about the questions because it implies that you are adding in markers to aid in the parsing of the data. You really shouldn't need to parse XML.
There are many great parsers of XML including one built into C# you should not roll your own.
In the XML standard the order of the children not defined. If you put a child as the "first" child, there is no reason to expect that a parser would list it as first.
(To have order in children you should just add an order attribute)
Because of these reason it should not matter where in the list of children you add the child.
So we can tell you how to add a child but we can't "put it in a specific spot" since children don't have an order.
In summary, it is not possible to do what you ask.

Recreating XML but passing variable into the data

I am trying to Create an XML with the below format but keep having issues. I am new to both c# and XML and hit a brick wall on this one. The reference XML i have is this
<workspace name="Remote Apps" xmlns="http://schemas.microsoft.com/ts/2008/09/tswcx" xmlns:xs="http://www.w3.org/2001/XMLSchema">
<defaultFeed url="CHANGEME" />
</workspace>
I need to be able to recreate this file with the adjustment of the url Value. I have tried loading this XML on its own and the alter the value and also tried to recreate from scratch. Both i have hit a blank wall.
Last attempt to do this was
XDocument doc = XDocument.Load("cloud.xml");
var element = doc.Elements("defaultFeed")
.Single(x => x.Attribute("url").Value == "ChangeMe");
element.SetAttributeValue("url", fullurl);
doc.Save(CloudFileLocation);
If someone would be kind enough to help me out with this either writing from scratch or altering the code from a local file i would appreciate it. (Create from scratch would be preferred)
There are three probems with your code:
doc.Elements("defaultFeed") searches for an element named defaultFeed as child of the document. Your element is however a child of the root node workspace.
Solution: change to
doc.Root.Elements("defaultFeed")
This attribute xmlns="http://schemas.microsoft.com/ts/2008/09/tswcx" says that all elements where the namespace is not explicitely specified, are in the namespace http://schemas.microsoft.com/ts/2008/09/tswcx. Elements("defaultFeed") however searches for elements without any namespace.
Solution: change to
XNamespace tswcx = "http://schemas.microsoft.com/ts/2008/09/tswcx";
doc.Root.Elements(tswcx + "defaultFeed")
The third one is a simple typo: You should compare to "CHANGEME", not to "ChangeMe"

Adding an attribute to xml document child node using linq

I'm trying to create an element and defining the path to the xml document, one of my tries was:
XElement main = XElement.Load(xmlpath);
Then i tried to select the existing element that I want to add an attribute
main.XPathSelectElement("/Row/ip_addresses").SetAttributeValue("id", sp_range.ToString());
Las tried these both
main.XPathSelectElement("/Row/ip_addresses").ReplaceAttributes("id", sp_range.ToString());
There is no errors presented in this code just nothing happens to the xml document and the existing Element, the existing child element is and the Parent is I am using Xpath to navigate to the child element that I want to add attribute to that don't exist according to Linq we are supposed to be able to change attributes that exist or don't exist and change ElementTags that exist or create Elements that don't exist.
Please any advise would help
You don't appear to be persisting/saving the changes...
Try the XElement.Save method
You are selecting from "Row" which doesn't exist under the current element. Current element itself is the "Row". As such, you need to select from the root "/ip_addresses", not from "/Row/ip_addresses".
main.XPathSelectElement("/ip_addresses").SetAttributeValue("id",sp_range.ToString()));

How to dynamically change attribute of an xml node with c#

I have a c# application that saves user's data to an xml document. I want to be able to dynamically change the attribute of an xml node based on a user entering different criteria into a text box and choosing to save/overwrite the existing file save. The problem is that I can't simply delete the node and recreate it with the new attribute as the node has child nodes that can't be deleted.
Does anyone have any ideas or suggestions?
the XmlNode.Attributes method does not provide a way as I can tell to delte just the attribute of a node and reassign it. I could be wrong though.
Cast your node to an XmlElement and use the element.SetAttribute(...); method.
((XmlElement)node).SetAttribute("name", "value");
Also I believe there is a way to do it without the cast if you know the attribute already exists:
node.Attributes["name"].Value = "value";

+ sign in front of a tree node

hI,
I am working with a treeview in C# using visual studio 2005 and want to find a tree node and add nodes below it upon a button being pressed in my windows forms application.
I have tried using treeView1.Nodes.Find("My_Text", true);
where "My_Text" is the text associated with the node under which i want to add mode nodes.
However I cannot find a way to use this to my advantage as I dont know what this statement returns.
I ntend to use treeView1.SelectedNode.Nodes.Add(newnode); to add nodes but for that I need to select a node first. And treeView1.Nodes.Find does not look likt it selects the node for me. Any help?
Are you sure that a node with give text exists in your application? I just tried a simple test application and the Find method worked without problems...
private void button1_Click(object sender, EventArgs e) {
// WARNING: add checks
TreeNode[] nodes = treeView1.Nodes.Find("Node2",true);
TreeNode node = nodes[0];
node.Nodes.Add("child node");
}
Do you need to use SelectedNode.Nodes.Add()? The Nodes.Add(...) operation can be performed on any TreeNode. So, if you can find the node at all, simply call node.Nodes.Add(..). You don't need to select it first.
Have a look at the documentation or intellisense information to see what the Find() method returns.
treeView1.Nodes.Find() returns an array of TreeNode objects. If you are sure there is one and only one such node, you can do this:
var node = treeView1.Nodes.Find("My_Text", true)[0];
node.Nodes.Add(newnode);
If there can be more than one such node, you need some other way to disambiguate first. And if there can be no such node, you need to add some error checking in there as well.
TreeView.Nodes.Find returns an array of nodes that match the string you specified. You can then use the Add method on the nodes to add sub-nodes, obviously if you have more than 1 node in the array then you have a non-unique situation so if you were looking for a specific node you'd need more information on which to identify it.

Categories