如何使用 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 对象,其中每个 Java Map 包含来自相应 YAML 映射的所有条目,以及键为字符串“objectType”的条目” 并且值是标签的(字符串)名称?

换句话说,我想解析标记的 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 对象中

使用 Java 标准库将 HTML 字符转换回文本

在颤动中使用 Chopper 库将 JSON 响应转换为模型对象?

我可以使用哪些库将 POJO 绑定到 TDD 的外部文件而无需太多开销?

如何在 Java 中将 YAML 转换为 JSON?

使用点分路径键字符串访问 Ruby 哈希