Obraz pokazujący żółty folder z napisem YAML

YAML dla początkujących

W artykule przeczytasz o zyskującym na popularności języku YAML. Dowiesz się do czego służy ten język i jaka jest jego składania. Ponadto poznasz narzędzia, dzięki którym będzie Ci łatwiej pracować z YAML. Dodatkowo przedstawione zostaną różnice między YAML i formatami JSON i XML.

Zapraszam do lektury artykułu.

Co to jest YAML

YAML (ang. AML Ain’t Markup Language) jest językiem formalnym służącym do opisu danych. Jego początki sięgają 2001 roku. Założeniami twórców było stworzenie języka czytelnego i przyjaznego człowiekowi. Język ten miał być również prosty w przetwarzaniu.

Zobaczmy prosty przykład, który prezentuje pewien zbiór danych zapisanych w formacie YAML.

# To jest przykład pliku w języku YAML
---
naglowek: 'Kurs języka YAML dla początkujących'
data: 2019-05-25 11:02:57
info:
    tytul: 'Język YAML'
    opis: 'Krótki przewodnik na temat języka YAML'
    ilosc-slow: 2000
    spis:
        - Zastosowanie
        - Skladnia YAML

Powyższy zapis jest z pewnością zrozumiały dla każdego z nas. Najprostsza struktura danych zapisana w YAML ma następującą składnie:

klucz : wartosc

Poszczególne struktury danych oddzielone są od siebie znakami nowej linii. Natomiast za pomocą wcięć tworzymy hierarchie pomiędzy tymi strukturami. Myślę, że bez trudu będziesz sam w stanie szybko nauczyć się opisywać dane tym języku.

Składnia

Z wcześniejszego przykładu wynika, że składnia YAML nie powinna być skomplikowana. I tak jest w istocie. Najprostsze struktury zapisane w YAML to mapowania wartości z kluczem.

Zanim zaczniemy zapisywać dane z użyciem YAML w plikach musimy wiedzieć, że muszą one spełniać pewne reguły. A są nimi:

  • pliki powinny mieć rozszerzenie yaml lub yml (najczęściej jest to rozszerzenie yaml),
  • wcięcia i pojedyncze odstępy powinny być zapisane za pomocą spacji, nie wolno używać znaków tabulacji,
  • należy pamiętać, że w YAML rozróżniana jest wielkość liter.

Wspomnę jeszcze o trzech znakach myślnika (---) na początku i trzech znakach kropki (...) na końcu pliku yaml. Są to opcjonalne elementy, które wskazują odpowiednio początek i koniec dokumentu.

Komentarze

W YAML występuje tylko jeden rodzaj komentarza. Jest nim komentarz liniowy. Aby stworzyć taki komentarz należy użyć znaku # (krzyżyk, ang. hash). Oto prosty przykład:

# To jest komentarz w języku YAML

Komentarz ten obejmuje obszar od znaku #, aż do końca wiersza w którym się znajduje. YAML nie obsługuje komentarzy blokowych jak to ma miejsce w innych językach. Jeśli chcemy stworzyć komentarz wieloliniowy to musimy na początku każdej linii umieścić znak #.

# To pierwsza linia komentarza
# To jest druga linia komentarza
# A to kolejna ...

Typy numeryczne

W YAML mamy do dyspozycji następujące typy danych numerycznych:

  • liczby całkowite (liczby bez części ułamkowej),
  • liczby zmiennoprzecinkowe (liczby z częścią ułamkową),
  • liczby zmiennoprzecinkowe zapisane w notacji wykładniczej,
  • liczby zapisane w systemie szesnastkowym,
  • liczby zapisane w systemie ósemkowym,
  • dodatnią nieskończoność,
  • ujemną nieskończoność,
  • nie liczbę (NaN , ang. Not a Number).

Spójrzmy na poniższy przykład, w którym przedstawione są wszystkie opisane powyżej typy numeryczne.

