我正在考虑在SnakeYAML中使用自定义构造,但不确定如何实现嵌套。我使用this example作为推荐人。
在链接的示例中,相关的YAML和结构是,
- !circle
center: {x: 73, y: 129}
radius: 7
private class ConstructCircle extends AbstractConstruct {
@SuppressWarnings("unchecked")
public Object construct(Node node) {
MappingNode mnode = (MappingNode) node;
Map<Object, Object> values = constructMapping(mnode);
Circle circle = new Circle((Map<String, Integer>) values.get("center"), (Integer) values.get("radius"));
return circle;
}
}现在,让我们将YAML更改为
- !circle
center: !point
x: 73
y: 129
radius: 7我想使用另一个AbstractConstruct来解析那个!point对象,但是在ConstructCircle上下文中这样做。我对Construct/Node关系的理解非常不稳定,我不知道如何在自定义构造函数中使用自定义构造函数。有什么想法或资源吗?
发布于 2015-05-17 03:09:48
好了,在用SnakeYaml做了更多的项目之后。我想我终于明白你的问题了。嵌套由SnakeYaml自动处理。你不必担心这一点。您需要做的就是为!point创建另一个结构,并将其添加到自定义构造函数类中的地图yamlConstructors中。这将在任何地方启用!point标记。
point结构可能如下所示:
class PointConstruct extends AbstractConstruct{
public Object construct(Node node){
String line = (String)constructScalar((ScalarNode)node);
Pattern pointPattern = Pattern.compile("\\((\\d+),(\\d+\\)");
Matcher m = pointPattern.matcher(line);
if(m.find())
return new Point(m.group(1),m.group(2));
throw new RuntimeException("Could not parse a point");
}
}然后,您的Yaml文件将如下所示:
!circle
center: !point (73,179)
radius: 7我认为这个输出看起来好多了。如果您将ImplicitResolver添加到yaml:
yaml.addImplicitResolver(new Tag("!point"), Pattern.compile("\\((\\d+),(\\d+\\)"),"(");那么yaml应该是这样的。
!circle
center: (73,179)
radius: 7或者,您可以放弃编写新的结构,只需让Point遵循bean模式,并使用如下所示的内容。
!circle
center !!package.goes.here.Point
x: 73
y: 179
radius: 7无论如何,希望这个答案比我上一个更清楚。
发布于 2013-08-31 05:43:25
我已经写了一个又快又脏的customConstructMapping()来解析你的嵌套结构。
public Map<Object, Object> customConstructMapping(MappingNode mnode) {
Map<Object, Object> values = new HashMap<Object, Object>();
Map<String, Integer> center = new HashMap<String, Integer>();
List<NodeTuple> tuples = mnode.getValue();
for (NodeTuple tuple : tuples) {
ScalarNode knode = (ScalarNode) tuple.getKeyNode();
String key = knode.getValue();
Node vnode = tuple.getValueNode();
if (vnode instanceof MappingNode) {
MappingNode nvnode = (MappingNode) vnode;
if ("!point".equals(nvnode.getTag().getValue())) {
List<NodeTuple> vtuples = nvnode.getValue();
for (NodeTuple vtuple : vtuples) {
ScalarNode vknode = (ScalarNode) vtuple.getKeyNode();
ScalarNode vvnode = (ScalarNode) vtuple.getValueNode();
Integer val = Integer.parseInt(vvnode.getValue());
center.put(vknode.getValue(), val);
}
values.put(key, center);
}
} else if (vnode instanceof ScalarNode) {
Integer val = Integer.parseInt(((ScalarNode) vnode).getValue());
values.put(key, val);
}
}
return values;
}发布于 2014-10-06 23:11:27
Snake Yaml应该自己负责嵌套。您只需确保将所有AbstractConstructs添加到自定义构造函数内的yamlConstructors字段中。
https://stackoverflow.com/questions/18412721
复制相似问题