Konwertuj tablicę YAML na listę Java za pomocą SnakeYAML

Wprowadzenie

YAM jest jednym z najpopularniejszych języków serializacji danych po JSON. Dlatego czasami nazywa się to rygorystyczny nadzbiór JSON. Został zaprojektowany z myślą o interakcji i czytelności z człowiekiem od samego początku, dlatego jest znany ze swojej prostoty. Został zaprojektowany z myślą o elastyczności i dostępności, dzięki czemu działa ze wszystkimi nowoczesnymi językami programowania i potężnym formatem do zapisywania plików konfiguracyjnych. Jest również używany do utrwalania danych, przesyłania wiadomości internetowych, udostępniania danych w wielu językach i wielu innych opcji.

YAML powstał w 2001 roku i był określany jako „Jeszcze inny język znaczników" w tym czasie. Ale później został oznaczony jako „YAML nie jest językiem znaczników“. Podstawowa struktura pliku YAML to mapa. Znany jest również jako słownik, hash (mapa) lub po prostu obiekt oparty na języku programowania, którego używamy.

Białe znaki i wcięcia są używane w plikach YAML do oznaczania zagnieżdżenia.

Note: Tylko spacje mogą być używane do wcięć w plikach YAML; znaki tabulacji nie są dozwolone. Dopóki wcięcie jest wykonywane konsekwentnie, nie ma znaczenia, ile spacji zostanie wykorzystanych.

Składnia YAML

Format YAML wykorzystuje głównie 3 typy węzłów:

  • Mapy/Słowniki: mapa zawartość węzła jest nieuporządkowaną kolekcją kluczowa wartość węzeł par, z wymaganiem, aby każdy klucz był odrębny. YAML nie nakłada żadnych dalszych ograniczeń na węzły.
  • Tablice/Listy: AN szyk zawartość węzła jest uporządkowaną kolekcją zerową lub większą liczbą węzłów. W szczególności sekwencja może zawierać ten sam węzeł więcej niż raz. Może zawierać nawet siebie.
  • Literały (Ciągi, liczby, wartości logiczne itp.): Sekwencja zero lub więcej Znaki Unicode może służyć do reprezentowania nieprzezroczystych danych, które składają się na skalarny zawartość węzła.

W tym artykule przyjrzymy się konkretnie konwersji zawartości tablicy YAML na Listę w Javie. Dostępnych jest wiele bibliotek open-source, ale najpopularniejsze z nich to Jackson i WążYAML. W tym przewodniku użyjemy SnakeYaml jako naszej biblioteki do analizowania zawartości YAML.

WążYaml

WążYAML to pakiet analizujący YAML, który oferuje interfejs API wysokiego poziomu do serializacji i deserializacji dokumentów YAML. Punktem wejścia dla SnakeYAML jest Yaml klasa. Dokumenty lub pliki YAML można załadować za pomocą load() metoda lub w partii za pośrednictwem loadAll() metoda. Metody pobierają oryginalne dane YAML w postaci obiektów String oraz InputStreams, który jest typowym typem pliku, który można napotkać.

Biorąc pod uwagę : struktura wrodzona do plików YAML, SnakeYAML naturalnie działa dobrze Mapy Java, ale możemy też użyć unikalnych Obiekty Java.

Aby włączyć bibliotekę do naszego projektu, dodaj następującą zależność do swojego pom.xml file:

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

Lub, jeśli używasz Gradle:

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

Czytanie prostej tablicy YAML

Zacznijmy szybko od odczytania prostej tablicy z pliku YAML. Weź pod uwagę, że mamy plik yaml z następującymi danymi w folderze zasobów naszego projektu Java:

- One
- Two
- Three
- Four

Następnie możemy załadować zawartość pliku jako InputStream. Następnie zbudujemy Yaml wystąpienie, które następnie będzie działać jako punkt wejścia do dostępu do biblioteki i obiektu, aby programowo reprezentować zawartość pliku YAML. The load() metoda pozwala nam czytać i analizować dowolne InputStream z prawidłowymi danymi YAML:

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

