XML file creation using XDocument in C#

C#XmlLinq to-Xml

C# Problem Overview


I have a List<string> "sampleList" which contains

Data1
Data2
Data3...

The file structure is like

<file>
   <name filename="sample"/>
   <date modified ="  "/>
   <info>
     <data value="Data1"/> 
     <data value="Data2"/>
     <data value="Data3"/>
   </info>
</file>

I'm currently using XmlDocument to do this.

Example:

List<string> lst;
XmlDocument XD = new XmlDocument();
XmlElement root = XD.CreateElement("file");
XmlElement nm = XD.CreateElement("name");
nm.SetAttribute("filename", "Sample");
root.AppendChild(nm);
XmlElement date = XD.CreateElement("date");
date.SetAttribute("modified", DateTime.Now.ToString());
root.AppendChild(date);
XmlElement info = XD.CreateElement("info");
for (int i = 0; i < lst.Count; i++) 
{
    XmlElement da = XD.CreateElement("data");
    da.SetAttribute("value",lst[i]);
    info.AppendChild(da);
}
root.AppendChild(info);
XD.AppendChild(root);
XD.Save("Sample.xml");

How can I create the same XML structure using XDocument?

C# Solutions


Solution 1 - C#

LINQ to XML allows this to be much simpler, through three features:

  • You can construct an object without knowing the document it's part of
  • You can construct an object and provide the children as arguments
  • If an argument is iterable, it will be iterated over

So here you can just do:

void Main()
{
	List<string> list = new List<string>
	{
		"Data1", "Data2", "Data3"
	};

	XDocument doc =
	  new XDocument(
		new XElement("file",
		  new XElement("name", new XAttribute("filename", "sample")),
		  new XElement("date", new XAttribute("modified", DateTime.Now)),
		  new XElement("info",
			list.Select(x => new XElement("data", new XAttribute("value", x)))
		  )
		)
	  );

	doc.Save("Sample.xml");
}

I've used this code layout deliberately to make the code itself reflect the structure of the document.

If you want an element that contains a text node, you can construct that just by passing in the text as another constructor argument:

// Constructs <element>text within element</element>
XElement element = new XElement("element", "text within element");

Solution 2 - C#

Using the .Save method means that the output will have a BOM, which not all applications will be happy with. If you do not want a BOM, and if you are not sure then I suggest that you don't, then pass the XDocument through a writer:

using (var writer = new XmlTextWriter(".\\your.xml", new UTF8Encoding(false)))
{
    doc.Save(writer);
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionThorin OakenshieldView Question on Stackoverflow
Solution 1 - C#Jon SkeetView Answer on Stackoverflow
Solution 2 - C#guestuserView Answer on Stackoverflow