liczba-calkowita: 100
liczba-zmiennoprzecinkowa: 1230.15
liczba-z-notacją-wykladnicza: 12.3015e+05
liczba-szesnastkowa: 0x1D2
liczba-osemkowa: 02333
dodatnia-nieskonczonosc: .inf
ujemna-nieskończonosc: -.Inf
nie-liczba: .NAN

Typ String

Ciągi znaków (ang. strings) przechowywane są w standardzie Unicode. W większości przypadków nie musisz zawierać ciągu znaków w cudzysłowach. Pokazuje to poniższy przykład.

ciag-znakow: Przykładowy ciąg znaków

Użycie znaków cudzysłowu jest konieczne jeśli ciąg znaków zaczyna się lub kończy spacjami. Oto przykład:

ciag-znakow: ' Ciąg znaków ze spacjami na początku i końcu '

Jeśli zdefiniowałeś ciąg znaków otoczony pojedynczymi cudzysłowami i chcesz w nim umieścić pojedynczy cudzysłów to musisz go zdublować. Ilustruje to poniższy przykład:

ciag-znakow: 'Ciąg znaków ze cudzyłowem '' w środku' 

Jeśli w ciągu znaków używamy znaków specjalnych to również muszą one zostać umieszczone w cudzysłowach. Oto zbiór znaków których dotyczy ten wymóg:

:, {, }, [, ], ,, &, *, #, ?, |, -, <, >, =, !, %, @, `

Ciągi znaków mogą być umieszczone również pomiędzy znakami podwójnego cudzysłowu. Wtedy zmienia się trochę interpretacja niektórych znaków. Jeśli mamy taki oto ciąg znaków:

ciag-znakow: 'Ciąg znaków ze znakiem końca linii\n' 

To dwa ostatnie znaki zostaną zinterpretowane jako dwa znaki. Jako znak \ i jako litera n. Jeśli natomiast zapiszemy powyższy ciąg znaków w podwójnym cudzysłowie jak poniżej

ciag-znakow: "Ciąg znaków ze znakiem końca linii\n"

to ostanie dwa znaki zostaną zinterpretowane jako jeden znak. Znakiem tym będzie znak przejścia do nowej linii.

Wieloliniowe ciągi znaków

Powyższe przykłady pokazywały ciągi znaków składające się z jednej linii. Jeśli chcemy zapisywać w YAML ciągi składające się z wielu linii musimy posłużyć się odpowiednią składnią. Spójrzmy na przykład.

ciag-znakow: >
  To jest ciąg znaków,
  który zapisany jest
  w więcej niż jednej linii

Ten ciąg znaków będzie zinterpretowany jako pojedyncza linia czyli jako

To jest ciąg znaków, który zapisany jest w więcej niż jednej linii

Widzimy że, każdy znak końca linii został zastąpiony spacją.

Jeśli chcemy zachować znaki końca linii to musimy zastosować następujący zapis:

ciag-znakow: |
  To jest ciąg znaków,
  który zapisany jest
  w więcej niż jednej linii

Wtedy zostanie to zinterpretowane jako następujący ciąg znaków

 To jest ciąg znaków,
 który zapisany jest
 w więcej niż jednej linii

Typ Boolean

Wartości typu boolean czyli wartości logiczne mogą być zapisane za pomocą słów true i false. Oto przykład, który pokazuje w jaki sposób możemy użyć wartości logicznych.

gotowy: true
walidacja: false

Daty

Jeśli chcemy zapisywać daty w języku YAML to musimy zapisywać je zgodnie ze standardem ISO-8601. Spójrzmy na kilka przykładów pokazujących jak mogą wyglądać daty zapisane zgodnie z ISO-8601.

data-dostawy: 2019-05-01
data-odczytu: 2019-04-11T01:22:13.1Z 
data-zapisu: 2019-05-14 20:29:33.20 -5

Wartość Null

Wartość null może być w YAML wyrażona na dwa sposoby:

  1. Poprzez użycie znaku tyldy ~
  2. Poprzez użycie słowa null

Spójrzmy na proste przykłady obrazujące użycie obu sposobów definiowania wartości null.