Metoda zwróci Java List danych ciągu. Jeśli wydrukujemy data wtedy da następujący wynik:

[One, Two, Three, Four]

Odczytywanie zgrupowanej tablicy YAML

Czasami chcielibyśmy zdefiniować tablicę treści dla danego klucza. Nazywa się to grupowaniem tablic w węzeł mapy YAML. Przykładowy YAML tego typu wygląda jak poniżej:

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

Można to uznać za Java Map zawierający a : gdzie wartość to an szyk. Więc dane będą nadal ładowane jako InputStream jak zdefiniowaliśmy powyżej. Ale data musi być zdefiniowany jako 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);
}

Teraz, jeśli czytamy nasze data, wyglądałoby to mniej więcej tak:

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

Odczytywanie wieloliniowej tablicy tablic YAML

Czasami natykamy się na plik YAML zawierający dane zawierające tablicę tablic. Na przykład grupujemy kursy i przedstawiamy je jako tablice tablic, jak poniżej:

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

Można to przeanalizować jako Java Map of List of List of String. Możemy ponownie załadować InputStream tak jak wcześniej. Ale dane zostaną załadowane jak poniżej:

Zapoznaj się z naszym praktycznym, praktycznym przewodnikiem dotyczącym nauki Git, zawierającym najlepsze praktyki, standardy przyjęte w branży i dołączoną ściągawkę. Zatrzymaj polecenia Google Git, a właściwie uczyć się to!

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);
}

Więc jeśli wypiszemy data, wyglądałoby to mniej więcej tak:

{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

Odczytywanie złożonej zagnieżdżonej treści YAML jako Java Bean

Widzieliśmy, jak możemy osobno obsługiwać zawartość typu tablica, ale ze złożonymi zagnieżdżonymi plikami YAML – posiadanie mapy map z listami list jest trudne do intuicyjnego przeanalizowania i trudne w obsłudze. Nawet w ostatnim przykładzie, w którym mieliśmy tylko dwie zagnieżdżone listy – obsługa ich jako list staje się dość szczegółowa.

W takich przypadkach najlepiej jest utworzyć POJO, które można zmapować na zagnieżdżone dane YAML. Najpierw utwórzmy przykładowy YAML zawierający zagnieżdżoną zawartość witryny:

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

Musimy zdefiniować nadrzędną klasę Javy WebsiteContent który będzie składał się z List umiejętności i List of Map samouczków, które ponownie będą zawierały listy tagów i współtwórców:

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 + ''' +
                '}';
    }
}

Teraz możemy ponownie załadować dane z pliku jako InputStream tak jak wcześniej. Następnie, gdy tworzymy nasze Yaml obiekt klasy, musimy określić typ danych, na który chcemy rzutować dane. The new Constructor(WebsiteContent.class) mówi SnakeYAML, aby odczytał dane z pliku YAML mapując je do naszego WebsiteContent obiekt.

Mapowanie jest proste, a nazwy naszych atrybutów obiektów muszą odpowiadać nazwom atrybutów YAML.

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);
}

Wreszcie, kiedy drukujemy data, wyglądałoby to mniej więcej tak:

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}}

Jak widać, SnakeYaml pomyślnie przeanalizował i przekonwertował WebsiteContent sprzeciwiać się i zachować spadek i związek z Tutorial obiekt nienaruszony.

Wnioski

Ponieważ pliki YAML są szeroko używane w przypadku DevOps i danych związanych z konfiguracją, bardzo przydatne jest analizowanie i manipulowanie danymi za pomocą kodu.

SnakeYAML pozwala nam z łatwością zarządzać plikami YAML w naszym projekcie Java i wymaga tylko odrobiny kodu, aby załadować pliki YAML do naszego projektu lub zapisać dane w plikach YAML. Dodatkowo SnakeYAML oferuje opcje formatowania, dzięki czemu możesz dostosować i spersonalizować go zgodnie z naszymi potrzebami.

Znak czasu:

Więcej z Nadużycie stosu