Zkratka XML znamená eXtensible Markup Language. Jedná se o textový formát určený k ukládání a výměně strukturovaných dat. Je čitelný pro člověka i pro stroj a historicky se stal velmi rozšířeným standardem zejména pro přenos dat mezi systémy (např. webové služby, konfigurace, dokumenty).

Vychází z jazyka SGML (Standard Generalized Markup Language). Je velmi podobný jazyku HTML, který také vychází z SGML.

XML schéma je možné validovat pomocí XSD, DTD nebo RelaxNG.

Podoba XML

XML ukládá data ve formě značek (tagů), které ohraničují obsah. Struktura připomíná stromový model, kde každý prvek může mít další vnořené prvky.

<Person>
  <Name>Alice</Name>
  <Age>30</Age>
  <City>Praha</City>
</Person>

Data mohou být vyjádřena:

  • elementy (tagy) – obsahují další data nebo text
  • atributy – připojují metadata k elementu
  • textový obsah – přímo uvnitř elementu

Ukázka

<Person Name="Alice" Age="30" City="Praha" />
 
<!--Ekvivalentně-->
<Person>
  <Name>Alice</Name>
  <Age>30</Age>
  <City>Praha</City>
</Person>
  • První řádek je takový, že takto XML spíše tvoří lidé
  • Druhá varianta je typická pro strojově tvořené XML

Výhody a Nevýhody

  • ✅ čitelný formát s pevnou strukturou
  • ✅ možnost definovat schéma (XSD) a kontrolovat formát dat
  • ✅ podporován mnoha nástroji (editory, validátory…)
  • ✅ možnost komentářů přímo v souboru
  • ❌ větší objem dat (delší zápis než JSON)
  • ❌ práce s XML bývá složitější (nutnost parsování komplikované stromové struktury)

Práce s XML v .NET

V .NET existuje několik způsobů, jak pracovat s XML. Mezi nejběžnější patří:

  • XmlDocument – klasický objektový model pro načítání a úpravy XML stromu.
  • XDocument (LINQ to XML) – modernější přístup, jednodušší práce s XML pomocí LINQ.
  • XmlSerializer – umožňuje serializaci/deserializaci objektů přímo do XML.

Ukázka práce s XDocument

Model (třída)

public class Person
{
    public required string Name { get; set; }
    public required int Age { get; set; }
    public required string City { get; set; }
}

Serializace

using System.Xml.Linq;
 
var fileName = "people.xml";
var people = new List<Person>
{
    new Person { Name = "Alice", Age = 30, City = "Praha" },
    new Person { Name = "Bob", Age = 25, City = "Brno" }
};
 
var root = new XElement("People");
 
foreach (var person in people)
{
    var personElement = new XElement("Person");
 
    var nameElement = new XElement("Name", person.Name);
    var ageElement = new XElement("Age", person.Age);
    var cityElement = new XElement("City", person.City);
 
    personElement.Add(nameElement);
    personElement.Add(ageElement);
    personElement.Add(cityElement);
 
    root.Add(personElement);
}
 
var doc = new XDocument(root);
doc.Save(fileName);

Výsledný obsah souboru people.xml:

<People>
  <Person>
    <Name>Alice</Name>
    <Age>30</Age>
    <City>Praha</City>
  </Person>
  <Person>
    <Name>Bob</Name>
    <Age>25</Age>
    <City>Brno</City>
  </Person>
</People>

Warning

Ukázka pro zjednodušení neřeší správné ošetření výjimek. To je pro zajištění stability aplikace při práci se soubory na disku klíčové. Více v Výjimky.

Deserializace

using System.Xml.Linq;
 
var fileName = "people.xml";
var doc = XDocument.Load(fileName);
 
var people = new List<Person>();
 
var root = doc.Element("People");
 
if (root is null)
{
	Console.WriteLine("No people present in the document.");
	return;
}
 
foreach (var personElement in root.Elements("Person"))
{
	var nameElement = personElement.Element("Name");
	var ageElement = personElement.Element("Age");
	var cityElement = personElement.Element("City");
 
	var person = new Person
	{
		Name = nameElement != null ? nameElement.Value : "",
		Age = ageElement != null ? int.Parse(ageElement.Value) : 0,
		City = cityElement != null ? cityElement.Value : ""
	};
 
	people.Add(person);
}
 
foreach (var person in people)
{
    Console.WriteLine($"{person.Name} ({person.Age}) z města {person.City}");
}

Warning

Ukázka pro zjednodušení neřeší správné ošetření výjimek. To je pro zajištění stability aplikace při práci se soubory na disku klíčové. Více v Výjimky.