Adding an attribute to xml document child node using linq - c#

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

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"

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

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.

Add XMl attributes if not exist using Xpath Navigator

I want to add attributes only when it is not exist.
Check out: http://egeveke.blogspot.com/2006/09/xpathnavigator-missing-setattribute.html
Basically you use MoveToAttribute, testing if it was successful. If not, then it does not exist and you can create. Remember to either start with a clone of you navigator, or move back to the parent when you are successful.
if (nav.MoveToAttribute())
{
// exists
nav.MoveToParent();
}
else
{
nav.CreateAttribute(...);
}
Check out Insert XML Data using XPathNavigator. Specifically the section Inserting Attribute Nodes
Use "HasAttributes" property on the Xpathnavigator object to check whether it has any attributes and then continue to do your operation. Hope this helps!!

Categories