Converteer YAML-array naar Java-lijst met SnakeYAML

Introductie

Yamla is een van de meest populaire talen voor gegevensserialisatie na JSON. Daarom wordt het soms a . genoemd streng superset van JSON. Het is vanaf het begin ontworpen voor menselijke interactie en leesbaarheid, vandaar dat het bekend staat om zijn eenvoud. Het is ontworpen met flexibiliteit en toegankelijkheid in het achterhoofd, dus het werkt met alle moderne programmeertalen en een krachtig formaat voor het schrijven van configuratiebestanden. Het wordt ook gebruikt voor gegevenspersistentie, internetberichten, het delen van gegevens in meerdere talen en nog veel meer opties.

YAML is gestart in 2001 en werd genoemd als "Nog een andere opmaaktaal" in die tijd. Maar later werd het handelsmerk als "YAML is geen opmaaktaal“. De basisstructuur van een YAML-bestand is a kaart. Het is ook bekend als een woordenboek, hash (kaart) of gewoon object-gebaseerd op de programmeertaal die we kiezen om te gebruiken.

Witruimte en inspringing worden in YAML-bestanden gebruikt om nesten aan te duiden.

Note: Alleen spaties mogen worden gebruikt voor inspringen in YAML-bestanden; tabtekens zijn niet toegestaan. Zolang de inspringing consequent wordt gedaan, maakt het niet uit hoeveel spaties worden gebruikt.

YAML-syntaxis

Een YAML-indeling gebruikt voornamelijk 3 knooppunttypen:

  • Kaarten/Woordenboeken: A kaart node's content is een ongeordende verzameling van sleutel waarde knooppunt paren, met de eis dat elke sleutel verschillend moet zijn. YAML legt geen verdere beperkingen op aan de nodes.
  • Arrays/lijsten: An reeks de inhoud van een knooppunt is een geordende verzameling van nul of meer knooppunten. Een reeks kan in het bijzonder hetzelfde knooppunt meer dan eens bevatten. Het kan zelfs zichzelf bevatten.
  • Letterlijke (Tekenreeksen, getallen, boolean, enz.): Een reeks van nul of meer Unicode-tekens kan worden gebruikt om de ondoorzichtige gegevens weer te geven waaruit een scalair inhoud van het knooppunt.

In dit artikel zullen we specifiek kijken naar het converteren van YAML-array-inhoud naar een lijst in Java. Er zijn veel open-sourcebibliotheken beschikbaar, maar de meest populaire daarvan zijn Jackson en SlangYAML. In deze handleiding zullen we SnakeYaml gebruiken als onze bibliotheek om de YAML-inhoud te ontleden.

SlangYaml

SlangYAML is een YAML-parsingpakket dat een API op hoog niveau biedt voor YAML-documentserialisatie en deserialisatie. Het toegangspunt voor SnakeYAML is de Yaml klas. De documenten of de YAML-bestanden kunnen worden geladen met: load() methode of in batch via de loadAll() methode. De methoden gebruiken echte YAML-gegevens in de vorm van String-objecten en ook: InputStreams, wat een typisch bestandstype is om tegen te komen.

Gezien : structuur aangeboren in YAML-bestanden, SnakeYAML werkt natuurlijk goed met Java-kaarten, maar we kunnen ook unique . gebruiken Java-objecten.

Om de bibliotheek in ons project op te nemen, voegt u de volgende afhankelijkheid toe aan uw pom.xml file:

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

Of, als u Gradle gebruikt:

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

Een eenvoudige YAML-array lezen

Laten we snel beginnen met het lezen van een eenvoudige array uit een YAML-bestand. Bedenk dat we een yaml-bestand hebben met de volgende gegevens in de bronnenmap van ons Java-project:

- One
- Two
- Three
- Four

Dan kunnen we de bestandsinhoud laden als een InputStream. Vervolgens construeren we de Yaml instantie die dan zal fungeren als een toegangspunt voor toegang tot de bibliotheek en het object om de inhoud van het YAML-bestand programmatisch weer te geven. De load() methode stelt ons in staat om elke te lezen en te ontleden InputStream met geldige YAML-gegevens:

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

