YAML Ain't Markup Language (YAML)
Eintrag zuletzt aktualisiert am: 12.06.2019
YAML ist ein textbasiertes
Datenformat in Form einer Auszeichnungssprache. Eine Auszeichnungssprache (englisch Markup Language) ist laut [
https://de.wikipedia.org/wiki/Auszeichnungssprache] eine maschinenlesbare Sprache für die Gliederung und Formatierung von Texten und anderen Daten. Bekanntere Auszeichnungssprachen sind HTML,
XML und
JSON. YAML zeichnet sich gegenüber HTML,
XML und
JSON dadurch aus, dass es kompakter und übersichtlicher ist; daher ist es nicht nur für Maschinen, sondern auch für Menschen gut lesbar.
Einsatzgebiete von YAMLYAML wird inzwischen an einigen Stellen als Konfigurationsformat eingesetzt, z.B. in Docker, Kubernetes und seit 2019 auch in Azure DevOps-Pipelines zur Definition von Continous Integration- und Continous Delivery-Prozessen. Grundsätzlich kann YAML aber nicht nur für Konfigurationsdateien, sondern als beliebiges Datenformat eingesetzt werden, auch als Ersatz für XML und JSON.
Es gibt zahlreiche Softwarekomponenten zur Serialisierung von Objektmodellen in YAML bzw. der Deserialisierung von YAML in Objektmodellen in zahlreichen Programmiersprachen und Frameworks, z.B. C, C++, Ruby, Python, Java, Perl, .NET, PHP, Dart, JavaScript (siehe [https://yaml.org/]).
Name YAMLDie Abkürzung YAML stand ursprünglich für "Yet Another Markup Language". Mittlerweile verwendet man YAML als rekursive Abkürzung für "YAML Ain’t Markup Language".
VersionenDie erste Version der YAML-Sepzifikation von Oren Ben-Kiki, Clark Evans und Brian Ingerson stammt bereits vom 29.2.2004 [https://yaml.org/spec/1.0/]
Version 1.1: 18.1.2005 [https://yaml.org/spec/1.1/]
Version 1.2: 10.1.2009 [https://yaml.org/spec/1.2/spec.html]
Websitehttps://yaml.org
YAML-Parser für .NEThttps://github.com/aaubry/YamlDotNet
Microsoft selbst liefert in .NET Framework und .NET Core noch keine YAML-Bibliothek mit. Diese Lücke füllt das Github-Projekt YamlDotNet [https://github.com/aaubry/YamlDotNet]. Die kompilierte Bibliothek gibt es auf Nuget [https://www.nuget.org/packages/YamlDotNet/]. Die erste dort veröffentlichte Version war 2013, seitdem sind zahlreiche Versionen erschienen. Die aktuelle Version zum Zeitpunkt der Erstellung des Beitrags ist 6.1.1 vom 4.6.2019. YamlDotNet basiert auf .NET Standard 1.3, läuft daher in .NET Core ab Version 1.0 und .NET Framework ab Version 4.5 sowie Mono und Unity. Die Installation in einem Projekt erfolgt mit Install-Package YamlDotNet.
BestandteileDie wichtigsten Elemente in YAML sind:
Leerzeichen zur Einrückung als Strukturierungselement
Einfachen Listen (alias Arrays); Listenelemente beginnen mit einem Minuszeichen
Assoziativen Listen (alias Hashes, Maps, Dictionary) in der Form Name : Wert
Einzelwerten (Skalare): diese können, müssen aber nicht in einfachen oder doppelten Anführungszeichen stehen
Sprungmarken (Anker) und Verweise (Referenzen): die Sprungmarke beginnt mit dem kaufmännischen &, der Verweis darauf mit einem Stern *
Kommentaren (beginnen mit #)
Abschnitten (---), die ein Datei in mehrere Dokumente teilen können
EinsatzgebieteYAML hat erst Mitte der 2010er-Jahre größere Bedeutung erhalten als es von Docker als Konfigurationsformat für Deployment und Debugging-Einstellungenverwendet wurde.
Microsoft verwendet YAML seit 2019 in Azure DevOps.
BeispielListing 1 zeigt ein Objektmodell mit verschiedenen Datentypen (inkl. Nullable Value Types), Listen, einem Aufzählungstyp und einer zirkulären Referenzen. Der Programmcode ist eine komplexere Form eines Beispiels auf Github [https://github.com/aaubry/YamlDotNet/blob/master/YamlDotNet.Samples/SerializeObjectGraph.cs]. Listing 2 zeigt die Serialisierung und Deserialisierung mit YamlDotNet. Listing 3 zeigt das Ergebnisdokument.
Listing 1: Ein Objektmodell in C# mit zirkulären Referenzenusing System;
using System.Collections.Generic;
namespace ITVisions.Demo.BO
{
public enum Title
{
None, Dr, Prof, ProfDr
}
public class Address
{
public string Street { get; set; }
public string City { get; set; }
public string State { get; set; }
}
public class Order
{
public Guid ReceiptGUID { get; set; }
public DateTime Date { get; set; }
public Customer Customer { get; set; }
public List<Item> Items { get; set; }
public Address Bill_To { get; set; }
public Address Ship_To { get; set; }
public string SpecialDelivery { get; set; }
}
public class Customer
{
public string Name { get; set; }
public Employee Employee { get; set; }
}
public class Employee
{
public Title Title { get; set; }
public string Givenname { get; set; }
public string Surname { get; set; }
public DateTime? Birthday { get; set; }
public List<Receipt> Receipts { get; set; } = new List<Receipt>();
}
public class Item
{
public short Part_No { get; set; }
public string Description { get; set; }
public decimal Price { get; set; }
public int Quantity { get; set; }
public int? Weight { get; set; }
}
}
Listing 2: Erzeugen eines Objektmodells und Serialisierung sowie Deserialisierung in YAMLusing ITVisions.Demo.BO;
using System;
using System.Linq;
using YamlDotNet.Serialization;
using YamlDotNet.Serialization.NamingConventions;
namespace ITVisions
{
public class YAMLDemo
{
public void Run()
{
Console.WriteLine("--- Creating Business Objects...");
var receipt = CreateBusinessObjects();
Console.WriteLine("--- Serializing...");
var serializer = new SerializerBuilder()
.WithNamingConvention(new PascalCaseNamingConvention())
.Build();
var yaml = serializer.Serialize(receipt);
Console.WriteLine("--- Result:");
Console.WriteLine(yaml);
Console.WriteLine("--- Deserializing...");
var deserializer = new DeserializerBuilder()
.WithNamingConvention(new PascalCaseNamingConvention())
.Build();
var receipt2 = deserializer.Deserialize<Order>(yaml);
Console.WriteLine("--- Result:");
ObjectDumper.Write(receipt2);
}
private static Order CreateBusinessObjects()
{
var address = new Address
{
Street = "De-La-Chevallerie-Straße 42,\nEtage 2",
City = "45894 Gelsenkirchen",
State = "NRW"
};
var receipt = new Order
{
ReceiptGUID = Guid.NewGuid(),
Date = DateTime.Now,
Customer = new Customer
{
Name = "5Minds IT Solutions Gmbh & Co KG",
Employee = new Employee
{
Title = Title.Dr,
Givenname = "Dr. Holger",
Surname = "Schwichtenberg"
}
},
Items = (new Item[]
{
new Item
{
Part_No = 123,
Description = "C# 7.3 Crashkurs",
Price = 14.99M,
Quantity = 40
},
new Item
{
Part_No = 456,
Description = "Moderne Datenzugriffslösungen mit \"Entity ramework Core 2.1/2.2 Ruby\"",
Price = 49.00M,
Quantity = 1
}
}).ToList(),
Bill_To = address,
Ship_To = address,
SpecialDelivery = "Bitte zusammen anliefern\n" +
"Wareneingang 2. Etage.\n" +
"Bitte am Empfang melden"
};
// recursion
receipt.Customer.Employee.Receipts.Add(receipt);
return receipt;
}
}
}
Listing 3: YAML-Dokument für das Objektmodell in Listing 1 &o0
ReceiptGUID: d5549070-102a-4768-8b65-03501b76af24
Date: 2019-06-12T20:16:55.2529275+02:00
Customer:
Name: 5Minds IT-Solutions Gmbh & Co KG
Employee:
Title: Dr
Givenname: Dr. Holger
Surname: Schwichtenberg
Receipts:
Items:
Description: C# 7.3 Crashkurs
Price: 14.99
Quantity: 40
Description: Moderne Datenzugriffslösungen mit "Entity Framework Core 2.1/2.2 Ruby"
Price: 49.00
Quantity: 1
BillTo: &o1
Street: >-
De-La-Chevallerie-Straße 42,
Etage 2
City: 45894 Gelsenkirchen
State: NRW
ShipTo: *o1
SpecialDelivery: >-
Bitte zusammen anliefern
Wareneingang 2. Etage.
Bitte am Empfang melden