Introducción
Ñame es uno de los lenguajes de serialización de datos más populares después de JSON. Por lo tanto, a veces se le llama como estricto superconjunto de JSON. Ha sido diseñado para la interacción humana y la legibilidad desde el principio, por lo tanto, es conocido por su simplicidad. Está diseñado teniendo en cuenta la flexibilidad y la accesibilidad, por lo que funciona con todos los lenguajes de programación modernos y un formato potente para escribir archivos de configuración. También se utiliza para la persistencia de datos, mensajería de Internet, intercambio de datos entre idiomas y muchas más opciones.
YAML se inició en 2001 y se denominó como "Otro lenguaje de marcado" En ese tiempo. Pero más tarde fue registrada como “YAML no es lenguaje de marcado“. La estructura básica de un archivo YAML es un mapa. También se conoce como diccionario, hash (mapa) o simplemente basado en objetos según el lenguaje de programación que optemos por usar.
Los espacios en blanco y la sangría se utilizan en los archivos YAML para indicar el anidamiento.
Note: Solo se pueden usar espacios para la sangría en archivos YAML; No se permiten caracteres de tabulación. Siempre que la sangría se realice de manera consistente, no importa cuántos espacios se utilicen.
Sintaxis YAML
Un formato YAML utiliza principalmente 3 tipos de nodos:
- Mapas/Diccionarios: Un mapa El contenido del nodo es una colección desordenada de valor clave nodo pares, con el requisito de que cada clave debe ser distinta. YAML no impone más limitaciones a los nodos.
- Matrices / Listas: Un matriz El contenido del nodo es una colección ordenada de cero o más nodos. Una secuencia puede incluir el mismo nodo más de una vez, en particular. Puede contener incluso a sí mismo.
- Literales (Cadenas, números, booleanos, etc.): una secuencia de cero o más Caracteres Unicode se puede utilizar para representar los datos opacos que componen un escalar contenido del nodo.
En este artículo, veremos específicamente cómo convertir contenido de matriz YAML en una lista en Java. Hay muchas bibliotecas de código abierto disponibles, pero las más populares son Jackson y Serpiente YAML. En esta guía, usaremos SnakeYaml como nuestra biblioteca para analizar el contenido YAML.
SerpienteYaml
Serpiente YAML es un paquete de análisis YAML que ofrece una API de alto nivel para la serialización y deserialización de documentos YAML. El punto de entrada para SnakeYAML es el Yaml
clase. Los documentos o los archivos YAML se pueden cargar usando load()
método o en lote a través del loadAll()
método. Los métodos toman datos YAML genuinos en forma de objetos String, así como InputStreams
, que es un tipo de archivo típico que se encuentra.
Dado que :
estructura innata a los archivos YAML, SnakeYAML naturalmente funciona bien con Mapas Java, pero también podemos usar Unique Objetos Java.
Para incluir la biblioteca en nuestro proyecto, agregue la siguiente dependencia a su pom.xml
archivo:
<dependencies>
<dependency>
<groupId>org.yaml</groupId>
<artifactId>snakeyaml</artifactId>
<version>1.33</version>
</dependency>
</dependencies>
O, si estás usando Gradle:
compile group: 'org.yaml', name: 'snakeyaml', version: '1.33'
Lectura de una matriz YAML simple
Comencemos rápidamente leyendo una matriz simple de un archivo YAML. Considere que tenemos un archivo yaml con los siguientes datos en la carpeta de recursos de nuestro proyecto Java:
- One
- Two
- Three
- Four
Entonces podemos cargar el contenido del archivo como un InputStream
. A continuación, construiremos el Yaml
instancia que luego actuará como un punto de entrada para acceder a la biblioteca y al objeto para representar el contenido del archivo YAML programáticamente. los load()
nos permite leer y analizar cualquier InputStream
con datos YAML válidos:
public void readYamlWithArray() {
InputStream inputStream = this.getClass()
.getClassLoader()
.getResourceAsStream("number.yml");
Yaml yaml = new Yaml();
List data = yaml.load(inputStream);
System.out.println(data);
}
El método devolverá un Java List
de datos de cadena. Si imprimimos el data
entonces dará el siguiente resultado:
[One, Two, Three, Four]
Lectura de una matriz agrupada YAML
A veces nos gustaría definir una matriz de contenido contra una clave determinada. Esto se denomina agrupación de matrices en un nodo de mapa YAML. Una muestra de YAML de este tipo se ve a continuación:
languages:
- Java
- JavaScript
- Python
- Golang
- Perl
- Shell
- Scala
Esto puede ser considerado como Java Map
que contiene un :
donde el valor es un matriz. Por lo tanto, los datos se seguirán cargando como InputStream
como definimos arriba. Pero el data
debe definirse como 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);
}
Ahora bien, si leemos nuestro data
, se vería así:
{languages=[Java, JavaScript, Python, Golang, Perl, Shell, Scala]}
Java
JavaScript
Python
Golang
Perl
Shell
Scala
Lectura de una matriz de matrices multilínea YAML
A veces nos encontramos con un archivo YAML que tiene datos que contienen una matriz de matrices. Por ejemplo, agrupamos los cursos y los representamos como una matriz de matrices como se muestra a continuación:
courses:
- - C
- Java
- Data Structures
- Algorithms
- - Big Data
- Spark
- Kafka
- Machine Learning
Esto se puede analizar como Java Map
of List
of List
of String
. Podemos volver a cargar el InputStream
como hicimos antes. Pero los datos se cargarán de la siguiente manera:
Consulte nuestra guía práctica y práctica para aprender Git, con las mejores prácticas, los estándares aceptados por la industria y la hoja de trucos incluida. Deja de buscar en Google los comandos de Git y, de hecho, aprenden ella!
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);
}
Así que si imprimimos el data
, se vería algo como lo siguiente:
{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
Leer un contenido YAML anidado complejo como Java Bean
Vimos cómo podemos manejar el contenido de tipo matriz por separado, pero con archivos YAML anidados complejos: tener un mapa de mapas con listas de listas es difícil de analizar intuitivamente y difícil de manejar. Incluso en el último ejemplo donde solo teníamos dos listas anidadas, manejarlas como listas se vuelve bastante detallado.
En estos casos, es mejor crear un POJO que se pueda asignar a los datos YAML anidados. Primero, creemos un YAML de muestra que contenga el contenido anidado de un sitio web:
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
Necesitamos definir una clase Java padre WebsiteContent
que consistirá en List
de habilidades y un List
of Map
de tutoriales que volverán a contener listas de etiquetas y colaboradores:
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 + ''' +
'}';
}
}
Ahora podemos volver a cargar los datos del archivo como InputStream
como hicimos antes. A continuación, cuando creamos nuestro Yaml
objeto de clase, necesitamos especificar el tipo de datos en el que queremos convertir los datos. los new Constructor(WebsiteContent.class)
le dice a SnakeYAML que lea los datos del archivo YAML y los asigne a nuestro WebsiteContent
objeto.
El mapeo es sencillo y los nombres de los atributos de nuestro objeto deben coincidir con los nombres de los atributos 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);
}
Finalmente, cuando imprimimos el data
, se vería algo como lo siguiente:
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}}
Como podemos ver, SnakeYaml ha analizado y convertido con éxito el WebsiteContent
objeto y conservaba la herencia y asociación con Tutorial
objeto intacto.
Conclusión
Dado que los archivos YAML se usan ampliamente para DevOps y datos relacionados con la configuración, es muy útil analizar y manipular los datos mediante código.
SnakeYAML nos permite administrar archivos YAML en nuestro proyecto Java con facilidad, y solo requiere un poco de código para cargar archivos YAML en nuestro proyecto o escribir datos en archivos YAML. Además, SnakeYAML ofrece opciones de formato para que puedas ajustarlo y personalizarlo según nuestras necesidades.