Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Parse list of beans with snakeyaml

Is it possible to parse with snakeyaml the following content and obtain a List<Radio> (where Radio is the appropriate java bean) ?

-
  id: chaine416
  name: 'France Inter'
  type: music
-
  id: chaine417
  name: 'France Culture'
  type: music
-
  id: chaine418
  name: 'Couleur 3'
  type: music

new Yaml().load(...); returns a List<HashMap>, but I'd like to get a List<Radio> instead.

like image 271
sdabet Avatar asked Jan 23 '26 14:01

sdabet


2 Answers

The only way I know is to use a top object to handle the collection.

Yaml file :

---
stations:
-
  id: chaine416
  name: "France Inter"
  type: music
-
  id: chaine417
  name: "France Culture"
  type: music
-
  id: chaine418
  name: "Couleur 3"
  type: music

I just added "---" , new document and an attribute stations.

Then :

package snakeyaml;

import java.util.ArrayList;

public class Radios {

    ArrayList<RadioStation> stations = new ArrayList<RadioStation>();

    public ArrayList<RadioStation> getStations() {
        return stations;
    }

    public void setStations(ArrayList<RadioStation> stations) {
        this.stations = stations;
    }
}

The class RadioStation :

package snakeyaml;


public class RadioStation {
    String id;
    String name;
    String type;


    public RadioStation(){

    }


    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }


    @Override
    public String toString() {
        return "RadioStation{" +
                "id='" + id + '\'' +
                ", name='" + name + '\'' +
                ", type='" + type + '\'' +
                '}';
    }
}

And to read the YAML file :

package snakeyaml;

import org.yaml.snakeyaml.Yaml;
import org.yaml.snakeyaml.constructor.Constructor;

import java.io.FileInputStream;
import java.io.FileNotFoundException;


public class Test {

    public static void main(String[] args) {
        Yaml yaml = new Yaml(new Constructor(Radios.class));
        try {
           Radios  result = (Radios) yaml.load(new FileInputStream("/home/ofe/dev/projets/projets_non_byo/TachesInfoengine/src/snakeyaml/data.yaml"));
            for (RadioStation radioStation : result.getStations()) {
                System.out.println("radioStation = " + radioStation);
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        }

    }
}
like image 188
olikaf Avatar answered Jan 25 '26 05:01

olikaf


Actually, there is a method loadAll in Yaml that returns Iterable but the yaml file should have a separator "---" between list items. The file should look like:

id: chaine416
name: 'Fr
ance Inter'
type: music
---
id: chaine417
name: 'France Culture'
type: music
---
id: chaine418
name: 'Couleur 3'
type: music

(The Radio DTO is omitted) And the code should be something like this:

public class Test {

    public static void main(String[] args) {
        Yaml yaml = new Yaml(new Constructor(Radio.class));
        InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("yourFile.yaml");
        
        List<Radio> radios = StreamSupport.stream(yaml.loadAll(inputStream).spliterator(), false)
                .filter(Radio.class::isInstance)
                .map(Radio.class::cast)
                .collect(Collectors.toList());
    }
}
like image 35
amisiuryk Avatar answered Jan 25 '26 03:01

amisiuryk



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!