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