Вступ
ЯМЛ є однією з найпопулярніших мов серіалізації даних після JSON. Тому його іноді називають a строгий суперсет JSON. Він був розроблений для взаємодії з людьми та читабельності з самого початку, тому він відомий своєю простотою. Його розроблено з урахуванням гнучкості та доступності, тому він працює з усіма сучасними мовами програмування та потужним форматом для запису конфігураційних файлів. Він також використовується для збереження даних, обміну повідомленнями в Інтернеті, міжмовного обміну даними та багатьох інших параметрів.
YAML було запущено в 2001 році і називалося «Ще одна мова розмітки" в той час. Але пізніше він був позначений як «YAML не є мовою розмітки“. Основною структурою файлу YAML є a карта. Він також відомий як словник, хеш (карта) або просто об’єктний, залежно від мови програмування, яку ми вибрали.
Пробіли та відступи використовуються у файлах YAML для позначення вкладеності.
примітки: для відступів у файлах YAML можна використовувати лише пробіли; символи табуляції заборонені. Поки відступи виконуються послідовно, не має значення, скільки пробілів використовується.
Синтаксис YAML
Формат YAML переважно використовує 3 типи вузлів:
- Карти/Словники: карта Вміст вузла є невпорядкованою колекцією ключ/значення вузол пар, з вимогою, щоб кожен ключ був окремим. Жодних додаткових обмежень YAML не накладає на вузли.
- Масиви/Списки: An масив Вміст вузла - це впорядкована колекція нуля або більше вузлів. Зокрема, послідовність може включати один і той же вузол більше одного разу. Він може містити навіть сам себе.
- Літерали (Рядки, числа, логічні значення тощо): послідовність нуля або більше Символи Unicode можна використовувати для представлення непрозорих даних, які складають a скалярний вміст вузла.
У цій статті ми конкретно розглянемо перетворення вмісту масиву YAML у список у Java. Існує багато відкритих бібліотек, але найпопулярніші з них Джексон та ЗміяYAML. У цьому посібнику ми будемо використовувати SnakeYaml як нашу бібліотеку для аналізу вмісту YAML.
SnakeYaml
ЗміяYAML — це пакет аналізу YAML, який пропонує API високого рівня для серіалізації та десеріалізації документів YAML. Точкою входу для SnakeYAML є Yaml
клас. Документи або файли YAML можна завантажити за допомогою load()
методом або пакетно через loadAll()
метод. Методи також беруть справжні дані YAML у формі об’єктів String InputStreams
, що є типовим типом файлу.
З огляду на :
структуру, вроджену для файлів YAML, з якою SnakeYAML природно працює Карти Java, але ми також можемо використовувати унікальний Об'єкти Java.
Щоб включити бібліотеку в наш проект, додайте таку залежність до свого pom.xml
Файл:
<dependencies>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.33</version>
</dependency>
</dependencies>
Або, якщо ви використовуєте Gradle:
compile group: 'org.yaml', name: 'snakeyaml', version: '1.33'
Читання простого масиву YAML
Давайте швидко почнемо з читання простого масиву з файлу YAML. Припустімо, що у папці ресурсів нашого проекту Java є файл yaml із такими даними:
- One
- Two
- Three
- Four
Тоді ми можемо завантажити вміст файлу як InputStream
. Далі ми побудуємо Yaml
екземпляр, який потім діятиме як точка входу для доступу до бібліотеки та об’єкта для програмного представлення вмісту файлу YAML. The load()
метод дозволяє читати та аналізувати будь-який InputStream
з дійсними даними 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);
}
Метод поверне Java List
рядкових даних. Якщо ми надрукуємо data
то це дасть такий результат:
[One, Two, Three, Four]
Читання згрупованого масиву YAML
Іноді нам хочеться визначити масив вмісту за заданим ключем. Це називається групуванням масивів у вузол карти YAML. Зразок YAML такого типу виглядає так:
languages:
- Java
- JavaScript
- Python
- Golang
- Perl
- Shell
- Scala
Це можна вважати Java Map
що містять a :
де значення an масив. Отже, дані все ще завантажуватимуться як InputStream
як ми визначили вище. Але data
необхідно визначити як 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);
}
Тепер, якщо ми прочитаємо наш data
, це виглядатиме приблизно так:
{languages=[Java, JavaScript, Python, Golang, Perl, Shell, Scala]}
Java
JavaScript
Python
Golang
Perl
Shell
Scala
Читання багаторядкового масиву масивів YAML
Іноді ми зустрічаємо файл YAML з даними, що містять масив масивів. Наприклад, ми групуємо курси та представляємо їх у вигляді масиву масивів, як показано нижче:
courses:
- - C
- Java
- Data Structures
- Algorithms
- - Big Data
- Spark
- Kafka
- Machine Learning
Це можна розібрати як Java Map
of List
of List
of String
. Ми можемо знову завантажити InputStream
як ми робили раніше. Але дані будуть завантажені так:
Ознайомтеся з нашим практичним практичним посібником із вивчення Git з передовими методами, прийнятими в галузі стандартами та включеною шпаргалкою. Припиніть гуглити команди Git і фактично вчитися це!
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);
}
Отже, якщо ми надрукуємо data
, це виглядатиме приблизно так:
{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
Читання складного вкладеного вмісту YAML як Java Bean
Ми побачили, як ми можемо обробляти вміст типу масиву окремо, але зі складними вкладеними файлами YAML – мати карту карт зі списками списків важко інтуїтивно проаналізувати та важко мати справу. Навіть в останньому прикладі, де ми мали лише два вкладені списки, обробка їх як списків стає досить багатослівною.
У цих випадках найкраще створити POJO, який можна зіставити з вкладеними даними YAML. Давайте спочатку створимо зразок YAML, що містить вкладений вміст веб-сайту:
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
Нам потрібно визначити батьківський клас Java WebsiteContent
що складатиметься з List
навичок і a List
of Map
посібників, які знову міститимуть списки тегів і учасників:
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 + ''' +
'}';
}
}
Тепер ми можемо знову завантажити дані з файлу as InputStream
як ми робили раніше. Далі, коли ми створимо свій Yaml
об’єкт класу, нам потрібно вказати тип даних, до якого ми хочемо привести дані. The new Constructor(WebsiteContent.class)
повідомляє SnakeYAML прочитати дані з файлу YAML, зіставити його з нашим WebsiteContent
об'єкт
Відображення є простим, і імена атрибутів наших об’єктів мають збігатися з іменами атрибутів 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);
}
Нарешті, коли ми друкуємо data
, це виглядатиме приблизно так:
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}}
Як ми бачимо, SnakeYaml успішно проаналізував і перетворив WebsiteContent
об'єкта та зберіг спадщину та товариство с Tutorial
об'єкт цілий.
Висновок
Оскільки файли YAML широко використовуються для даних DevOps і конфігурації, дуже корисно аналізувати та маніпулювати даними за допомогою коду.
SnakeYAML дозволяє нам легко керувати файлами YAML у нашому проекті Java, і для завантаження файлів YAML у наш проект або запису даних у файли YAML потрібно лише трохи коду. Крім того, SnakeYAML пропонує варіанти форматування, щоб ви могли налаштувати та персоналізувати його відповідно до наших потреб.