Search code examples
javayamlminecraftbukkit

Java get List of maps of maps from config.yml


I'm trying to create a plugin where I'm storing some Minecraft items' data along with some properties.

This is my YAML file's content:

rates:
- 391:
    mul: 10000
    store: 5000
- 392:
    mul: 9000
    store: 5000

So it's basically a list of maps of maps(I think so at least). This is my JAVA code where I'm trying to access the key 'mul' of '391':

List<Map<?,?>> rates;
rates= getConfig().getMapList("rates");
for(Map<?,?> mp : rates){
    Map <?,?> test = (Map<?,?>) mp.get("" + item);
    player.sendMessage(test.toString());// HERE I get null pointer exception, and the following lines if this line wasn't there in the first place
    player.sendMessage("Mul is: " + test.get("mul"));
    player.sendMessage("Store is: " + test.get("store"));
}

As per suggested answer, here is my test code, where I still get NullPointerException:

import java.io.FileNotFoundException;
import java.io.FileReader;
import java.util.Map;

import net.sourceforge.yamlbeans.YamlException;
import net.sourceforge.yamlbeans.YamlReader;

public class Test {

public static void main(String[] args) throws FileNotFoundException, YamlException{
    YamlReader reader = new YamlReader(new FileReader("config.yml"));
    Map map = (Map) reader.read();
    Map itemMap = (Map) map.get("391");
    System.out.println(itemMap.get("mul"));//This is where I get the exception now
    System.out.println(itemMap.get("store"));
}
}

Solution

  • Parsing yaml by hand can be tedious and error prone. It might be easier to use a library like yamlbeans.

    http://yamlbeans.sourceforge.net/

    package com.jbirdvegas.q41267676;
    
    import com.esotericsoftware.yamlbeans.YamlReader;
    
    import java.io.StringReader;
    import java.util.List;
    import java.util.Map;
    
    public class YamlExample {
        public static void main(String[] args) throws Exception {
    
            String yamlInput =
                    "rates:\n" +
                            "- 391:\n" +
                            "    mul: 10000\n" +
                            "    store: 5000\n" +
                            "- 392:\n" +
                            "    mul: 9000\n" +
                            "    store: 5000";
    
            YamlReader reader = new YamlReader(new StringReader(yamlInput));
            Map map = (Map) reader.read();
            // rates is a list
            List<Map> rates = (List<Map>) map.get("rates");
            // each item in the list is a map
            for (Map itemMap : rates) {
                // each map contains a single map the key is [ 391|392 ]
                itemMap.forEach((key, value) -> {
                    System.out.println("Key: " + key);
                    // the value in in this map is itself a map
                    Map embededMap = (Map) value;
                    // this map contains the values you want
                    System.out.println(embededMap.get("mul"));
                    System.out.println(embededMap.get("store"));
                });
            }
        }
    }
    

    This prints:

    Key: 391
    10000
    5000
    Key: 392
    9000
    5000
    

    This is a simple usecase but yamlbeans also provides GSON like reflective class model population if that would be better suited for your needs.