YAML
1. Bevezetés¶
A YAML (a "YAML Ain't Markup Language" rövidítése) egy ember által olvasható adat-sorosítási nyelv. Általában konfigurációs fájlokban és olyan alkalmazásokban használják, ahol adatokat tárolnak vagy továbbítanak. A YAML ugyanazokat a kommunikációs alkalmazásokat célozza meg, mint az Extensible Markup Language (XML), de minimális szintaxissal rendelkezik, amely szándékosan különbözik az SGML-től. Python-stílusú behúzást használ a blokkok jelzésére, valamint egy kompaktabb formátumot, amely a [] listákat használja és a {} a mappeket használja, így a YAML 1.2 a JSON szuperkészletévé válik.
Az egyéni adattípusok megengedettek, de a YAML natívan kódolja azokat (például karakterláncokat, egész számokat és tört számokat), a listákat és az asszociatív tömböket (hash, map vagy szótár néven is ismert). Ezek az adattípusok a Perl programozási nyelvén alapulnak, bár az összes általánosan használt magas szintű programozási nyelv nagyon hasonló fogalmakat használ. A kettőspont központú szintaxist, amelyet a kulcs-érték párok kifejezésére használnak, az RFC 0822 meghatározása szerinti elektronikus levél fejlécek inspirálják, és a "---" dokumentum elválasztó a MIME-től (RFC 2046) származik. A kilépési szekvenciákat a C-ből felhasználták fel, és a többsorok közötti szóközt a HTML-kód ihlette. A listák és hash-ok beágyazott listákat és hash-ekat tartalmazhatnak, amelyek fa struktúrát képeznek; tetszőleges grafikonok ábrázolhatók YAML álnevekkel (hasonlóan az XML-hez a SOAP-ban). A YAML adatfolyamokban való olvasást és írást a SAX szolgáltatás inspirálta.
A YAML olvasását és írását számos programozási nyelven elérhető. Néhány forráskód-szerkesztő, például az Emacs, VSCode és a különféle integrált fejlesztési környezetek olyan funkciókkal rendelkeznek, amelyek megkönnyítik a YAML szerkesztését, például a beágyazott struktúrák összehajtása vagy a szintaxis hibák automatikus kiemelése.
2006 óta a YAML fájlok hivatalosan ajánlott fájlnévkiterjesztése .yaml.
2. Szintaxis¶
- A behúzások a szerkezet jelölésére szolgál; a tabulátor karakterek azonban nem engedélyezettek.
- A megjegyzések a kettőskeresztel (#) kezdődnek, bárhol kezdődhetnek a sorban, és a sor végéig tartanak. A megjegyzéseket szóközzel kell elválasztani a többi karaktertől. Ha a # karakter megjelenik egy karakterlánc belsejében, akkor számjeggyel kell leírni.
- A listákat kötőjelel kell kezdeni (-), soronként egy lehet belőle.
- A listát ([]) szögletes zárójellel is meg lehet határozni, ebben az esetben a belsejében a bejegyzéséseket vesszővel kell elválasztani.
- Az asszociatív tömböt kulcs: érték párként szerepel a bejegyzésben. A YAML megköveteli, hogy a kettőspontot szóköz kövesse, hogy a skaláris értékek, például a https://www.eresseel.org, ábrázolhatóak legyenek anélkül, hogy idézőjelekbe kellene foglalni őket.
- A kérdőjel használható egy kulcs előtt, "? Kulcs: érték" formában, hogy idézőjelek nélkül tartalmazzon a kulcs kötőjelet, szögletes zárójelet stb.
- Egy asszociatív tömb meghatározható a kapcsos zárójelekbe zárt szöveggel is ({}). A kulcsok elszeparálását az értékektől kettősponttal elválasztva, a bejegyzéseket vesszővel elválasztva kell leírni. (szóköz nem szükséges, a JSON kompatibilitáshoz)
- A karakterláncokat (skalárokat) általában nem idézőjelek közé tesszük, ennek ellenére lehetnek macskakörmök (") vagy idézőjelek (') közé zárni.
- A dupla idézőjelekben a speciális karakterek ábrázolhatók C-típusú jelöléssel, amelyek visszaper jellel kezdődnek (). A dokumentáció szerint az egyetlen támogatott oktális jelölés a (\0).
- A blokk skalárt behúzással határozzuk meg. Opcionálisan módosítók, hogy megőrizzék a sor folytonosságot (>) vagy új sort hajtson végre (|).
- Egy fájlon belül több dokumentum részt három kötőjel (---) választ el.
- Három pont (...) tetszés szerint véget vethet a dokumentum résznek egy adatfájlon belül.
- Az ismétlődő csomópontokat kezdetben az endjel (&) jelöli, majd csillaggal (*) jelölik.
- A csomópontokat fel lehet tüntetni egy típus vagy címke a használatával (!!), amelyet egy karakterlánc követ, amely kibővíthető URI-ként.
- A YAML-dokumentumokat „direktívák” előzhetik meg, amelyek egy százalékjelet (%) tartalmaznak, amelyet egy név és utána szóközzel elválasztott paraméterek követnek. A YAML 1.1 két irányelvet határoz meg:
- A %YAML direktíva a YAML verziójának azonosításához szolgál egy adott dokumentumban.
- A %TAG direktíva az URI előtagok parancsikonjaként szolgál. Ezeket a parancsikonokat csomópont típusú címkékben lehet használni.
Két további karakter van fenntartva a YAML-ben a lehetséges jövőbeli specifikációkhoz: a kukac (@) és backtick (`).
3. Alap Komponensek¶
A YAML "in-line" stílust kínál az asszociatív tömbök és listák jelölésére. Itt található egy minta az összetevőkről. A hagyományos blokkformátum kötőjelet + szóközt használ egy új elem elindításához a listában.
--- # Kedvenc filmjeim
- Casablanca
- North by Northwest
- The Man Who Wasn't There
Az opcionális inline formátumot vesszővel + szóközzel elválasztva írjuk és szögletes zárójelbe zárjuk (hasonlóan a JSON-hoz).
--- # Bevásárló lista
[tej, kenyer, tojas, asvanyviz]
A kulcsokat kettőspont + szóköz választja el az értékektől. A YAML adatfájlokban behúzásokat használunk a blokkok elkülönítésére és új sorok használatával választjuk el a "kulcs: érték" párokat. A YAML adatfájlban az inline blokkokat vesszővel + szóközzel választjuk el a "kulcs: érték" párokat a kapcsos zárójelek között.
--- # Behúzott blokk
nev: John Smith
kor: 33
--- # Inline Block
{nev: John Smith, kor: 33}
A szövegek nem igényelnek idézőjelet. Kétféle módon írhatsz több sorból álló karakterláncokat: az egyik megőrzi az új sorokat (|), és a másik lehetőség, hogy az új sorokat összefűzi egyetlen sorrá (>). Mindkettő karakter után ENTER-t ütni.
data: |
There once was a tall man from Ealing
Who got on a bus to Darjeeling
It said on the door
"Please don't sit on the floor"
So he carefully sat on the ceiling
Alapértelmezetten az első sor elején a behúzás és a sor végén a szóköz megszűnik, bár ettől eltérő viselkedés meghatározható.
data: >
Wrapped text
will be folded
into a single
paragraph
Blank lines denote
paragraph breaks
A többsoros szövegben az új sorokat szőközzé alakítja és eltávolítja a kezdő behúzást.
--- # Smiths profilja
- {nev: John Smith, kor: 33}
- nev: Mary Smith
kor: 27
- [nev, kor]: [Rae Smith, 4] # A szekvenciák kulcsként támogattak
--- # Emberek, nemek szerint
ferfi: [John Smith, Bill Jones]
no:
- Mary Smith
- Susan Williams
Az objektumok és a listák a YAML fontos elemei, és ezek tetszőlegesen keverhetőek. Az első példa a kulcsértékű objektumok listája, ami a Smith családtagajaiból ált. A második nemek szerint sorolja fel őket, ez egy kulcs értékű objektum, amely két listát tartalmaz.
4. Speciális Komponensek¶
Két tulajdonság van, ami megkülönbözteti a YAML-t a többi adat-sorosítási nyelv képességeitől, a struktúrák és az adatok használata. A YAML struktúrák lehetővé teszik több dokumentum tárolását egyetlen fájlban, az ismételt csomópontok referenciáinak használatát és a tetszőleges csomópontok kulcsként történő használatát. Az érthetőség, a kompaktság és az adatbeviteli hibák elkerülése érdekében a YAML csomópont horgonyokat biztosít és a és referenciákat a (*) használatával. A horgonyra vonatkozó hivatkozásokat minden adattípusra lásd a az alábbi példában. Az alábbiakban bemutatok egy példát amelyben két lépést ismételten újrafelhasználnok anélkül, hogy minden alkalommal teljes körűen leírnám.
# protokollok lézeres szemműtéthez
---
- step: &id001 # horgonycimke meghatározása &id001
instrument: Lasik 2000
pulseEnergy: 5.4
pulseDuration: 12
repetition: 1000
spotSize: 1mm
- step: &id002
instrument: Lasik 2000
pulseEnergy: 5.0
pulseDuration: 10
repetition: 500
spotSize: 2mm
- step: *id001 # horgonnyal utal az első lépésre (&id001)
- step: *id002 # a második lépésre vonatkozik
- step: *id002
Az explicit adatokat a YAML-dokumentumok többségében ritkán látják, mivel a YAML az automatikus típusokat automatikusan felismeri. Az adattípusok három kategóriába sorolhatók: alapvető, meghatározott és felhasználói által meghatározott. Az alapvető adatok várhatóan léteznek bármely elemzőben (például törtek, egészek, karakterláncok, listák stb.). Számos fejlettebb adattípus, például bináris adat, a YAML specifikációban van meghatározva, de nem támogatott minden megvalósításban. Végül a YAML meghatározza az adattípus-meghatározások helyben történő kiterjesztésének módját, hogy a felhasználó által definiált osztályokat, struktúrákat vagy primitíveket (például négy pontos pontosságú törteket) alkalmazzon.
A YAML képes automatikusan meghatározza az entitás adattípusát, de vannak olyan esetek amikor az adattípust kifejezetten meg kell adni. A leggyakoribb eset az, amikor az egyszavas karakterlánc, úgy néz ki, mint egy szám, logikai kifelyezés vagy címke, ekkor egyértelművé kell tenni idézőjelekkel vagy kifejezetten adattípus-címke használatával.
---
a: 123 # egész szám
b: "123" # idézőjelek használatával karakterlánc lesz belőle
c: 123.0 # tört szám
d: !!float 123 # (!!) az előtagnak köszönhetően tört számként fogja ártelmezni
e: !!str 123 # karakterlánc, explicit típussal azonosítva
f: !!str Yes # karakterlánc, explicit típuson keresztül
g: Yes # logikail kifejezés: "Igaz" érteket vesz fel yaml1.1-ben, karakterlánc lesz yaml1.2-ben, értéke: "Igen"
h: Yes we have No bananas # "Igen" és "Nem" karakterlánc, a kontextus alapján egyértelművé válik.
A YAML nem minden verziójában van minden adattípus meghatározva. Ezek a beépített típusok kettős felkiáltójelet (!!) használnak. Különösen érdekesek, amelyek itt nem jelennek meg, a készletek, a rendezett térképek, az időbélyegzők és a hexadecimálisok. Íme egy példa az base64-kódolt bináris adatokra.
---
picture: !!binary |
R0lGODdhDQAIAIAAAAAAANn
Z2SwAAAAADQAIAAACF4SDGQ
ar3xxbJ9p0qa7R0YxwzaFME
1IAADs=
A YAML számos implementációja támogatja a felhasználó által definiált adattípusokat az objektumok sorosítása céljából. A helyi adattípusok nem univerzális adattípusok, hanem az alkalmazásban a YAML elemző könyvtár használatával kerülnek meghatározásra. A helyi adattípusok egyetlen felkiáltójelet (!) használnak.
---
myObject: !myClass { name: Joe, age: 15 }
Figyelembe kell venni, hogy a karakterláncokat nem kell idézőjelbe tenni. A behúzás helyének meghatározott száma nem számít, mindaddig, amíg a párhuzamos elemeknek ugyanaz a bal oldali behúzása van, és a hierarchikusan beágyazott elemek beljebb vannak behúzva.
5. Jellemzők¶
5.1. Nem hierarchikus adatmodellek¶
A JSON-től eltérően, amely csak hierarchikus modellben reprezentálhat adatokat, és minden gyermekcsomópont egyetlen szülővel rendelkezik, a YAML egy egyszerű relációs sémát is kínál, amely lehetővé teszi az azonos adatok ismétléseinek hivatkozását a fa két vagy több pontjáról, ahelyett, hogy redundáns módon beírnák ezeket a pontokat. Ez hasonló az XML-be beépített létesítmény IDREF-hez. A YAML elemző ezután kibővíti ezeket a hivatkozásokat a teljesen kitöltött adatstruktúrákba, amelyek beolvasásuk során szükségesek, tehát az elemzőt használó programnak nem kell tisztában lennie a relációs kódolási modellel, ellentétben az XML feldolgozókkal, amelyek nem terjesztik ki a hivatkozásokat. Ez a bővítés javíthatja az olvashatóságot, miközben csökkentheti az adatbeviteli hibákat a konfigurációs fájlokban vagy a feldolgozási protokollokban, ahol sok paraméter ugyanaz marad a rekordok egymást követő sorában, míg csak néhány változik.
5.2. Gyakorlati megfontolások¶
A YAML sor-orientált, így gyakran egyszerű a meglévő programok struktúrálatlan kimenete YAML formátumba konvertálása, miközben ők megtartják az eredeti dokumentum megjelenésének nagy részét. Mivel nincsenek záró címkék, zárójelek vagy idézőjelek az egyensúlyozáshoz, általában könnyű jól megformált YAML-et generálni közvetlenül az elosztott nyomtatási képekből a kifinomult programokon belül. Hasonlóképpen, a szóközt elhatárolók megkönnyítik a YAML fájlok gyors szűrését a grep, AWK, Perl, Ruby és Python sor-orientált parancsokkal.
Különösen, a jelölőnyelvekkel ellentétben, az egymást követő YAML sorok darabjai általában jól formált YAML dokumentumok. Ez nagyon egyszerűvé teszi azon elemzők írását, amelyeknek nem kell teljes egészében feldolgozniuk a dokumentumot (például kiegyenlíteni a nyitó és záró címkéket, és navigálni az idézett karaktereket), mielőtt megkezdenék a meghatározott rekordok kibontását. Ez a tulajdonság különösen akkor célszerű, ha egyetlen, állapot nélküli átadással iterálunk egy fájlban, amelynek teljes adatszerkezete túl nagy a memóriában való tároláshoz, vagy amelynél az egész elem rekonstruálása egy elem kinyerése érdekében megfizethetetlenül nagy költséges.
A behúzás bonyolultnak tűnhet a többszintű beágyazott hierarchiákban. A YAML a kisebb francia bekezdéseket kezel, és ezzel jobb tömörítés érhető el, mint a jelölőnyelveknél. Ezzel a rendkívül mély behúzódást teljes mértékben elkerülhetjük: 1) a behúzás nélkül visszatérve az "inline stílusra" (azaz JSON-szerű formátumra); vagy 2) relációs horgonyok használatával tehetjük kötetlenebbé a hierarchiát, amelyet a YAML elemző átlátható módon rekonstruál a teljes adatszerkezetbe.
5.3. Biztonság¶
A YAML azonban lehetővé teszi a nyelvspecifikus címkéket, így tetszőleges helyi objektumokat hozhat létre egy elemző, amely támogatja ezeket a címkéket. Bármely YAML elemző, amely lehetővé teszi a kifinomult objektum-megvalósítást, lehetővé teszi az injekciós támadást. A tetszőleges osztályú objektumok betöltését lehetővé tevő Perl elemzők úgynevezett "blessed" értékeket hoznak létre. Ezen értékek használata váratlan viselkedést válthat ki, pl. ha az osztály túlterhelt operátort használ. Ez tetszőleges Perl-kód végrehajtásához vezethet.
Hasonló a helyzet a Python vagy a Ruby elemzőknél. A PyYAML dokumentációja szerint:
- Ne feledje, hogy a saját Python objektum felépítése veszélyes lehet, ha YAML dokumentumot megbízhatatlan forrásból kapja, például az internetről. A yaml.safe_load függvény korlátozza ezt a képességet az egyszerű Python objektumokhoz, például egészek vagy listák.
- A PyYAML lehetővé teszi bármilyen típusú Python objektum felépítését. Még a Python osztályok példányai is felépíthetők a !!python/object címke segítségével.
5.4. Adatfeldolgozás és reprezentáció¶
A YAML specifikáció egy példánydokumentumot "Presentation" vagy "karakterfolyamként" azonosít. A YAML példánydokumentum elsődleges logikai struktúrái a skalár, a szekvencia és a leképezés. A YAML specifikáció néhány alapvető korlátozást is jelöl, amelyek vonatkoznak ezekre az elsődleges logikai struktúrákra. Minden olyan esetben, amikor a csomóponti sorrend jelentős, sorozatot kell használni.
Ezenkívül a YAML processzorok megfelelőségének meghatározásakor a YAML specifikáció két elsődleges műveletet határoz meg: a dump-ot és a betöltést. Az összes YAML-kompatibilis processzornak legalább ezen műveletek egyikét végre kell hajtania, és adott esetben mindkettőt biztosíthatja. Végül, a YAML specifikáció meghatároz egy információs modellt vagy "reprezentációs gráfot", amelyet létre kell hozni a feldolgozás során mind a dump, mind a betöltési műveletekhez, bár ezt a reprezentációt nem kell a felhasználó rendelkezésére bocsátani egy API-n keresztül.