【问题标题】:How can I parse yaml comments using java?如何使用 java 解析 yaml 注释?
【发布时间】:2018-10-15 06:31:46
【问题描述】:

我想在我的项目中使用一个 yml 配置文件。我正在使用 jackson-dataformat-yaml 来解析 yml 文件。但我也需要解析 yml cmets。我使用ruamel yaml 在python 中使用了类似的方法。我怎样才能在 java 中做同样的事情?

更新。

为了什么?好吧,我想通过使用命令行参数来覆盖我的配置选项。因此,要为每个选项生成描述消息,我想使用我的 cmets。像这样:

在我的config.yml

# Define a source directory
src: '/foo/bar'

# Define a destination directory
dst: '/foo/baz'

因此,当您使用 --help 标志运行程序时,您将看到以下输出:

Your program can be ran with the following options: 
--src   Define a source directory
--dst   Define a destination directory

这种模型的主要好处是您不需要重复相同的语句两次,因为它们可以从配置文件中检索到。

【问题讨论】:

  • 您不这样做,因为 YAML 定义 cmets 不得传达内容信息,因此,如果您以任何方式处理 cmets,则违反了 YAML 规范。在更实用的方面,Jackson 在后台使用的 SnakeYaml 不支持它。但也许这是一个 XY 问题,如果您描述您的用例,可能会有替代方案(例如使用 YAML 标签)。
  • @flyx 我刚刚添加了我的用例

标签: java parsing jackson yaml comments


【解决方案1】:

基本上,你有三层数据:

  • 您的配置架构。这定义了要在配置文件中定义的值。
  • 配置文件本身,描述当前机器上的常用配置。
  • 一次性切换,覆盖通常的配置。

每个值的描述属于架构,而不是配置文件本身。想一想:如果有人在他们的机器上编辑配置文件并更改了 cmets,你的帮助输出会突然显示不同的描述。

我的建议是将描述添加到架构中。架构是您将 YAML 加载到其中的 Java 类。我不确定您为什么使用 Jackson,因为它使用 SnakeYaml 作为解析器,并且 SnakeYaml 完全能够反序列化为 Java 类,但具有更多配置选项,因为它不像 Jackson 那样泛化 JSON 和 YAML可以。

以下是如何使用 SnakeYaml 的总体思路(注意,未经测试):

// ConfigParam.java
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
public @interface ConfigParam { String description(); }

// Configuration.java
public class Configuration {
    @ConfigParam("Define a source directory")
    String src;
    @ConfigParam("Define a destination directory")
    String dst;
}

// loading code
Yaml yaml = new Yaml(new Constructor(Configuration.class));
Configuration config = yaml.loadAs(input, Configuration.class);

// help generation code
System.out.println("Your program can be ran with the following options:")
for (Field field: Configuration.class.getFields()) {
    ConfigParam ann = field.getAnnotation(ConfigParam.class);
    if (ann != null) {
        System.out.println(String.format("--%s  %s", field.getName(), ann.description());
    }
}

为了将实际参数映射到配置,您还可以循环遍历类字段并将参数映射到在加载配置后的字段名称(用给定的值替换标准值)。

【讨论】:

  • 是的,你是对的。 ruby 之后我太放松了 :) 我写的代码几乎和你一样。非常感谢您的完整解释。
猜你喜欢
  • 2021-12-24
  • 1970-01-01
  • 2012-01-04
  • 1970-01-01
  • 2012-07-28
  • 1970-01-01
  • 2017-02-02
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多