[英]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.