我一直在使用SnakeYAML进行某些序列化/反序列化。我的应用程序结合了Python和Java,所以我需要在标签和类型上有一些“合理的行为”。
我在YAML文档上的问题/实际状态:
!!mypackage.MyClassA
someFirstField: normal string
someSecondField:
a: !!mypackage.ThisIsIt
subField: 1
subOtherField: 2
b: !!mypackage.ThisIsIt
subField: 3
subOtherField: 4
someThirdField:
subField: 5
subOtherField: 6
我通过重新实现someSecondField
并简单地执行checkGlobalTag
,实现了集合中标记的使用(请参阅示例return
)。如果我理解正确的话,这可以确保没有蛇形的智能清洁并保持标签。到目前为止一切都很好:我到处都需要这种类型。
但是,这还不够,因为someThirdField
也是!!mypackage.ThisIsIt
,但它有隐式标记,这是一个问题(Python不理解它)。还有其他一些不完整的案例(尝试在Python方面采取一些快捷方式,它们成了一个坏主意)。
确保所有用户定义的类都显示标记的正确方法是什么?我假设我应该覆盖Representer
上的一些方法,但我找不到哪一种方法。
答案 0 :(得分:1)
负责该线路"智能标签自动清洁"如下:
if (property.getType() == propertyValue.getClass())
对于班级representJavaBeanProperty
,可在Representer
中找到。
我找到的(丑陋)解决方案是使用以下内容扩展Representer
和@Override
representJavaBeanProperty
:
protected NodeTuple representJavaBeanProperty(Object javaBean,
Property property,
Object propertyValue,
Tag customTag) {
// Copy paste starts here...
ScalarNode nodeKey = (ScalarNode) representData(property.getName());
// the first occurrence of the node must keep the tag
boolean hasAlias = this.representedObjects.containsKey(propertyValue);
Node nodeValue = representData(propertyValue);
if (propertyValue != null && !hasAlias) {
NodeId nodeId = nodeValue.getNodeId();
if (customTag == null) {
if (nodeId == NodeId.scalar) {
if (propertyValue instanceof Enum<?>) {
nodeValue.setTag(Tag.STR);
}
}
// Copy-paste ends here !!!
// Ignore the else block --always maintain the tag.
}
}
return new NodeTuple(nodeKey, nodeValue);
这也会强制显式标记列表行为(之前通过覆盖checkGlobalTag
方法强制执行,现在已在representJavaBeanProperty
代码中实现)。