Java如何读取Iterable嵌套YAML对象 按路径获取嵌套列表数据
实现方式
你不需要绑定固定实体类,直接写一个轻量的通用路径解析方法,就能通过a/b/c格式的路径从SnakeYAML解析出的嵌套Map中提取目标值。
SnakeYAML的loadAll返回的是多文档YAML的迭代器,你循环拿到的每个对象都是单个YAML文档对应的根Map,基于这个根Map做路径穿透即可。
通用路径解析工具代码
import java.util.Map; public class YamlPathReader { /** * 按斜杠分隔的路径从嵌套Map结构中取值 * @param rootMap YAML文档解析出的根Map * @param path 斜杠分隔的取值路径,例:fileList/files * @return 路径匹配到的值,路径不存在/中间节点类型不匹配时返回null */ public static Object getValue(Map<String, Object> rootMap, String path) { if (rootMap == null || path == null || path.isBlank()) { return null; } String[] nodes = path.split("/"); Object current = rootMap; for (String node : nodes) { if (!(current instanceof Map)) { return null; } @SuppressWarnings("unchecked") Map<String, Object> currentMap = (Map<String, Object>) current; current = currentMap.get(node); if (current == null) { return null; } } return current; } }
业务代码调用示例
修改你原来的读取逻辑即可,注意加类型校验避免结构不固定导致的强转异常,同时用try-with-resources自动关流:
import org.yaml.snakeyaml.Yaml; import java.io.InputStream; import java.io.IOException; import java.util.List; import java.util.Map; public class YamlTest { public void readYaml() { Yaml yaml = new Yaml(); try (InputStream inputStream = this.getClass().getClassLoader().getResourceAsStream("test.yml")) { Iterable<Object> docs = yaml.loadAll(inputStream); for (Object doc : docs) { @SuppressWarnings("unchecked") Map<String, Object> docMap = (Map<String, Object>) doc; // 提取fileList/files对应的列表 Object filesVal = YamlPathReader.getValue(docMap, "fileList/files"); if (filesVal instanceof List<?> fileList) { System.out.println("文件列表内容:" + fileList); } // 提取nestedData/animal对应的列表 Object animalVal = YamlPathReader.getValue(docMap, "nestedData/animal"); if (animalVal instanceof List<?> animalList) { System.out.println("动物列表内容:" + animalList); } } } catch (IOException e) { e.printStackTrace(); } } }
注意事项
- 该实现无额外依赖,完全基于SnakeYAML原生解析出的Map/List嵌套结构做遍历,支持任意层级的Map嵌套
- 取值时必须做
instanceof校验,因为你提到YAML结构不固定,避免路径对应的值不是List类型时抛出ClassCastException - 如果你的YAML键名本身包含斜杠,可以自行修改路径分隔符,比如将分隔符换成
.,只需要把工具类中split("/")改成split("\\.")即可 - 上述代码针对你给出的测试YAML运行,会在第一个文档中匹配到
fileList/files对应的两个文件对象的列表,在第二个文档中匹配到nestedData/animal对应的dog对象列表
内容的提问来源于stack exchange,提问作者Talktomegoose
相关产品推荐
相关产品推荐

