gpt4 book ai didi

java - 如何使用snakeyaml从yaml文件中读取顶级HashMap?

转载 作者:太空宇宙 更新时间:2023-11-04 13:04:47 27 4
gpt4 key购买 nike

我正在为 Docker Compose YML 文件开发 GUI。目前我选择snakeyml来读取/写入YML文件。

作为测试,我使用以下程序(部分)生成 YML 文件:

HashMap<String, Service> map1 = new HashMap();

Service srv1 = new Service();
srv1.setImage("aaa");
srv1.setCommand("-c crc");
List<String> ports = new ArrayList();
ports.add("5001:5001");
ports.add("444:333");
srv1.setPorts(ports);
srv1.setContainer_name("myname");
map1.put("srv1", srv1);

Service srv2 = new Service();
srv2.setImage("bbb");
srv2.setContainer_name("c2");
map1.put("srv2", srv2);

Representer representer = new SkipNullRepresenter();
//comment the following out to remove explicit tags in the YAML file
//representer.addClassTag(Service.class, Tag.MAP);

DumperOptions options = new DumperOptions();
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);

Yaml yaml = new Yaml(representer, options);
String output = yaml.dump(map1);

服务类在哪里:

public class Service {
private String image = null;
private String command = null;
private String container_name = null;
private List ports = null;

// plus getters and setters ...
}

就我而言,这给出了:

srv1: !!CoSession.Service
command: -c crc
container_name: myname
image: aaa
ports:
- 5001:5001
- 444:333
srv2: !!CoSession.Service
container_name: c2
image: bbb

我可以通过以下方式读回此内容:

HashMap<String, Service> map2 = new HashMap();
Constructor constructor = new Constructor(map2.getClass());

Yaml yaml2 = new Yaml(constructor);
FileReader reader = new FileReader(f);
map2 = (HashMap<String, Service>)yaml2.load(reader);

但是(哪里出了问题):当我在 YML 文件中省略标签“!!CoSession.Service”时,负载不会将该 block 识别为服务类实例,并将所有内容转换为字符串值。这就是我现在想要的。

我宁愿不使用该标签。我如何读取如下所示的 YML?(其中 srvX 下的所有键值对都是服务类属性)。

srv1:
command: -c crc
container_name: myname
image: aaa
ports:
- 5001:5001
- 444:333
srv2:
container_name: c2
image: bbb

最佳答案

经过一番搜索,我设法创建了以下“解决方法”。它适用于我的情况,但我们赞赏更好、更通用的解决方案。

我基本上重写了构造函数类来检查 MAP 节点,并在满足条件时将它们更改为“服务”节点。

package CoSession;

import org.yaml.snakeyaml.constructor.Constructor;
import org.yaml.snakeyaml.nodes.Node;
import org.yaml.snakeyaml.nodes.ScalarNode;
import org.yaml.snakeyaml.nodes.Tag;
import org.yaml.snakeyaml.nodes.MappingNode;
import org.yaml.snakeyaml.nodes.NodeTuple;

import java.util.*;

public class YamlConstructor extends Constructor {

public YamlConstructor() {
super();
}

public YamlConstructor(Class<? extends Object> theRoot) {
super(theRoot);
}

@Override
protected Object constructObject(Node node) {
// Check if this node is actually a Service node, and if so change the tag
// so that a Java Service object will be instantiated

//System.out.println("TAG: " + node.getTag().getValue());
if (node.getTag() == Tag.MAP) {
// A map is a collection of unsorted key-value pairs in a MappingNode.
// potentially a Service node
List<NodeTuple> list = ((MappingNode) node).getValue();

// scan the collection to check if there is a key that matches the key "image"
// (this key is required for a Service)
for (int i = 0; i < list.size(); i++) {
NodeTuple nt = list.get(i);
Node n = nt.getKeyNode();

// check if the key has the right tag
if (n.getTag() == Tag.STR) {
ScalarNode sn = (ScalarNode) n;
if ("image".equals(sn.getValue())) {
// All conditions met; we assume this is a Service node!
// Now change the tag of the node to Service
//System.out.println("***: Changed to Service");

node.setTag(new Tag(Service.class));
break;
}
}
}
}

// Use the default constructObject.
return super.constructObject(node);
}
}

关于java - 如何使用snakeyaml从yaml文件中读取顶级HashMap?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34593661/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com