klucz-1: ~
klucz-2: null

Listy

W YAML możemy definiować listy elementów. Elastyczność języka pozwala na tworzenie list w różny sposób. Przykład poniżej pokazuje pierwszy z tych sposobów.

wzorce-projektowe:
 - strategia
 - budowniczy
 - proxy

Listę możemy również utworzyć w inny sposób. Poprzez umieszczenie elementów w nawiasach kwadratowych i rozdzieleniu ich przecinkami. Spójrzmy jak wygląda deklaracja takiej listy.

poziom-logowania: ["error", "info", "debug"]

Elementy tworzonych list mogą reprezentować bardziej złożone struktury danych. Następujący przykład przedstawia strukturę opisującą listę plików. Każdy element listy opisujący pojedynczy plik składa się z dwóch elementów. Pierwszym z nich jest nazwa pliku, a drugim jego rozmiar wyrażony w bajtach.

pliki:
 - nazwa: "komponenty.txt"
   rozmiar: 1023
 - nazwa: "statystyki.txt"
   rozmiar: 5363
 - nazwa: "zestawienie.txt"
   rozmiar: 1342

Powyższa lista może być również zadeklarowana w taki oto sposób:

pliki:
 - 
   nazwa: "komponenty.txt"
   rozmiar: 1023
 - 
   nazwa: "statystyki.txt"
   rozmiar: 5363
 - 
   nazwa: "zestawienie.txt"
   rozmiar: 1342

YAML jest bardzo elastycznym językiem i umożliwia zapisanie powyższej listy w jeszcze jeden sposób. Oto on:

pliki:
 - {nazwa: "komponenty.txt", rozmiar: 1023}
 - {nazwa: "statystyki.txt", rozmiar: 5363}
 - {nazwa: "zestawienie.txt", rozmiar: 1342}

Zakotwiczenia i aliasy

W YAML możesz stosować odwołania do innych elementów za pomocą kotwic (ang. anchor).

W tym celu należy oznaczyć za pomocą kotwicy (znaku &) element do którego będziemy się odwoływać. Natomiast samo odwołanie do oznaczonego elementu zrealizujemy za pomocą aliasu (znaku *). Zobaczmy przykład, który rozjaśni nam w jaki sposób działa ten mechanizm.

komputer:
  nazwa: &nazwa "135123"
  procesor: "Intel Core i7"
  ram: "4GB"
  dysk: "120GB"
  
  # informacje dodatkowe
  identyfikator: *nazwa  

W powyższym przykładzie zdefiniowaliśmy kotwicę o nazwie &nazwa. Kotwica ta musi zostać umieszczona po nazwie klucza, a przed wartością przypisaną do tego klucza. Następnie odwołujemy się do wartości reprezentowanej przez kotwice. Dokonujemy tego podczas definiowania identyfikatora. Oznacza to, że wartość dla klucza identyfikator jest taka sama jak wartość dla klucza nazwa. Czyli wynikowa struktura opisująca identyfikator będzie wyglądać następująco:

  identyfikator: "135123"

Scalanie struktur

W YAML możemy scalać zdefiniowane struktury danych. Aby dokonać scalenia struktur posługujemy się znakiem <<. Rozpatrzmy następujący przykład.

production: &settings
  database-host: 221.10.23.33
  database-port: 3306
  database-pool-size: 25
  database-name: production

test:
  <<: *settings
  database-host: 127.0.0.1
  database-name: test

W powyższym przykładzie widzimy konfigurację bazy danych dla środowiska produkcyjnego i testowego. Konfigurowane są takie parametry jak:

  • adres IP serwera na którym znajduje się baza danych,
  • port,
  • rozmiar puli połączeń,
  • nazwa bazy danych.

Ustawienia produkcyjne oznaczone są kotwicą o nazwie &settings. W konfiguracji środowiska testowego widzimy odwołanie do kotwicy &settings. Odwołujemy się używając operatora <<. Powoduje to włączenie danych z konfiguracji środowiska produkcyjnego do konfiguracji środowiska testowego.

