1

I have a very frustrating issue which I'm hoping will actually be something extremely simple. Apologies in advance if my terminology in XML files is wrong.

Basically I have a fairly simple XML file, here is an extract of one node:

<Attr num="108" name="Title" desc="The title of this file." type="s" ord="1" value="Test Title">

I can read and write the value key of the node fairly easily, but only if the value key exists.

I can use this code to write values back to the file:

XmlNode node = xmlDoc.SelectSingleNode("//ma:Attr[@name='Title']/@value", ns);
node.Value = partname.Text;
xmlDoc.Save(sympath);

However, if the XML file has the node of the correct name, but does not have a value key then it fails. For example, in some files the XML looks like this:

<Attr num="108" name="Title" desc="The title of this file." type="s" ord="1">

So I'm going round and round in circles just trying to add value="something" to that node if it doesn't already exist. Is there a way to do this? I can add child elements, but I just want to add the value in that string!

I have tried searching for an answer, but all the other similar issues seem to be about adding or modifying child elements.

Thank you,
Andrew

Manfred Radlwimmer
  • 13,257
  • 13
  • 53
  • 62
Andrew Taylor
  • 145
  • 13
  • If I understand you right you want to create the attribute _value_ if it doesn't exist. If that is the case take a look at [this answer](https://stackoverflow.com/a/883234/5638825) – Prajnan Bhuyan Feb 08 '18 at 08:55
  • Possible duplicate of [How to add a node to XML in C#?](https://stackoverflow.com/questions/9192495/how-to-add-a-node-to-xml-in-c) – skyfoot Feb 08 '18 at 09:50

1 Answers1

2

Actually, XmlElement.SetAttribute() alone did the job :

var node = (XmlElement)xmlDoc.SelectSingleNode("//ma:Attr[@name='Title']", ns);
node.SetAttribute("value", partname.Text);

Select parent element instead of the attribute, check if value attribute exists in that element and take action accordingly i.e add attribute or just update the value :

var node = (XmlElement)xmlDoc.SelectSingleNode("//ma:Attr[@name='Title']", ns);
var attr = node.Attributes["value"];
if(attr != null)
{
    attr.Value = partname.Text;
}   
else 
{
    node.SetAttribute("value", partname.Text);
}
har07
  • 88,338
  • 12
  • 84
  • 137
  • looks like some great code, but i can't get it to work. Firstly I get an error because the var attr is null if value doesn't exist. Also, I don't see node.setattribute. I have tried using XmlAttribute... – Andrew Taylor Feb 08 '18 at 09:40
  • @AndrewTaylor sorry, `node` should be of type `XmlElement`. If there is a possibility of `SelectSingleNode` returning `null` then you'll need to check the return value first before casting to `XmlElement`... – har07 Feb 08 '18 at 09:49
  • ok that is almost working now. I'm having trouble if value doesn't exist still. I've tried using if node.hasattribute("value"), but it's still returning null and throwing up an error. Any more pointers?! Sorry to be a pain – Andrew Taylor Feb 08 '18 at 10:53
  • The code in this answer does the check already, so I'm not sure how you adapted this code. Hopefully live demo can help you to understand better: https://dotnetfiddle.net/Dht4FC – har07 Feb 08 '18 at 10:57
  • Ah, actually you can just call `SetAttribute()` without checking if the attribute exists first... answer updated.. and the demo as well – har07 Feb 08 '18 at 11:02
  • brilliant, thank you! Was my fault. Forgot to include the namespace so it was throwing exceptions! – Andrew Taylor Feb 08 '18 at 11:56