使用snakeYaml在根目录中解析带有映射的YAML文档

我想将YAML文档读取到自定义对象的地图(而不是默认情况下snakeYaml执行的地图)。 所以这:

19: typeID: 2 limit: 300 20: typeID: 8 limit: 100 

将被加载到如下所示的地图:

 Map 

其中项目是:

 class Item { private Integer typeId; private Integer limit; } 

我找不到用snakeYaml做这个的方法,我也找不到更好的任务库。

该文档仅包含嵌套在其他对象中的maps / collections的示例,以便您可以执行以下操作:

  TypeDescription typeDescription = new TypeDescription(ClassContainingAMap.class); typeDescription.putMapPropertyType("propertyNameOfNestedMap", Integer.class, Item.class); Constructor constructor = new Constructor(typeDescription); Yaml yaml = new Yaml(constructor); /* creating an input stream (is) */ ClassContainingAMap obj = (ClassContainingAMap) yaml.load(is); 

但是,当它位于文档的根目录时,如何定义Map格式呢?

您需要添加自定义构造函数 。 但是,在您的情况下,您不希望注册“item”或“item-list”标记。

实际上,您想要将Duck Typing应用于您的Yaml。 它不是超级高效,但有一种相对简单的方法可以做到这一点。

 class YamlConstructor extends Constructor { @Override protected Object constructObject(Node node) { if (node.getTag() == Tag.MAP) { LinkedHashMap map = (LinkedHashMap) super .constructObject(node); // If the map has the typeId and limit attributes // return a new Item object using the values from the map ... } // In all other cases, use the default constructObject. return super.constructObject(node); 

这是我为一个非常相似的情况所做的。 我只是将整个yml文件标记在一个选项卡上,并将map:标记添加到顶部。 所以对你的情况来说就是这样。

 map: 19: typeID: 2 limit: 300 20: typeID: 8 limit: 100 

然后在类中创建一个静态类,读取此文件,如下所示。

 static class Items { public Map map; } 

然后阅读你的地图就好用。

 Yaml yaml = new Yaml(new Constructor(Items)); Items items = (Items) yaml.load(); Map itemMap = items.map; 

更新:

如果您不想或不能编辑您的yml文件,您可以在使用类似的东西读取文件时在代码中进行上述转换。

 try (BufferedReader br = new BufferedReader(new FileReader(new File("example.yml")))) { StringBuilder builder = new StringBuilder("map:\n"); String line; while ((line = br.readLine()) != null) { builder.append(" ").append(line).append("\n"); } Yaml yaml = new Yaml(new Constructor(Items)); Items items = (Items) yaml.load(builder.toString()); Map itemMap = items.map; }