Solved Get the path to the correct list in the .yml file based on the value of the first key?

Discussion in 'Spigot Plugin Development' started by Majong7, Feb 15, 2020.

  1. I've been doing spigot plugins for some time now, but I have never gone this in depth with YAML.
    This is my config.yml:
    Code (YAML):
    edibles:
        - name
    : "Fish"
          img
    : "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZmVkMjljMGI0ZjE3NWI2NDBhZmNhYjQ0NWJkMTI5YzhmYjhiYTdjNDY1MTJjYTU2M2YxMDExOTU5MzJhZDdmNCJ9fX0="
          color
    : "Gravel"
        - name
    : "Beer"
          img
    : "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNDExNTRkNzU2NDZiMzlkMDRjNWI4NzZkNjVlYTdjZDU2ODU4NjY2OGYzMTM4YmQwNWViZjM1MTFjNGI4NmQifX19"
          color
    : "Dirt"
    What I want to get is the correct instance of "- name:" by the value next to it, for example: "Fish" and based on that add another field under that section, for example: "color". My YAML syntax is probably not correct, but I've never used it this much. I have been trying to find a solution to my problem for almost a week now and still I found nothing.
    Does anyone have any idea on what I could try next or at least point me in the right direction?
     
  2. That YAML looks a bit weird. Change it like this:
    Code (YAML):
    edibles:
      Fish
    :
        img
    : "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvZmVkMjljMGI0ZjE3NWI2NDBhZmNhYjQ0NWJkMTI5YzhmYjhiYTdjNDY1MTJjYTU2M2YxMDExOTU5MzJhZDdmNCJ9fX0="
        color
    : "Gravel"
      Beer
    :
        img
    : "eyJ0ZXh0dXJlcyI6eyJTS0lOIjp7InVybCI6Imh0dHA6Ly90ZXh0dXJlcy5taW5lY3JhZnQubmV0L3RleHR1cmUvNDExNTRkNzU2NDZiMzlkMDRjNWI4NzZkNjVlYTdjZDU2ODU4NjY2OGYzMTM4YmQwNWViZjM1MTFjNGI4NmQifX19"
        color
    : "Dirt"
    That way, you can access the values easily. Here is an example:
    Code (Java):
    public String getColor(FileConfiguration fileConfiguration, String key) {
        return fileConfiguration.getString("edibles." + key + ".color");
    }
    Code (Java):

    public void handleColor(FileConfiguration fileConfiguration, String key) {
        String color = getColor(fileConfiguration, key);
    }
     
     
    #2 patri9ck, Feb 15, 2020
    Last edited: Feb 15, 2020
    • Like Like x 1
  3. Is there a way for me to go through "edibles:" and get "Fish" and "Beer" with something like a for loop?
     
  4. Yes, there is:
    Code (Java):
    public void loopThroughEdibles(FileConfiguration fileConfiguration) {
        for (String key : fileConfiguration.getConfigurationSection("edibles").getKeys(false)) {
            String color = getColor(fileConfiguration, key);
        }
    }
    Or alternatively, with lambda:
    Code (Java):
    public void loopThroughEdibles(FileConfiguration fileConfiguration) {
        fileConfiguration.getConfigurationSection("edibles").getKeys(false).forEach(key -> {  
            String color = getColor(fileConfiguration, key);
        });
    }
     
    #4 patri9ck, Feb 15, 2020
    Last edited: Feb 15, 2020
    • Like Like x 1
  5. Let me rephrase my last question, Is there a way to loop through "edibles:" and get all of the main values like "Fish" and "Beer" out with the return statement?
     
  6. Of course, simply do not create the method and shift its contents to the loop.
     
  7. Could you maybe give me an example because I don't use YAML that often so I don't have that much experience with it.
     
  8. That has nothing to do with YAML. It moore seems like you do not use Java that often.
    Code (Java):
    public void loopThroughEdibles(FileConfiguration fileConfiguration) {
        fileConfiguration.getConfigurationSection("edibles").getKeys(false).forEach(key -> {
            String color = fileConfiguration.getString("edibles." + key + ".color");
        });
    }
     
  9. I know how to use Java but I currently don't need the value of color, I need the value of it's parent which is, for example: "Fish". I need a method that loops through "edibles:" and returns all of the main values so the output would be: ["Fish", "Beer"] or something in that context. That is the reason for my original YAML, I went through the elements in order to get the "name:" for each element, but the real problem is that I couldn't add another value under those values, for example "size:" or something like that.
     
  10. You need a method which returns all the keys of "edibles"? Then simply use ConfigurationSection#getKeys(boolean). In your case, it would return a Set with the elements "Fish" and "Beer". You can get a ConfigurationSection object with FileConfiguration#getConfigurationSection(String).
     
    #10 patri9ck, Feb 15, 2020
    Last edited: Feb 15, 2020
  11. Strahan

    Benefactor

    This may be of some help.
     
  12. So this is what I have so far:
    Code (Java):
        public String[] GetConfigList(String item, String category) {
            ConfigurationSection data = plugin.getConfig().getConfigurationSection(category);
            for (String i : data.getKeys(false)) {
                if (item.equalsIgnoreCase(String.valueOf(i))){
                    String[] info = {String.valueOf(plugin.getConfig().getString(category+"."+i+".img")), String.valueOf(category+"."+i+".color")};
                    return info;
                }
            }
            return null;
        }
    But if I give it a string that doesn't exist in the file, I get an NPE (Supposedly this line: "for (String i : data.getKeys(false)) {").
    Also, I'm expecting the value to be "null" if it doesn't find anything.
     
  13. I see, what you want to do. Here is a version which would work:
    Code (Java):
    public Map<String, Object> GetConfigList(String item, String category) {
        FileConfiguration fileConfiguration = plugin.getConfig();

        return fileConfiguration.contains(category + "." + item) ? fileConfiguration.getConfigurationSection(category + "." + item).getValues(false) : Collections.EMPTY_MAP;
    }
    Also, do not forget to change your configuration like I suggested in a post above.
     
    #13 patri9ck, Feb 15, 2020
    Last edited: Feb 16, 2020
  14. It doesn't seem to work. I've created another method:
    Code (Java):
        public String[] GetConfigList(String item, String category) {
            ConfigurationSection data = plugin.getConfig().getConfigurationSection(category);
            if(data.getKeys(false) != null && data.getKeys(false).isEmpty() == false) {
                for (String i : data.getKeys(false)) {
                    if (item.equalsIgnoreCase(i)){
                        String[] info = {String.valueOf(plugin.getConfig().getString(category+"."+i+".img")), String.valueOf(category+"."+i+".color")};
                        return info;
                    }
                }
            }
            return null;
        }
    The NPE should be caused by "data.getKeys(false)" being "null" so I've checked if it was empty or "null" but I still got an NPE. But I only get an NPE if the item isn't in the config.yml file.
     
  15. Try my method and do not forget to change your configuration as I suggested.
     
  16. I did both of those things and it doesn't work, that's why I tried modifying my old method.
     
  17. I't s working!!!
    Code (Java):
        public String[] GetConfigList(String item, String category) {
            ConfigurationSection data = plugin.getConfig().getConfigurationSection(category);
            if(data != null) {
                for (String i : data.getKeys(false)) {
                    if (item.equalsIgnoreCase(i)){
                        String[] info = {String.valueOf(plugin.getConfig().getString(category+"."+i+".img")), String.valueOf(category+"."+i+".color")};
                        return info;
                    }
                }
            }
            return null;
        }
    Thanks to this post it's finally working. The problem was that "data" returned null so "data.getKeys(false)" couldn't be executed because it was null and by checking "if(data != null) {" I managed to solve my issue.

    I would like to thank everyone who helped me solve my issue.