JSON'dan YAML'a dönüştürücü
JSON'u YAML'a dönüştürür ve eklediği her tırnağı açıklar — tırnak olmadan sessizce mantıksal değer, sayı ya da tarih hâline gelecek dizeleri.
name: deploy
country: 'NO'
startsAt: '12:30'
mode: '0755'
version: '1.10'
released: '2024-01-30'
enabled: 'yes'
script: |-
set -e
npm run build
npm test
replicas: 3
tags:
- web
- edge
Tırnaklı değerler: 6. Yalnızca YAML 1.1'in gerektirdiği: 4. Farkı görmek için yukarıdaki şemayı değiştirin.
countryyalnızca 1.1“NO”, false mantıksal değeri olarak okunurdu.
startsAtyalnızca 1.1“12:30”, 60 tabanında 750 olarak okunurdu.
mode“0755” baştan sıfırlı; bu yüzden 493 sayısı olarak okunurdu.
version“1.10”, 1.1 sayısı olarak okunurdu.
releasedyalnızca 1.1“2024-01-30”, metin olarak değil bir tarih olarak okunurdu.
enabledyalnızca 1.1“yes”, true mantıksal değeri olarak okunurdu.
Bu araç ne yapar
Bir JSON belgesini YAML'a dönüştürür ve sonra her dizenin neden tırnak içinde bittiğini size söyler. O ikinci kısım, aracın var olma nedenidir: diğer her dönüştürücü çıktıyı geri verir ve değerlerinizden birinin artık bir dize olmadığını sonradan keşfetmeyi size bırakır.
Dönüştürme tek yönde çalışır. YAML okumak, onu yazmaktan çok daha büyük bir problemdir ve kısmen doğru bir YAML ayrıştırıcısı hiç yoktan kötüdür — dosyanızı kabul eder ve şikâyet etmeden yanlış veriyi geri verir. Yazmak sınırlıdır; bu yüzden burada kapsanan yön odur.
Bir dönüştürücünün neden hiç görüşlere ihtiyacı olur
JSON her şeyin ne tür olduğunu söyler. Bir dizenin tırnakları vardır, bir sayının yoktur ve üçüncü bir olasılık yoktur. YAML ise tırnaksız bir değerin türüne şekline bakarak karar verir: bir mantıksal değerin desenine uyuyorsa bir mantıksal değerdir, bir sayıya uyuyorsa bir sayıdır ve yalnızca hiçbir şeye uymuyorsa metin olarak bırakılır.
YAML'ı elle yazmayı hoş kılan ve ona dönüştürmeyi bir değerlendirme meselesi yapan budur. Girdideki her dize, YAML'ın çözdüğü her desene karşı kontrol edilmeli ve birine uyuyorsa tırnaklanmalıdır. Güvenli yönde yanlış yapın, çıktı gürültülü olur; diğer yönde yanlış yapın, bir değer sessizce tür değiştirir.
Norveç sorunu ve akrabaları
En iyi bilinen durum bir ülke kodları listesidir. Norveç NO'dur ve YAML 1.1'de tırnaksız NO belirteci false mantıksal değeridir. Ülkeleri listeleyen bir yapılandırma dosyası Norveç'i kaybeder ve bir false kazanır ve hiçbir yerde hiçbir şey bir hata bildirmez.
Bu tek bir tuhaf kural değil, bir ailedir. YAML 1.1, y, Y, yes, no, on ve off'un hepsini, her büyük/küçük harfte mantıksal değerler olarak okur, ki bu bir kimyasal simgeyi, bir düğme konumunu ve bir soruya verilen bir yanıtı yakalar. Ve sayısal çözücüler daha da tuhaftır:
- 12:30, 750'dir. YAML 1.1, iki nokta ile ayrılmış basamakları 60 tabanında okur; böylece günün bir saati ya da bir süre bir tam sayı olur.
- 0755, 493'tür. Baştaki bir sıfır YAML 1.1'de sekizlik demektir — ve YAML 1.2'de aynı metin onluk 755'tir; böylece iki sürüm, hangisi olduğu üzerinde değil, hangi sayı olduğu üzerinde anlaşamaz.
- 1.10, 1.1'dir. İki parçalı bir sürüm numarası bir kayan sayıdır ve sondaki sıfır kaybolur. 1.10'a sabitlenmiş bir bağımlılık artık 1.1'i gösterir.
- 2024-01-30 bir dize değil, bir tarih nesnesidir, çünkü YAML 1.1'in bir zaman damgası türü vardır.
- Boş bir dize null'dır, tıpkı çıplak sözcükler null, Null, NULL ve tilde gibi.
Bunların hiçbiri YAML'da bir hata değildir. Bunlar, uyum sağlayan metin üzerinde tam olarak söz verdiklerini yapan çözücülerdir. Tek savunma, uyan her şeyi tırnaklamaktır, ki bu aracın yaptığı ve bulgular panelinin satır satır hesaba kattığı şeydir.
İki sürüm ve neden eski olanın varsayılan olduğu
YAML 1.2, 2009'da geldi ve şaşırtıcı çözücülerin çoğunu kaldırdı. Çekirdek şeması mantıksal değer olarak yalnızca true ve false'u tutar, 60 tabanını tümüyle atar ve bir zaman damgası türü yoktur. 1.2 altında NO ve 12:30 ve 2024-01-30 hepsi yalnızca dizedir.
İşin püf noktası, dosyanızı gerçekte neyin okuduğudur. PyYAML, YAML 1.1'i uygular ve PyYAML, muazzam miktarda aracın ardındaki ayrıştırıcıdır — Ansible, eski Kubernetes istemcileri, sayısız betik. Go'nun yaml.v3'ü ve güncel js-yaml, 1.2'yi izler. Yani aynı belge, onu kimin açtığına bağlı olarak iki farklı şekilde okunabilir ve her yerde güvenli olan tek çıktı, 1.1 için tırnaklanmış olandır.
Buradaki varsayılan budur. Ayarı 1.2'ye geçirmek hiçbir şeyi gizlemez — yeni çözücülerle yeniden yazar ve bulgular paneli küçülür; böylece hangi tırnakların eski şema için orada olduğunu tam olarak görebilirsiniz. Kalanlar, her ayrıştırıcının gerek duyduklarıdır.
Türü değil, söz dizimini bozan dizeler
İkinci bir dize grubu farklı bir nedenle tırnaklanmalıdır: YAML onları başka bir tür olarak okuyacağı için değil, hiç metin olarak ayrıştırılmayacakları için.
- Bir boşluğun izlediği bir iki nokta bir anahtarı sonlandırır. «note: time: now», değeri bir «time» anahtarı olan bir «note» anahtarı olarak okunurdu.
- Bir kare işaretinin izlediği bir boşluk bir yorum başlatır; böylece ondan sonraki her şey kaybolur.
- Baştaki bir -, ?, :, [, ], {, }, #, &, *, !, |, >, %, @ ya da ters tırnak bir gösterge karakteridir ve yapısal bir şey ifade eder.
- Baştaki ya da sondaki boşluk tırnaksız bir değer tarafından korunmaz; böylece « x », «x» olarak geri gelir.
- Değerin herhangi bir yerindeki bir sekme doğrudan reddedilir — PyYAML onu yanlış okumak yerine tüm belgeyi reddeder; bu yüzden bu, yüksek sesle başarısız olur.
Tek tırnaklar yettikleri her yerde kullanılır, çünkü tam olarak bir kaçış kuralları vardır — bir kesme işareti iki kez yazılır — ve çift tırnakların getirdiği ters eğik çizgi kaçışlarından daha kolay okunurlar. Çift tırnaklar gerçekten kaçışlama gerektiren durumlara ayrılır: denetim karakterleri, sekmeler ve bir blok kullanamayan çok satırlı dizeler.
Çok satırlı dizeler ve kırpma göstergesi
Satır sonları içeren bir dize — bir betik, bir sertifika, bir düzyazı bloğu — genellikle birinin en başta YAML istemesinin nedenidir. JSON onu yalnızca çok uzun bir satırda ters-eğik-çizgi-n kaçışlarıyla yazabilir; YAML'ın, bir dikey çizgiyle sunulan, metnin altta girintili ve okunabilir göründüğü değişmez blok skaleri vardır.
İncelik, sondaki satır sonlarına ne olduğudur, ki bu kırpma göstergesiyle denetlenir:
- Çıplak bir dikey çizgi kırpar: bloğun kaç sondaki satır sonu olursa olsun, değer tam olarak bir tane alır.
- Bir eksinin izlediği bir dikey çizgi soyar: değer hiç almaz.
- Bir artının izlediği bir dikey çizgi tutar: değer onların her birini alır.
Bu araç göstergeyi kendisine verilen dizeden seçer; böylece değer gidiş-gelişten tam olarak sağ çıkar. Bilmeye değer, çünkü varsayılan — çıplak dikey çizgi — insanların elle yazdığıdır ve iki satır sonuyla ya da hiç satır sonu olmadan biten bir dizeyi sessizce normalleştirir.
Bir blok skaleri her şeyi taşıyamaz ve taşıyamadığı yerde çıktı çift tırnaklara geri döner ve bulgular paneli nedenini söyler. Bir satır başı sağ çıkmaz, çünkü blok skalerleri satır sonlarını normalleştirir. Bir boşlukla başlayan bir ilk satır fazladan girinti olarak okunur ve soyulurdu. Ve bir boşlukla biten bir satır belirtim tarafından korunur ama ekranda görünmezdir ve çoğu düzenleyici tarafından kaydetmede kaldırılır; bu yüzden onu tırnaklamak daha güvenli seçimdir — bu, bir sınırlama değil, bir karardır ve öyle bildirilir.
Birden çok belge
YAML'ın JSON'da olmayan bir şeyi vardır: bir dosya, üç tireyle ayrılmış bir belge akışı tutabilir. Bu, bir Kubernetes manifest'inin biçimidir ve bir JSON dizisinin neden bu kadar sık bir YAML dizisinden başka bir şey olması gerektiğinin nedenidir.
Buradaki düğme, üst düzey bir dizinin her öğesini kendi belgesi olarak yazar. Ve girdi hiç tek bir JSON değeri değil de her satır kendi başına ayrıştırılıyorsa, NDJSON olarak okunur — günlüklerin ve API dışa aktarımlarının geldiği satırla sınırlanmış biçim — ve her satır bir belge olur. O okuma bir tahmindir; bu yüzden sessizce yapılmak yerine çıktının üstünde bildirilir.
Geri dönüş yalnızca tüm girdi ayrıştırılamadığında ve her satır başarılı olduğunda uygulanır, ki yalnızca hatalı biçimli bir belge bunu yapmaz. Bir söz dizimi hatası hâlâ bir söz dizimi hatası olarak, oluştuğu satır ve sütunla yüzeye çıkar.
Dönüşümün koruyamadığı şey
Bu araç verinizi görmeden önce iki şey kaybolur, her ikisi de JSON ayrıştırmasının kendisinde ve hangisi olduğunu bilmeye değer.
Yinelenen anahtarlar. JSON, bir nesnenin aynı anahtarı iki kez listelemesine izin verir ve çoğu ayrıştırıcı sonuncuyu sessizce tutar. YAML yinelenenleri doğrudan yasaklar; böylece çıktı geçerli olacaktır, ama önceki değer zaten yok olmuştur — ve hiçbir dönüştürücü hiç almadığı şeyi bildiremez.
Tam sayı kesinliği. Yaklaşık dokuz katrilyondan büyük bir JSON sayısı bir double'a ayrıştırılmaktan sağ çıkmaz; böylece 12345678901234567890 gibi bir kimlik yuvarlanmış olarak geri gelir. Bu bir YAML sorunu değildir ve bu aracın getirdiği bir sorun değildir; dildeki her JSON ayrıştırıcısında olur. Büyük bir tanımlayıcı önemliyse, her iki tarafta da bir dizeye aittir.
Çıktı hakkında notlar
Girinti her zaman boşluklardır, çünkü YAML girinti için sekmeleri tümüyle yasaklar — bu, biçimin katı olduğu birkaç şeyden biridir. İki boşluk kuraldır; dört, bazı kurum tarzları istediği için sunulur.
Diziler anahtarlarının altında girintilenir. Hem o hem de girintisiz biçim geçerli YAML'dır ve aynı şeyi ifade eder; girintili olan çoğu kişinin yazdığı ve çoğu düzenleyicinin doğru katladığıdır.
Boş bir dizi ya da nesne, akış biçeminde bir çift köşeli ya da süslü parantez olarak yazılır, çünkü blok biçeminin boşluğu ifade etmenin bir yolu yoktur — izleyen satırlarda yazılacak bir şey yoktur.
Çıktı bir satır sonuyla biter ve bu, derli topluluk değil, yük taşıyan bir şeydir. Bir blok skalerinin kırpması, onu izleyen satır sonuna karşı ölçülür; böylece bir dosyanın en sonunda, son bir satır sonu olmadan kırpılmış bir blok, tutması gereken satır sonunu kaybeder.
Sıkça sorulan sorular
- JSON zaten geçerli YAML mı?
- YAML 1.2 altında, evet: belirtim bunu açıkça söyler ve bir 1.2 ayrıştırıcısı bir JSON dosyasını doğrudan okur. Bu pratikte pek işe yaramaz, çünkü dönüştürme nedeni okunabilirliktir — yorumlar, blok skalerleri, süslü parantez yok — ve JSON'u bir YAML dosyasına yapıştırmak size bunların hiçbirini vermez. YAML 1.1 altında tam olarak doğru değildir, ki bu iki sürümü ayırt etmeye değer olmasının bir nedeni daha.
- Dizem neden ihtiyaç duyar görünmediği tırnakları aldı?
- Neredeyse kesinlikle onlara ihtiyaç duyuyor. YAML, tırnaksız bir değeri desenleri eşleştirerek türler; böylece NO, yes, off, 12:30, 0755, 1.10, 2024-01-30 ve boş bir dize hepsi dize olmaktan çıkar. Bulgular paneli her birini adlandırır ve hâline geleceği değeri gösterir; böylece iddia güvenilmek yerine kontrol edilebilir. Bir YAML 1.2 ayrıştırıcısını hedefliyorsanız, şemayı değiştirmek yalnızca 1.1'in gerektirdiklerini kaldırır.
- Burada YAML 1.1 ile 1.2 arasındaki fark nedir?
- 1.2, sürprizlerin çoğuna neden olan çözücüleri bıraktı: yes/no/on/off artık mantıksal değer değil, 60 tabanı gitti ve bir zaman damgası türü yok. PyYAML 1.1'i uygular ve hâlâ her yerdedir; bu yüzden tutucu çıktı varsayılandır; 1.2 ayarı, dosyayı neyin okuyacağını bildiğiniz durum içindir.
- YAML'ı tekrar JSON'a dönüştürebilir mi?
- Hayır, bilerek. Bir YAML okuyucusu çıpalara, takma adlara, etiketlere, birleştirme anahtarlarına, beş skaler biçeme ve iki şema sürümüne ihtiyaç duyar ve bunların herhangi birini ince biçimde yanlış yapmak, bir dosyayı kabul edip içerdiğinden farklı veri döndürmek demektir. O başarısızlık sessizdir, ki bu onu özelliği sunmamaktan daha kötü yapar.
- Kubernetes tarzı çok belgeli bir dosyayı nasıl elde ederim?
- Üst düzey bir dizinin her öğesini kendi belgesi olarak yazan düğmeyi açın, dizi üç tireyle ayrılmış belgeler olur. Girdiniz bunun yerine NDJSON ise — günlüklerin ve API dışa aktarımlarının sıklıkla olduğu gibi satır başına bir JSON nesnesi — bu otomatik algılanır ve çıktının üstünde bildirilir.
- Çıktıda neden yorum yok?
- Çünkü girdide hiç yoktu. Yorumlar, YAML'ın JSON'un sahip olmadığı ana şeydir ve bir dönüştürücü onları uyduramaz. Bunu diğer yönde de hatırlamaya değer: bir YAML dosyasını JSON üzerinden gidip getirirseniz, içindeki her yorum yok olur.
- Yapıştırdığım herhangi bir şey bir sunucuya gönderiliyor mu?
- Hayır. Ayrıştırma ve dönüştürme tümüyle tarayıcınızda çalışır; hiçbir şey yüklenmez ya da günlüğe yazılmaz ve ağ bağlantısı olmadan çalışır.