如何使用 Java 库将标记的 YAML 对象转换为 JSON 对象?
Posted
技术标签:
【中文标题】如何使用 Java 库将标记的 YAML 对象转换为 JSON 对象?【英文标题】:How do you convert tagged YAML objects to JSON objects using a Java library? 【发布时间】:2021-12-16 01:07:53 【问题描述】:如何解析包含标记映射的 YAML 文件并返回嵌套的 Java Map
换句话说,我想解析标记的 YAML 对象,就好像它们是带有类型条目的 JSON 对象一样。
例如,你如何解析这个:
!ControlGroup
name: myGroup
controls:
- !Button
name: button1
size: 10
- !Knob
name: knob1
maxValue: 11
size: 7
好像是这样的?:
objectType: ControlGroup
name: myGroup
controls:
- objectType: Button
name: button1
size: 10
- objectType: Knob
name: knob1
maxValue: 11
size: 7
我已经在我正在处理的项目中使用 SnakeYAML,所以如果存在使用 SnakeYAML 的解决方案,那将是理想的。
【问题讨论】:
我猜你可以注入一个自定义解析器,将标签处理为objectType: Button
对,但遗憾的是,SnakeYAML 存储库由于某种原因变得私有,所以我无法检查细节。如果缩进实际上并没有像您显示的代码那样被破坏,那么快速的正则表达式替换输入可能是简单的解决方案。
【参考方案1】:
我以单元测试的形式编写了code,它准确地解析了您使用snakeYml
提供的文件。运行它。
@Test
void testYamlConvert() throws IOException
// Step 1: Raad in file
var in = this.getClass().getResourceAsStream("/test.yml");
// System.out.println(in);
String yml = IOUtils.toString(in,"UTF-8");
// Step 2: Do in memory replacement to standard form
Pattern p = Pattern.compile("!!(.*)");
Matcher m = p.matcher(yml);
String ymlWithReplacement = yml;
while (m.find())
var nameToken = m.group().substring(2);
// System.out.println("Name token:"+nameToken);
ymlWithReplacement=ymlWithReplacement.replace("!!"+nameToken, "objectType: "+nameToken);
// System.out.println(ymlWithReplacement);
// Step 3: Do the parse ...
Yaml yaml = new Yaml();
var myYamlMap = (Map<String,Object>) yaml.load(ymlWithReplacement);
for(var entry : myYamlMap.entrySet())
System.out.println("Key:" + entry.getKey() + "Value:" + entry.getValue());
生成的地图如下所示。
从这里获取必要的数据应该很容易。 cmets中解释了工作原理。
如果您需要其他东西让我能够领取赏金,请告诉我!
【讨论】:
解决方案应该内联添加。 10 年后,链接可能会消失,并且无法访问解决方案,即使问题可能仍然相关 好的。会做。谢谢。 @user10264746 这个解决方案对你有用吗?【参考方案2】:这是有效的,
!!ControlGroup
name: myGroup
controls:
- !!Button
name: button1
size: 10
- !!Knob
name: knob1
maxValue: 11
size: 7
Yaml yaml = new Yaml();
InputStream url = SnakeYml.class.getClassLoader().getResourceAsStream("sample.yaml");
Map<String, Object> obj = yaml.load(url);
System.out.println(obj);
public class ControlGroup
String name;
public ControlGroup() ;
public String getName()
return name;
public void setName(String name)
this.name = name;
....
【讨论】:
不幸的是,这并没有解决问题,因为它没有将条目“objectType:ControlGroup”插入到生成的地图中。【参考方案3】:试试这个,
ControlGroup controlGroup = yaml.load(url);
controlGroup.setObjectType(ControlGroup.class.getName());
System.out.println(yaml.dumpAsMap(controlGroup));
public class ControlGroup
String objectType = this.getClass().getTypeName();
String name;
public ControlGroup() ;
public String getName()
return name;
public void setName(String name)
this.name = name;
public String getObjectType()
return this.getClass().getTypeName();
public void setObjectType(String className)
this.objectType = className;
MAP -->
name: myGroup
objectType: ControlGroup
【讨论】:
我很欣赏这篇文章,但它实际上并没有解决问题,因为它没有为“旋钮”和“按钮”创建地图条目。更重要的是,我正在寻找一种不涉及向每个 YAML 实例化类添加两种方法的解决方案。以上是关于如何使用 Java 库将标记的 YAML 对象转换为 JSON 对象?的主要内容,如果未能解决你的问题,请参考以下文章
如何使用处理 Java 库将自定义形状数组和字符串数组合并到 JSON 对象中
在颤动中使用 Chopper 库将 JSON 响应转换为模型对象?