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.
Kubernetes manifestleri ve dize kalmak zorunda olan alanlar
Kubernetes bir manifesti iki biçimden herhangi biriyle okur. Kendi belgeleri YAML’ı alışılmış biçim diye anar ve JSON’u seçenek olarak söyler; kubectl de isteği yaparken manifesti JSON’a, ya da API’nin desteklediği başka bir serileştirmeye, çevirir. Yani dönüştürme, kümenin neyi kabul edeceğiyle ilgili değildir. Elinizde kalan dosyayla ilgilidir: inceleyenin okuduğu YAML’dır, bir pull request farkının okunabilir olduğu YAML’dır ve ikisinden yalnızca YAML bir yorum taşıyabilir. JSON genellikle kubectl get -o json’dan, bir şablondan ya da nesne döndüren bir API’den gelir.
- Tek dosya, birden çok nesne. Manifestler üç tireyle ayrılarak tek bir dosyada toplanabilir ve belgeler, göründükleri sırayla oluşturulduklarını açıkça söyler — bu yüzden bir Service, onu dolduran Deployment’ın üstüne yazılır. Üst düzey bir dizinin her öğesini kendi belgesi olarak veren düğme, bir JSON nesne listesini işte böyle bir dosyaya çevirir.
- Bir kapsayıcının ortam girdileri iki dize alanıdır. API başvurusu name’i de value’yu da dize olarak bildirir; bu yüzden "true" olan bir JSON değeri tırnaklarıyla çıkmak zorundadır: tırnaksız o bir mantıksal değerdir ve mantıksal değer, alanın tutmak üzere bildirildiği tür değildir.
- Bir kapsayıcı portu tam sayı olarak bildirilir ve o dizelerden birkaç satır ötede durur. İkisi ters işlem ister ve JSON ayrımı zaten taşır: bir sayı yalın sayı olur, bir dize ise yalnızca YAML’ın onu dize okumayı bırakacağı yerde tırnaklanır.
- Etiketler ve açıklama notları dizeden dizeye eşlemelerdir. Norveç sorununun bir manifestin içine indiği yer orasıdır: değeri NO, on ya da off olan bir etiket, YAML 1.1 ayrıştırıcısı için mantıksal değerdir ve 1.10 değeri, sondaki sıfırını yitiren bir kayan sayıdır.
Her değeri dize olan JSON olarak verilen üç ortam girdisi şuna dönüşür:
env:
- name: DEBUG
value: 'true'
- name: REPLICAS
value: '3'
- name: COUNTRY
value: 'NO'Üçü de tırnaklanır ve Bulgular paneli üçünü de her birinin dönüşecek olduğu değerle birlikte adlandırır: true bir mantıksal değer, 3 bir sayı ve NO mantıksal false. Yalnızca sonuncusu sürüme bağlıdır — şemayı 1.2’ye alın ve onun tırnakları düşer, çünkü 1.2 NO’yu metinden başka hiçbir şey olarak okumaz. Diğer ikisi tırnaklarını iki sürümde de korur.
Docker Compose: biçimin kendi başvurusunun YAML konusunda uyardığı yer
Bir Compose dosyası YAML’dır ve Docker’ın ona ayırdığı başvuru, YAML ayrıştırması üzerine iki uyarı taşır. Bir ürünün kendi belgelerinin, kullandığı serileştirme biçimini tehlike olarak anması olağan değildir; iki uyarı da tam olarak bu aracın var olma nedenine dokunur: metin olması istenen bir değeri bir ayrıştırıcının başka bir şey olarak okuması.
- Portlar. Başvuru, bir HOST:CONTAINER eşlemesinin YAML’ın 60 tabanlı kayan sayısıyla çatışmaması için her zaman tırnaklı bir dize olarak verilmesi gerektiğini söyler. Tırnaksız 22:22, 1342 tam sayısıdır.
- Ortam değerleri. Başvuru, ayrıştırıcı onları dönüştürmesin diye true, false, yes ve no sözcüklerinin tırnak içine alınmasını ister. Dördün ikisi YAML’ın iki sürümünde de mantıksal değerdir, ikisi — yes ve no — yalnızca 1.1’de; Bulgular paneli bu yüzden onları farklı işaretler.
- 60 tabanı kuralı yalnızca iki noktadan sonraki sayısı altmıştan küçük olan bir eşlemeye uzanır, çünkü 60 tabanında bir basamağın kapsadığı aralık budur. Bu yüzden 22:22 burada tırnaklanır, 8080:80 yalın kalır ve fark, hangi portların önemli olduğuna dair bir yargı değil kuraldır.
Portları ve ortam değerleri JSON’da tümüyle dize olan bir hizmet şuna dönüşür:
services:
proxy:
image: nginx
ports:
- '22:22'
- 8080:80
environment:
TLS_ENABLED: 'no'
DEBUG: 'true'Başvurunun istediği çıktı budur ve onu üreten şey öntanımlı şemadır. Şemaya dokunmamak için en açık neden de budur: 1.2’ye geçin, port eşlemesi ile no tırnaklarını yitirir, true ise kendi tırnaklarını korur, çünkü 1.2, 60 tabanını bıraktı ve mantıksal değer olarak yalnızca true ile false’ı tuttu. 1.2’yi gerçekleyen bir ayrıştırıcı sonucu yine doğru okur — ama Docker’ın öğüdü böyle hiçbir koşul olmadan yazılmıştır ve ona uymanın bedeli iki çift tırnaktır.
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.
- kubectl’in JSON çıktısını YAML manifestine nasıl dönüştürürüm?
- Yapıştırın ve YAML’ı okuyun. Kubernetes iki biçimi de kabul eder — belgeleri YAML’ı alışılmış biçim, JSON’u seçenek diye anar — dolayısıyla dönüştürme nedeni, kümenin neyi kabul edeceği değil elinizde kalan dosyadır. Denetlenecek olan tırnaklardır: bir manifest, API’nin dize olarak bildirdiği alanlarla doludur; ortam değerleriyle etiket ve açıklama notu değerleri de bunların arasındadır ve YAML’ın türünü değiştireceği alanlar tam olarak bunlardır. JSON birkaç nesnenin listesiyse, çok belgeli düğme onu tek bir dosya yapar.
- Docker Compose portlarımı neden tırnak içinde istiyor?
- Çünkü bir YAML 1.1 ayrıştırıcısı için 22:22 bir sayı çifti değil, 60 tabanında tek bir sayıdır — 1342. Docker’ın Compose başvurusu tam bu nedenle bir HOST:CONTAINER eşlemesinin her zaman tırnaklı bir dize olması gerektiğini söyler; aynı sayfa bir ortam bloğundaki true, false, yes ve no’nun da tırnaklanmasını ister. İkisi de bu aracın öntanımlı şemasıyla yaptığı şeydir ve Bulgular paneli her tırnağın hangi kuraldan geldiğini söyler. İki noktadan sonraki sayısı altmış ya da daha büyük olan bir eşleme, örneğin 8080:80, 60 tabanı kuralının dışındadır ve yalın kalır.
- Kubernetes ya da Docker Compose için hangi YAML sürümünü seçmeliyim?
- Öntanımlı olanı, 1.1. Eklediği her tırnağı bir 1.2 ayrıştırıcısı da kabul eder; bu yüzden ihtiyatlı çıktı her durumda güvenlidir ve Compose başvurusundaki iki uyarı da 1.1 kurallarıyla ilgilidir: 60 tabanındaki port eşlemeleri ile mantıksal değer olarak yes ve no. 1.2 ayarı, hangi tırnakların yalnızca eski şema yüzünden var olduğunu göstermek için vardır; çıktı onları yitirir ve bu, o uyarıların istediğinin tersidir.
İlgili araçlar
- JSON’dan TypeScript’e
Bir JSON örneğinden TypeScript arayüzleri çıkarın.
- JSONPath test aracı
RFC 9535 JSONPath sorgularını JSON’a karşı test edin.
- Markdown tablo oluşturucu
CSV, TSV veya JSON verisinden Markdown tablosu oluşturun.
- PDF birleştirme
Birden çok PDF’yi seçtiğiniz sırayla tek dosyada birleştirin — hiçbir şey yüklenmez.