Introduktion
YAML er et af de mest populære dataserialiseringssprog efter JSON. Derfor kaldes det nogle gange som en streng supersæt af JSON. Den er designet til menneskelig interaktion og læsbarhed lige fra begyndelsen, og derfor er den kendt for sin enkelhed. Det er designet med fleksibilitet og tilgængelighed i tankerne, så det fungerer med alle moderne programmeringssprog og et kraftfuldt format til at skrive konfigurationsfiler. Det bruges også til datapersistens, internetmeddelelser, datadeling på tværs af sprog og mange flere muligheder.
YAML blev startet i 2001 og blev betegnet som "Endnu et Markup Language" på det tidspunkt. Men senere blev det varemærket som "YAML Ain't Markup Language“. Den grundlæggende struktur af en YAML-fil er en kort. Det er også kendt som en ordbog, hash(map) eller blot objektbaseret på det programmeringssprog, som vi vælger at bruge.
Mellemrum og indrykning bruges i YAML-filer til at angive indlejring.
Bemærk: Kun mellemrum må bruges til indrykning i YAML-filer; tabulatortegn er ikke tilladt. Så længe indrykningen udføres konsekvent, er det ligegyldigt, hvor mange pladser der bruges.
YAML syntaks
Et YAML-format bruger primært 3 nodetyper:
- Kort/ordbøger: A kort nodes indhold er en uordnet samling af nøgle/værdi node par, med krav om, at hver nøgle skal være særskilt. Ingen yderligere begrænsninger pålægges noderne af YAML.
- Arrays/lister: An matrix nodes indhold er en ordnet samling af nul eller flere noder. En sekvens kan især omfatte den samme node mere end én gang. Det kan endda indeholde sig selv.
- konstanter (Strenge, tal, boolean osv.): En sekvens på nul eller mere Unicode-tegn kan bruges til at repræsentere de uigennemsigtige data, der udgør en skalar nodens indhold.
I denne artikel vil vi specifikt tage et kig på at konvertere YAML-arrayindhold til en liste i Java. Der er masser af open source-biblioteker tilgængelige, men de mest populære af dem er Jackson , SnakeYAML. I denne guide vil vi bruge SnakeYaml som vores bibliotek til at analysere YAML-indholdet.
SnakeYaml
SnakeYAML er en YAML-parsing-pakke, der tilbyder en API på højt niveau til YAML-dokumentserialisering og deserialisering. Indgangspunktet for SnakeYAML er Yaml
klasse. Dokumenterne eller YAML-filerne kan indlæses vha load()
metode eller i batch via loadAll()
metode. Metoderne tager ægte YAML-data i form af String-objekter såvel som InputStreams
, som er en typisk filtype at støde på.
På grund af :
struktur medfødt til YAML-filer, fungerer SnakeYAML naturligvis godt med Java kort, men vi kan også bruge unikke Java objekter.
For at inkludere biblioteket i vores projekt skal du tilføje følgende afhængighed til din pom.xml
fil:
<dependencies>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.33</version>
</dependency>
</dependencies>
Eller, hvis du bruger Gradle:
compile group: 'org.yaml', name: 'snakeyaml', version: '1.33'
Læsning af et simpelt YAML-array
Lad os hurtigt starte med at læse et simpelt array fra en YAML-fil. Overvej, at vi har en yaml-fil med følgende data i vores Java-projekts ressourcemappe:
- One
- Two
- Three
- Four
Så kan vi indlæse filindholdet som en InputStream
. Dernæst vil vi konstruere Yaml
forekomst, som derefter vil fungere som et indgangspunkt for at få adgang til biblioteket og objektet for at repræsentere YAML-filens indhold programmatisk. Det load()
metode giver os mulighed for at læse og parse evt InputStream
med gyldige 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 returnerer en Java List
af strengdata. Hvis vi udskriver data
så vil det give følgende resultat:
[One, Two, Three, Four]
Læsning af et YAML Grouped Array
Nogle gange vil vi gerne definere en række indhold mod en given nøgle. Dette kaldes gruppering af arrays i en YAML-kortnode. Et eksempel på YAML af en sådan art ser ud som nedenfor:
languages:
- Java
- JavaScript
- Python
- Golang
- Perl
- Shell
- Scala
Dette kan betragtes som Java Map
indeholdende en :
hvor værdien er an matrix. Så dataene vil stadig blive indlæst som InputStream
som vi definerede ovenfor. Men data
skal defineres som Map
of List
of String
s:
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);
}
Hvis vi nu læser vores data
, det ville se sådan ud:
{languages=[Java, JavaScript, Python, Golang, Perl, Shell, Scala]}
Java
JavaScript
Python
Golang
Perl
Shell
Scala
Læsning af en YAML Multi-Line Array af Arrays
Nogle gange støder vi på en YAML-fil med data, der indeholder en række arrays. For eksempel grupperer vi kurserne og repræsenterer dem som en række af arrays som nedenfor:
courses:
- - C
- Java
- Data Structures
- Algorithms
- - Big Data
- Spark
- Kafka
- Machine Learning
Dette kan parses som Java Map
of List
of List
of String
. Vi kan igen indlæse InputStream
som vi gjorde tidligere. Men dataene indlæses som nedenfor:
Tjek vores praktiske, praktiske guide til at lære Git, med bedste praksis, brancheaccepterede standarder og inkluderet snydeark. Stop med at google Git-kommandoer og faktisk lærer 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å hvis vi udskriver data
, ville det se nogenlunde ud som nedenfor:
{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æsning af et komplekst indlejret YAML-indhold som Java Bean
Vi så, hvordan vi kan håndtere indholdet af matrixtypen separat, men med komplekse indlejrede YAML-filer – at have et kort over kort med lister over lister er svært at analysere intuitivt og svært at håndtere. Selv i det sidste eksempel, hvor vi kun havde to indlejrede lister – bliver håndteringen af dem som lister ret omfattende.
I disse tilfælde er det bedst at oprette en POJO, der kan tilknyttes de indlejrede YAML-data. Lad os først oprette et eksempel på YAML, der indeholder det indlejrede indhold af et websted:
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 skal definere en overordnet Java-klasse WebsiteContent
der vil bestå af List
af færdigheder og en List
of Map
af selvstudier, som igen vil indeholde lister over tags og bidragydere:
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 igen indlæse data fra filen som InputStream
som vi gjorde tidligere. Næste når vi skaber vores Yaml
klasseobjekt, skal vi angive den datatype, vi vil caste dataene ind i. Det new Constructor(WebsiteContent.class)
fortæller SnakeYAML at læse dataene fra YAML-filen, kortlægge det til vores WebsiteContent
objekt.
Kortlægningen er ligetil, og navnene på vores objektattributter skal matche navnene på YAML-attributterne.
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);
}
Endelig, når vi udskriver data
, ville det se nogenlunde ud som nedenfor:
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 med succes analyseret og konverteret WebsiteContent
genstand og beholdt arven og foreningen med Tutorial
objekt intakt.
Konklusion
Da YAML-filer bruges meget til DevOps og konfigurationsrelaterede data, er det ganske nyttigt at parse og manipulere dataene ved hjælp af kode.
SnakeYAML giver os mulighed for at administrere YAML-filer i vores Java-projekt med lethed, og det kræver kun en lille smule kode for at indlæse YAML-filer i vores projekt eller skrive data til YAML-filer. Derudover tilbyder SnakeYAML formateringsvalg, så du kan justere og tilpasse det, så det passer til vores behov.