SnakeYAML ile YAML Dizisini Java Listesine Dönüştürün

Giriş

YAML sonra en popüler veri serileştirme dillerinden biridir. JSON. Bu nedenle, bazen olarak adlandırılır sıkı süperset JSON'un. Başından beri insan etkileşimi ve okunabilirlik için tasarlanmıştır, bu nedenle sadeliği ile bilinir. Esneklik ve erişilebilirlik göz önünde bulundurularak tasarlanmıştır, bu nedenle tüm modern programlama dilleriyle ve yapılandırma dosyalarını yazmak için güçlü bir formatla çalışır. Ayrıca veri kalıcılığı, internet mesajlaşması, diller arası veri paylaşımı ve daha birçok seçenek için kullanılır.

YAML 2001 yılında başlatıldı ve “Yine Başka Bir İşaretleme Dili" o zamanda. Ancak daha sonra ticari marka olarak “YAML Biçimlendirme Dili Değildir“. YAML dosyasının temel yapısı, harita. Kullanmayı tercih ettiğimiz programlama diline bağlı olarak bir sözlük, karma (harita) veya basitçe nesne tabanlı olarak da bilinir.

Boşluk ve girinti, YAML dosyalarında yuvalamayı belirtmek için kullanılır.

not: YAML dosyalarında girinti için yalnızca boşluk kullanılabilir; sekme karakterlerine izin verilmez. Girinti tutarlı bir şekilde yapıldığı sürece, kaç boşluk kullanıldığı önemli değildir.

YAML Sözdizimi

Bir YAML biçimi öncelikle 3 düğüm türü kullanır:

  • Haritalar/Sözlükler: A harita düğümün içeriği, sıralanmamış bir koleksiyondur. anahtar/değer düğüm çiftleri, her anahtarın farklı olması şartıyla. YAML tarafından düğümlere başka sınırlamalar getirilmez.
  • Diziler/Listeler: bir dizi düğümün içeriği, sıfır veya daha fazla düğümden oluşan sıralı bir koleksiyondur. Bir sekans, özellikle aynı düğümü birden fazla içerebilir. Kendini bile içerebilir.
  • Değişmez (Dizeler, sayılar, boole vb.): Sıfır veya daha fazla bir dizi Unicode karakterler oluşturan opak verileri temsil etmek için kullanılabilir. sayısal düğümün içeriği.

Bu yazıda, özellikle YAML dizisi içeriğini Java'da bir Listeye dönüştürmeye göz atacağız. Pek çok açık kaynak kitaplık mevcuttur, ancak bunlardan en popüler olanları Jackson ve YılanYAML. Bu kılavuzda, YAML içeriğini ayrıştırmak için kitaplığımız olarak SnakeYaml'ı kullanacağız.

YılanYaml

YılanYAML YAML belge serileştirme ve serisini kaldırma için üst düzey bir API sunan bir YAML ayrıştırma paketidir. SnakeYAML için giriş noktası Yaml sınıf. Belgeler veya YAML dosyaları kullanılarak yüklenebilir. load() yöntemiyle veya toplu olarak loadAll() yöntem. Yöntemler, orijinal YAML verilerini String nesneleri biçiminde ve ayrıca InputStreams, karşılaşılması gereken tipik bir dosya türüdür.

Göz önüne alındığında : YAML dosyalarına özgü bir yapıya sahip olan SnakeYAML, doğal olarak Java Haritaları, ancak benzersiz de kullanabiliriz Java nesneleri.

Kütüphaneyi projemize dahil etmek için, aşağıdaki bağımlılığı ekleyin. pom.xml Dosya:

<dependencies>
    <dependency>
        <groupId>org.yaml</groupId>
        <artifactId>snakeyaml</artifactId>
        <version>1.33</version>
    </dependency>
</dependencies>

Veya Gradle kullanıyorsanız:

compile group: 'org.yaml', name: 'snakeyaml', version: '1.33'

Basit Bir YAML Dizisini Okumak

Bir YAML dosyasından basit bir dizi okuyarak hızlıca başlayalım. Java projemizin kaynaklar klasöründe aşağıdaki verileri içeren bir yaml dosyamız olduğunu düşünün:

- One
- Two
- Three
- Four

Ardından dosya içeriğini bir InputStream. Ardından, Yaml daha sonra kitaplığa erişim için bir giriş noktası görevi görecek örnek ve programlı olarak YAML dosya içeriğini temsil eden nesne. bu load() yöntem, herhangi bir şeyi okumamıza ve ayrıştırmamıza izin verir. InputStream geçerli YAML verileriyle:

public void readYamlWithArray() {
    InputStream inputStream = this.getClass()
            .getClassLoader()
            .getResourceAsStream("number.yml");
    Yaml yaml = new Yaml();
    List data = yaml.load(inputStream);
    System.out.println(data);
 }