Widzimy jednak, że mamy takie same klucze w obydwóch konfiguracjach. Są nimi database-host i database-name. W takiej sytuacji wartości dla kluczy z konfiguracji produkcyjnej zostaną nadpisane wartościami z konfiguracji testowej. Oznacza to, że końcowa konfiguracja dla środowiska testowego będzie następująca:

  database-host: 127.0.0.1
  database-port: 3306
  database-pool-size: 25
  database-name: test

Jawne określanie typu

Specyfikacja języka YAML pozwala nam jawnie zadeklarować typ danych. W tym celu używamy dwóch znaków wykrzyknika (!!) po których podajemy typ danych.

Oto kilka przykładów, które pokazują w jaki sposób możemy jawnie deklarować typ danych.

rok: !!int 2019
cena: !!float 2.34
data-jako-string: !!str 2019-05-14
walidacja: !!bool   true

Typ binarny

W języku YAML możemy definiować wartości binarne. Do tego celu wykorzystuje się format base64.

Przykład poniżej pokazuje jak zapisano tekst javadeveloper.pl jako typ binarny.

dana-binarna: !!binary amF2YWRldmVsb3Blci5wbA==

Zastosowanie

YAML ma zastosowanie w następujących przypadkach:

  • Pliki konfiguracyjne. Prostota i przejrzystość zapisu danych w YAML sprawia, że bardzo łatwo przygotowuje się w nim pliki konfiguracyjne. Coraz więcej narzędzi i środowisk wykorzystuje go w tym celu. Wśród nich można wymienić Ansible, Spring, Ruby on Rails czy Google App Engine.
  • Serializacja danych. Niezależność od platformy i języka programowania powoduje, że wymiana danych jest stosunkowo prosta. Możemy dodatkowo manipulować procesem serializacji wykorzystując kotwice i aliasy.

Narzędzia dla języka YAML

Edytory

Poniższe programy to najpopularniejsze aplikacje do pracy z językiem YAML.

  • Notepad++ (popularny darmowy edytor posiadający podświetlanie składni oraz obsługę wcięć)
  • Sublime Text (edytor komercyjny obługujący podświetlanie składni i obsługę wcięć)

Walidatory składni

Konwertery

Porównanie YAML z XML

Spójrzmy na poniższe porównanie języka YAML z formatem XML.

  • znacznie czytelniejszy niż XML
  • łatwiejsza edycja (brak dodatkowych znaczników zmniejsza możliwość wprowadzenia błędów)
  • brak możliwości definiowania struktury względem, której dokonuje się walidacji
  • brak możliwości wykonywania zapytań wyszukujących dane (w XML możemy użyć XPath)

Porównanie YAML z JSON

Zobaczmy również listę prezentującą porównanie YAML z JSON.

  • znacznie czytelniejszy niż JSON
  • posiada możliwość tworzenia komentarzy - brak takiej możliwości w JSON
  • JSON ma znacznie prostszą specyfikacją niż YAML
  • możliwość jawnej deklaracji typu danych, której nie ma w JSON
  • JSON nie posiada funkcjonalności realizowanej w YAML przez kotwice i aliasy
  • JSON jest podzbiorem YAML (od wersji 1.2) - oznacza to, że można go analizować narzędziami do obsługi YAML

Materiały dodatkowe

Materiały wideo

Polecam zapoznanie się z bardzo interesującym wykładem na temat języka YAML w wykonaniu pani Tiny Müller.

Zasoby sieciowe

Podsumowanie

Po zapoznaniu się z lekturą dzisiejszego artykułu wiesz czym jest YAML. Poznałeś jego składanie i myślę, że praca z nim nie będzie Ci sprawiać problemów.

Znasz również różnicę pomiędzy YAML a formatami XML i JSON. Dodatkowo zaznajomiłeś się z narzędziami, dzięki którym praca z YAML będzie bardziej efektywna.

Popularność YAML ciągle rośnie i być może w przyszłości dorówna ona popularności jaką dziś mają XML i JSON.