Logotipo de Zephyrnet

Convierta una matriz YAML en una lista Java con SnakeYAML

Fecha:

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

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.

punto_img

Información más reciente

punto_img