Search code examples
c#winformslinq-to-xmlxelement

What is the proper way to retrieve a value from a single, nested, XElement?


To retieve the value of a nested XElement I have the following in my code:

XElement xml = new XElement("UserDefinedSettings", new XElement("RootFolder", new XElement("FolderName", "User Input Goes Here")));

xml.Save("UserDefinedSettings.xml");

Which gives me this saved to the hard drive:

<?xml version="1.0" encoding="utf-8"?>
<UserDefinedSettings>
  <RootFolder>
    <FolderName>User Input Goes Here</FolderName>
  </RootFolder>
</UserDefinedSettings>

Later, To retrieve the name of the folder that the user has chosen I am using:

XDocument xdoc = XDocument.Load("UserDefinedSettings.xml");

var myVar = xdoc.Descendants("FolderName").Single();

textBox1.Text = myVar.Value;

I am new to Linq-XML and I am wondering if what I have done is the right way to go about it?

Initially I had been using the following line of code to get the name of the folder, but I knew there had to be a better way and after searching here on SO for examples I am using the code above instead.

string s =xdoc.Element("UserDefinedSettings").Element("RootFolder").Element("FolderName").Value;

Solution

  • What you have should be fine (the newer way), as long as you are certain those elements exist. It runs the risk of throwing a null reference exception however if any of them do not exist. I typically query with Elements() rather than Element(). Elements() returns an IEnumerable which you can safely chain together with more Elements() queries (or whatever). For example, you might consider:

    var folder = (string)xdoc.Elements("UserDefinedSettings").Elements("RootFolder").Elements("FolderName").FirstOrDefault();
    

    Another thing I typically do when I want the value from an attribute or element is cast my XElements and XAttributes with a string as I did above. A null value cast as a string will return a null string, preventing a null reference exception that you would get with a .Value call.