我想将YAML文档读取到自定义对象的地图(而不是默认情况下snakeYaml执行的地图)。所以这个:
19:
typeID: 2
limit: 300
20:
typeID: 8
limit: 100
将加载到如下所示的地图:
Map<Integer, Item>
其中Item是:
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格式呢?
答案 0 :(得分:7)
这是我为非常类似的情况所做的。我只是将整个yml文件标记在一个选项卡上,并在顶部添加了map:标记。所以对于你的情况来说就是。
map:
19:
typeID: 2
limit: 300
20:
typeID: 8
limit: 100
然后在类中创建一个静态类,读取此文件,如下所示。
static class Items {
public Map<Integer, Item> map;
}
然后阅读你的地图就好了。
Yaml yaml = new Yaml(new Constructor(Items));
Items items = (Items) yaml.load(<file>);
Map<Integer, Item> 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<Integer, Item> itemMap = items.map;
}
答案 1 :(得分:4)
您需要添加自定义Constructor。但是,在您的情况下,您不希望注册“item”或“item-list”标记。
实际上,您希望将Duck Typing应用于您的Yaml。它不是超级高效的,但有一种相对简单的方法可以做到这一点。
class YamlConstructor extends Constructor {
@Override
protected Object constructObject(Node node) {
if (node.getTag() == Tag.MAP) {
LinkedHashMap<String, Object> map = (LinkedHashMap<String, Object>) 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);
答案 2 :(得分:0)
yaml.load返回一个映射。您可以这样做:
Java版本
Yaml yaml = new Yaml();
Map<String, Object> data = (Map<String, Object>)yaml.load(yamldata);
Scala版本
val yaml = new Yaml()
yaml.load(getClass.getResourceAsStream(name))
.asInstanceOf[java.util.Map[String, Any]]