How to dynamically change attribute of an xml node with c# - 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";

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.

How do you cycle through nodes in XML file [duplicate]

This question already has answers here:
Reading Xml with XmlReader in C#
(7 answers)
Closed 6 years ago.
I have an XML file and the structure is roughly like this:
<ScenarioList>
<Scenario>
... various things
</Scenario>
</ScenarioList>
This is being read into a WPF dialog box. Every time the user selects 'Next' I want to read the next Scenario data into the various fields. Obviously, the same thing goes for the user clicking on the 'Last' button, too.
But the question is: how do i just read in the information from the selected Scenario node?
Let me to try and clarify the question since it appears that it is 'overly broad':
I am familiar with loading and reading entire XML files. I just want to selectively read specific nodes. For example: How can I read just the data for the first Scenario node? Then, depending on user input, read just the data for the second Scenario node? Then, depending on user input, read just the data for the first scenario node? Or just the third scenario node?
In essence, I'm asking since XML doesn't have an 'index' how do I specify which instance of a node to read?
First you need to load the xml into an XmlDocument, then you can select the specific nodes and iterate over them, like this:
XmlDocument xml = new XmlDocument();
xml.LoadXml("your xml");
XmlNodeList list = xml.SelectNodes("/ScenarioList/Scenario");
foreach (XmlNode xn in list)...
You can traverse to node by using JXPath.
If you need to evaluate multiple paths relative to a certain node in the object graph, you might want to create a relative JXPathContext.
First, obtain the pointer for the location that is supposed to be the root the relative context. Then obtain the relative context by calling
JXPathContext context = JXPathContext.newContext(bean);
Pointer addressPtr = context.getPointer("/employees[1]/addresses[2]");
JXPathContext relativeContext =
context.getRelativeContext(addressPtr);
// Evaluate relative path
String zipCode = (String)relativeContext.getValue("zipCode");
// Evaluate absolute path
String name = (String)relativeContext.getValue("/employees[1]/name");
// Use the parent axis to locate the employee for the current address
Double salary = (Double)relativeContext.getValue("../salary");
you can refer in more detail from here

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

Copy an existing XML element into the same document

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.

+ 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