Yöntem bir Java döndürür List dizi verileri. yazdırırsak data o zaman aşağıdaki sonucu verecektir:

[One, Two, Three, Four]

YAML Gruplandırılmış Dizi Okuma

Bazen belirli bir anahtara karşı bir dizi içerik tanımlamak isteriz. Buna dizilerin bir YAML harita düğümünde gruplandırılması denir. Bu tür bir örnek YAML aşağıdaki gibi görünür:

languages:
  - Java
  - JavaScript
  - Python
  - Golang
  - Perl
  - Shell
  - Scala

Bu Java olarak kabul edilebilir Map içeren : değerin bir olduğu yerde dizi. Böylece veriler hala şu şekilde yüklenecektir: InputStream yukarıda tanımladığımız gibi. Ama data olarak tanımlanmalıdır Map of List of Strings:

public void readYamlWithArrayGroup() {
    InputStream inputStream = this.getClass()
            .getClassLoader()
            .getResourceAsStream("language.yml");
    Yaml yaml = new Yaml();
    Map<String, List> data = yaml.load(inputStream);
    System.out.println(data);
    
    data.values()
            .stream()
            .collect(Collectors.toList())
            .get(0)
            .forEach(System.out::println);
}

Şimdi bizimkini okursak data, şuna benzer bir şey olurdu:

{languages=[Java, JavaScript, Python, Golang, Perl, Shell, Scala]}
Java
JavaScript
Python
Golang
Perl
Shell
Scala

YAML Çok Satırlı Dizi Dizisini Okuma

Bazen dizi dizisini içeren verilere sahip bir YAML dosyasıyla karşılaşırız. Örneğin, kursları gruplandırıyoruz ve aşağıdaki gibi diziler halinde temsil ediyoruz:

courses:
  - - C
    - Java
    - Data Structures
    - Algorithms
  - - Big Data
    - Spark
    - Kafka
    - Machine Learning

Bu, Java olarak ayrıştırılabilir Map of List of List of String. tekrar yükleyebiliriz InputStream Daha önce yaptığımız gibi. Ancak veriler aşağıdaki gibi yüklenecektir:

En iyi uygulamalar, endüstri tarafından kabul edilen standartlar ve dahil edilen hile sayfası ile Git'i öğrenmek için uygulamalı, pratik kılavuzumuza göz atın. Googling Git komutlarını durdurun ve aslında öğrenmek o!

public void readYamlWithMultiLineArrayGroup() {
    InputStream inputStream = this.getClass()
            .getClassLoader()
            .getResourceAsStream("courses.yml");
    Yaml yaml = new Yaml();
    
    Map<String, List<List>> data = yaml.load(inputStream);
    System.out.println(data);
    
    System.out.println("First Array Group:");
    data.values()
            .stream()
            .collect(Collectors.toList())
            .get(0)
            .get(0)
            .forEach(System.out::println);
    
    System.out.println("nSecond Array Group:");
    data.values()
            .stream()
            .collect(Collectors.toList())
            .get(0)
            .get(1)
            .forEach(System.out::println);
}

Yani yazdırırsak data, aşağıdakine benzer bir şey olurdu:

{courses=[[C, Java, Data Structures, Algorithms], [Big Data, Spark, Kafka, Machine Learning]]}

First Array Group:
C
Java
Data Structures
Algorithms

Second Array Group:
Big Data
Spark
Kafka
Machine Learning

Karmaşık İç İçe YAML İçeriğini Java Bean Olarak Okumak

Dizi tipi içeriği ayrı ayrı, ancak karmaşık iç içe YAML dosyalarıyla nasıl ele alabileceğimizi gördük; liste listeleri içeren bir harita haritasına sahip olmak sezgisel olarak ayrıştırmak ve uğraşmak zordur. Yalnızca iki iç içe geçmiş listemizin olduğu son örnekte bile – onları listeler olarak ele almak oldukça ayrıntılı hale geliyor.

Bu durumlarda, iç içe YAML verileriyle eşlenebilecek bir POJO oluşturmak en iyisidir.Önce bir web sitesinin iç içe içeriğini içeren örnek bir YAML oluşturalım:

website: stackabuse
skills:
  - python
  - javascript
  - java
  - unix
  - machine learning
  - web development
tutorials:
  - graphs:
      name: Graphs in Python - Theory and Implementation
      tags:
        - python
        - data structures
        - algorithm
      contributors:
        - David Landup
        - Dimitrije Stamenic
        - Jovana Ninkovic
      last_updated: June 2022
  - git:
      name: Git Essentials - Developer's Guide to Git
      tags:
        - git
      contributors:
        - David Landup
        - François Dupire
        - Jovana Ninkovic
      last_updated: April 2022
  - deep learning:
      name: Practical Deep Learning for Computer Vision with Python
      tags:
        - python
        - machine learning
        - tensorflow
        - computer vision
      contributors:
        - David Landup
        - Jovana Ninkovic
      last_updated: October 2022