De methode retourneert een Java List van String-gegevens. Als we de . afdrukken data dan geeft het het volgende resultaat:

[One, Two, Three, Four]

Een YAML-gegroepeerde array lezen

Soms willen we een array van inhoud definiëren voor een bepaalde sleutel. Dit wordt het groeperen van arrays in een YAML-kaartknooppunt genoemd. Een voorbeeld van een dergelijke YAML ziet er als volgt uit:

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

Dit kan worden beschouwd als Java Map met een : waar de waarde een is reeks. Dus de gegevens worden nog steeds geladen als: InputStream zoals we hierboven hebben gedefinieerd. Maar de data moet worden gedefinieerd als 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);
}

Als we nu onze . lezen data, zou het er ongeveer zo uit zien:

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

Een YAML multi-line array van arrays lezen

Soms komen we een YAML-bestand tegen met gegevens die een reeks arrays bevatten. We groeperen bijvoorbeeld de cursussen en vertegenwoordigen ze als een reeks arrays zoals hieronder:

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

Dit kan worden geparseerd als Java Map of List of List of String. We kunnen de . opnieuw laden InputStream zoals we eerder deden. Maar de gegevens worden geladen zoals hieronder:

Bekijk onze praktische, praktische gids voor het leren van Git, met best-practices, door de industrie geaccepteerde normen en bijgevoegd spiekbriefje. Stop met Googlen op Git-commando's en eigenlijk leren het!

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

Dus als we de . afdrukken data, zou het er ongeveer als volgt uit kunnen zien:

{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

Een complexe geneste YAML-inhoud lezen als Java Bean

We hebben gezien hoe we de inhoud van het array-type afzonderlijk kunnen verwerken, maar met complexe geneste YAML-bestanden - het hebben van een kaart met kaarten met lijsten met lijsten is moeilijk intuïtief te doorgronden en moeilijk om mee om te gaan. Zelfs in het laatste voorbeeld, waar we slechts twee geneste lijsten hadden, wordt het behoorlijk uitgebreid om ze als lijsten te behandelen.

In deze gevallen is het het beste om een ​​POJO te maken die kan worden toegewezen aan de geneste YAML-gegevens. Laten we eerst een voorbeeld-YAML maken met de geneste inhoud van een website:

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

We moeten een bovenliggende Java-klasse definiëren WebsiteContent dat zal bestaan ​​uit List van vaardigheden en een List of Map van tutorials die weer lijsten met tags en bijdragers zullen bevatten:

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

Nu kunnen we de gegevens uit het bestand opnieuw laden als InputStream zoals we eerder deden. Volgende wanneer we onze . maken Yaml class-object, moeten we het gegevenstype opgeven waarnaar we de gegevens willen casten. De new Constructor(WebsiteContent.class) vertelt SnakeYAML om de gegevens van het YAML-bestand te lezen en toe te wijzen aan onze WebsiteContent voorwerp.

De toewijzing is eenvoudig en de namen van onze objectkenmerken moeten overeenkomen met de namen van de YAML-kenmerken.

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

Eindelijk, wanneer we de . afdrukken data, zou het er ongeveer als volgt uit kunnen zien:

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

Zoals we kunnen zien, heeft SnakeYaml met succes de . geparseerd en geconverteerd WebsiteContent bezwaar en hield de erfenis en associatie met Tutorial voorwerp intact.

Conclusie

Omdat YAML-bestanden veel worden gebruikt voor DevOps- en configuratiegerelateerde gegevens, is het best handig om de gegevens te ontleden en te manipuleren met behulp van code.

SnakeYAML stelt ons in staat om gemakkelijk YAML-bestanden in ons Java-project te beheren, en het vereist slechts een klein beetje code om YAML-bestanden in ons project te laden of gegevens naar YAML-bestanden te schrijven. Bovendien biedt SnakeYAML opmaakkeuzes, zodat u het kunt aanpassen en personaliseren om aan onze behoeften te voldoen.

Tijdstempel:

Meer van Stapelmisbruik