Zephyrnet-logotyp

Konvertera YAML Array till Java List med SnakeYAML

Datum:

Beskrivning

YAML är ett av de mest populära dataserialiseringsspråken efter JSON. Därför kallas det ibland som en sträng superset av JSON. Den har designats för mänsklig interaktion och läsbarhet redan från början, därför är den känd för sin enkelhet. Den är designad med flexibilitet och tillgänglighet i åtanke, så den fungerar med alla moderna programmeringsspråk och ett kraftfullt format för att skriva konfigurationsfiler. Det används också för databeständighet, internetmeddelanden, datadelning över flera språk och många fler alternativ.

YAML startades 2001 och kallades "Ännu ett märkningsspråk" vid den tiden. Men senare var det varumärkesskyddat som "YAML Ain't Markup Language". Den grundläggande strukturen för en YAML-fil är en karta. Det är också känt som en ordbok, hash(karta) eller helt enkelt objektbaserat på det programmeringsspråk som vi väljer att använda.

Blanksteg och indrag används i YAML-filer för att beteckna kapsling.

Anmärkningar: Endast mellanslag får användas för indrag i YAML-filer; tabbtecken är inte tillåtna. Så länge indragningen görs konsekvent spelar det ingen roll hur många utrymmen som används.

YAML-syntax

Ett YAML-format använder i första hand 3 nodtyper:

  • Kartor/ordböcker: En karta nodens innehåll är en oordnad samling av nyckelvärde nod par, med kravet att varje nyckel måste vara distinkt. Inga ytterligare begränsningar påläggs noderna av YAML.
  • Arrayer/listor: En array nodens innehåll är en ordnad samling av noll eller fler noder. En sekvens kan i synnerhet inkludera samma nod mer än en gång. Den kan även innehålla sig själv.
  • Bokstäver (Strängar, tal, booleska, etc.): En sekvens med noll eller mer Unicode-tecken kan användas för att representera de ogenomskinliga data som utgör en skalär nodens innehåll.

I den här artikeln kommer vi specifikt att ta en titt på att konvertera YAML-arrayinnehåll till en lista i Java. Det finns massor av öppen källkodsbibliotek tillgängliga men de mest populära av dem är Jackson och SnakeYAML. I den här guiden kommer vi att använda SnakeYaml som vårt bibliotek för att analysera YAML-innehållet.

SnakeYaml

SnakeYAML är ett YAML-parsningspaket som erbjuder ett högnivå-API för YAML-dokumentserialisering och deserialisering. Ingångspunkten för SnakeYAML är Yaml klass. Dokumenten eller YAML-filerna kan laddas med load() metod eller i batch via loadAll() metod. Metoderna tar äkta YAML-data i form av String-objekt såväl som InputStreams, vilket är en typisk filtyp att stöta på.

Med tanke på : struktur medfödd till YAML-filer, fungerar SnakeYAML naturligtvis bra med Java-kartor, men vi kan också använda unika Java-objekt.

För att inkludera biblioteket i vårt projekt, lägg till följande beroende till din pom.xml fil:

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

Eller om du använder Gradle:

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

Läsa en enkel YAML-array

Låt oss snabbt börja med att läsa en enkel array från en YAML-fil. Tänk på att vi har en yaml-fil med följande data i vårt Java-projekts resursmapp:

- One
- Two
- Three
- Four

Sedan kan vi ladda filinnehållet som en InputStream. Därefter kommer vi att konstruera Yaml instans som sedan kommer att fungera som en ingångspunkt för åtkomst till biblioteket och objektet för att representera YAML-filens innehåll programmatiskt. De load() metoden låter oss läsa och analysera alla InputStream med giltig YAML-data:

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

Metoden returnerar en Java List av strängdata. Om vi ​​skriver ut data då kommer det att ge följande resultat:

[One, Two, Three, Four]

Läsa en YAML Grouped Array

Ibland skulle vi vilja definiera en uppsättning innehåll mot en given nyckel. Detta kallas gruppering av arrayer till en YAML-kartanod. Ett exempel på YAML av sådan sort ser ut som nedan:

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

Detta kan betraktas som Java Map som innehåller en : där värdet är an array. Så data kommer fortfarande att laddas som InputStream som vi definierat ovan. Men data måste definieras som 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);
}

Om vi ​​nu läser vår data, det skulle se ut ungefär så här:

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

Läsa en YAML Multi-Line Array of Array

Ibland stöter vi på en YAML-fil med data som innehåller en array av arrayer. Till exempel grupperar vi kurserna och representerar dem som en rad matriser som nedan:

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

Detta kan tolkas som Java Map of List of List of String. Vi kan ladda igen InputStream som vi gjorde tidigare. Men data kommer att laddas enligt nedan:

Kolla in vår praktiska, praktiska guide för att lära dig Git, med bästa praxis, branschaccepterade standarder och medföljande fuskblad. Sluta googla Git-kommandon och faktiskt lära Det!

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

Så om vi skriver ut data, det skulle se ut ungefär så här:

{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

Läsa ett komplext kapslat YAML-innehåll som Java Bean

Vi såg hur vi kan hantera innehållet av arraytyp separat, men med komplexa kapslade YAML-filer – att ha en karta över kartor med listor är svårt att intuitivt analysera och svårt att hantera. Även i det sista exemplet där vi bara hade två kapslade listor – att hantera dem som listor blir ganska utförligt.

I dessa fall är det bäst att skapa en POJO som kan mappas till kapslade YAML-data. Låt oss först skapa ett exempel på YAML som innehåller det kapslade innehållet på en webbplats:

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

Vi måste definiera en överordnad Java-klass WebsiteContent som kommer att bestå av List av kompetens och en List of Map av handledningar som återigen kommer att innehålla listor med taggar och bidragsgivare:

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 kan vi återigen ladda data från filen som InputStream som vi gjorde tidigare. Nästa när vi skapar vår Yaml klassobjekt måste vi ange vilken datatyp vi vill casta data till. De new Constructor(WebsiteContent.class) säger till SnakeYAML att läsa data från YAML-filen mappa den till vår WebsiteContent objekt.

Mappningen är enkel och namnen på våra objektattribut måste matcha namnen på YAML-attributen.

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

Slutligen, när vi skriver ut data, det skulle se ut ungefär så här:

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

Som vi kan se har SnakeYaml framgångsrikt analyserat och konverterat WebsiteContent föremål och behöll arvet och föreningen med Tutorial föremål intakt.

Slutsats

Eftersom YAML-filer används i stor utsträckning för DevOps och konfigurationsrelaterad data, är det ganska användbart att analysera och manipulera data med hjälp av kod.

SnakeYAML låter oss hantera YAML-filer i vårt Java-projekt med lätthet, och det kräver bara lite kod för att ladda YAML-filer till vårt projekt eller skriva data till YAML-filer. Dessutom erbjuder SnakeYAML formateringsval så att du kan justera och anpassa den för att passa våra behov.

plats_img

Senaste intelligens

plats_img