published: true

Bir ebeveyn Java sınıfı tanımlamamız gerekiyor WebsiteContent bundan oluşacak List becerilerin ve bir List of Map Yine etiketlerin ve katkıda bulunanların listelerini içerecek olan öğreticilerin sayısı:

public class WebsiteContent {
    private String website;
    private List skills;
    private List<Map> tutorials;
    private Boolean published;

    

    @Override
    public String toString() {
        return "WebsiteContent{" +
                "website='" + website + ''' +
                ", skills=" + skills +
                ", tutorials=" + tutorials +
                ", published=" + published +
                '}';
    }
}
public class Tutorial {

    private String name;
    private List tags;
    private List contributors;
    private String lastUpdated;

    

    @Override
    public String toString() {
        return "Tutorial{" +
                "name='" + name + ''' +
                ", tags=" + tags +
                ", contributors=" + contributors +
                ", lastUpdated='" + lastUpdated + ''' +
                '}';
    }
}

Artık verileri dosyadan tekrar yükleyebiliriz. InputStream Daha önce yaptığımız gibi. Sonraki oluşturduğumuzda Yaml class nesnesinde, verileri içine dökmek istediğimiz veri türünü belirtmemiz gerekir. bu new Constructor(WebsiteContent.class) SnakeYAML'a YAML dosyasındaki verileri okumasını söyler. WebsiteContent nesne.

Eşleme basittir ve nesne özniteliklerimizin adları, YAML özniteliklerinin adlarıyla eşleşmelidir.

public void readYamlAsBeanWithNestedArrays(){
    
    InputStream inputStream = this.getClass()
            .getClassLoader()
            .getResourceAsStream("website_content.yml");
            
    
    Yaml yaml = new Yaml(new Constructor(WebsiteContent.class));
    WebsiteContent data = yaml.load(inputStream);
    
    
    System.out.println(data);
    System.out.println("nList of Skills: ");
    data.getSkills().stream().forEach(System.out::println);
    System.out.println("nList of Tutorials: ");
    data.getTutorials().stream().forEach(System.out::println);
}

Son olarak yazdırdığımızda data, aşağıdakine benzer bir şey olurdu:

WebsiteContent{website='stackabuse', skills=[python, javascript, java, unix, machine learning, web development], tutorials=[{graphs={name=Graphs in Python - Theory and Implementation, tags=[python, data structures, algorithm], contributors=[David Landup, Dimitrije Stamenic, Jovana Ninkovic], last_updated=June 2022}}, {git={name=Git Essentials - Developer's Guide to Git, tags=[git], contributors=[David Landup, François Dupire, Jovana Ninkovic], last_updated=April 2022}}, {deep learning={name=Practical Deep Learning for Computer Vision with Python, tags=[python, machine learning, tensorflow, computer vision], contributors=[David Landup, Jovana Ninkovic], last_updated=October 2022}}], published=true}

List of Skills: 
python
javascript
java
unix
machine learning
web development

List of Tutorials: 
{graphs={name=Graphs in Python - Theory and Implementation, tags=[python, data structures, algorithm], contributors=[David Landup, Dimitrije Stamenic, Jovana Ninkovic], last_updated=June 2022}}
{git={name=Git Essentials - Developer's Guide to Git, tags=[git], contributors=[David Landup, François Dupire, Jovana Ninkovic], last_updated=April 2022}}
{deep learning={name=Practical Deep Learning for Computer Vision with Python, tags=[python, machine learning, tensorflow, computer vision], contributors=[David Landup, Jovana Ninkovic], last_updated=October 2022}}

Gördüğümüz gibi, SnakeYaml başarılı bir şekilde ayrıştırdı ve dönüştürdü. WebsiteContent nesne ve mirası ve ilişkilendirmeyi korudu Tutorial nesne bozulmamış.

Sonuç

YAML dosyaları, DevOps ve yapılandırmayla ilgili veriler için yaygın olarak kullanıldığından, verileri kod kullanarak ayrıştırmak ve değiştirmek oldukça yararlıdır.

SnakeYAML, Java projemizdeki YAML dosyalarını kolaylıkla yönetmemizi sağlar ve YAML dosyalarını projemize yüklemek veya YAML dosyalarına veri yazmak için yalnızca biraz kod gerektirir. Ek olarak, SnakeYAML biçimlendirme seçenekleri sunar, böylece onu ihtiyaçlarımıza göre ayarlayabilir ve kişiselleştirebilirsiniz.

Zaman Damgası:

Den fazla Yığın kötüye kullanımı