繁体   English   中英

如何使用 SnakeYaml 从 YAML 文件中安全地提取嵌套值?

[英]How to safely extract nested values from YAML file using SnakeYaml?

我正在使用 Snakeyaml 库从 Java 中的 YAML 文件中提取值。 不幸的是,当我事先不知道文件的内容时,我很难从这些文件中提取值。

因此,我正在寻找一个安全的原因,为什么要从给定的 YAML 文件中提取嵌套值。

这是我的方法:

Map<String, Object> dataMap = yaml.load(FileUtils.readFileToString(file, StrandardCharsets.UTF_8));
for(Map.Entry<String, Object> entry: dataMap.entrySet()) {
    if(entry.getValue() instanceof Map<String, Object>) {
        // Do something. Potentially loop again, because I do not know the depth of the File
    } else {
        // Get actual Value
    }
}

我编写了这个函数,它递归地读取 yml 文件中的所有字段。 我没有彻底测试它,但我会说它按预期工作。

 public static void readMapRec(Map<String,Object> map){
        if(Objects.isNull(map) || map.entrySet().size()==0){
            return;
        }
        for(Map.Entry<String,Object> entry: map.entrySet()){
            try {
                if (entry.getValue() instanceof List) {
                    for(int i = 0 ; i< ((List<?>) entry.getValue()).size();i++) {
                        Map<String, Object> casted = (Map<String, Object>) ((List<?>) entry.getValue()).get(i);
                        readMapRec(casted);
                    }
                }
                else {
                    System.out.println(entry.getKey() +" "+entry.getValue());
                }
            }catch (Exception ex){
                System.out.println(ex.getMessage());
            }
        }

    }

public static void main(String[] args) throws IOException {

        
        InputStream inputStream = new FileInputStream(new File("myFile.yml"));

        Yaml yaml = new Yaml();
        Map<String, Object> data = yaml.load(inputStream);

        readYml(data);

    }

所以,如果你有这样的 yml 文件:

id: 20
name: Bruce
year: 2020
address: Gotham City
department: Computer Science
courses:
  - name: Algorithms
    credits: 6
  - name: Data Structures
    credits: 5
  - name: Design Patterns
    credits: 3
books:
  - ds:
      - a: test
      - b: test
      - c:
          - e: test
          - f: test

你应该看到这样的输出:

id 20
name Bruce
year 2020
address Gotham City
department Computer Science
name Algorithms
credits 6
name Data Structures
credits 5
name Design Patterns
credits 3
a test
b test
e test
f test

我稍微修改了您在顶部提出的功能以捕获不分青红皂白的情况:

private @NotNull Map<String[], Object> parseMap(@NotNull Map<String, Object> map, String[] previousRoot) {
            Map<String[], Object> values = new HashMap<>();
            if(map.entrySet().size()==0){
                return values;
            }
            for(Map.Entry<String, Object> entry: map.entrySet()){
                try {
                    LinkedList<String> list = new LinkedList<>(Arrays.asList(previousRoot));
                    list.add(entry.getKey());
                    String[] key = list.toArray(previousRoot);
                    if (entry.getValue() instanceof List) {
                        List<Map<String, Object>> objectItems = new ArrayList<>();
                        for(int i = 0 ; i< ((List<?>) entry.getValue()).size();i++) {
                            Map<String, Object> casted = (Map<String, Object>) ((List<?>) entry.getValue()).get(i);
                            if(casted.size() > 1) {
                                objectItems.add(casted);
                            } else {
                                values.putAll(parseMap(casted, key));
                            }
                        }
                        if(!objectItems.isEmpty()) {
                            System.out.println("Putting Key: " + Arrays.toString(key) + " with Value: " + objectItems);
                            values.put(key, objectItems);
                        }
                    }
                    else {
                        System.out.println("Putting Key: " + Arrays.toString(key) + " with Value: " + entry.getValue());
                        values.put(key, entry.getValue());
                    }
                }catch (Exception ex){
                    System.out.println("Exception: " + ex.getMessage());
                }
            }
            return values;
        }

你怎么看? 如果您对如何改进它有任何建议,我很乐意听到。 :)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM