【问题标题】:Snakeyaml appears to unnecessarily wrap simple values in listsSnakeyaml 似乎不必要地将简单值包装在列表中
【发布时间】:2017-12-06 11:34:13
【问题描述】:

我正在尝试使用 Groovy 和 Snakeyaml 解析以下 YAML 文件(显然我已经清理了数据,但足以证明问题):

---
info:
  summary: Snakeyaml Issue
examples:
  - 1st example:
      name: Example 1
      sublist:
        - 0.1:
           foo: bar

我希望得到以下陈述:

println resource.info.summary
println resource.examples."1st example".name
println resource.examples."1st example".sublist."0.1"

屈服:

Snakeyaml Issue
Example 1
[foo:bar]

和:

println resource.examples."1st example".sublist."0.1".foo

屈服:

bar

但是,实际输出来自:

println resource.info.summary
println resource.examples."1st example".name
println resource.examples."1st example".sublist."0.1"
println resource.examples."1st example".sublist."0.1".foo

是:

Snakeyaml Issue
[Example 1]
[[[foo:bar]]]
[[bar]]

我只能通过包含列表索引来获得所需的输出:

println resource.info.summary
println resource.examples[0]."1st example".name
println resource.examples[0]."1st example".sublist[0]."0.1"
println resource.examples[0]."1st example".sublist[0]."0.1".foo

这似乎是不必要的。也许我误解了数据的结构?

为了完整起见,我用来说明问题的常规代码如下所示(我从网上抓取了 CustomerResolver 代码,以便将浮点数保持为字符串):

import org.yaml.snakeyaml.DumperOptions
import org.yaml.snakeyaml.Yaml
import org.yaml.snakeyaml.constructor.Constructor
import org.yaml.snakeyaml.nodes.Tag
import org.yaml.snakeyaml.representer.Representer
import org.yaml.snakeyaml.resolver.Resolver

def fileName = "example.yaml"
def Yaml yaml = new Yaml(new Constructor(), new Representer(), new DumperOptions(),
    new CustomResolver())
def resource = yaml.load(new File(fileName).newInputStream())

println resource.info.summary
println resource.examples."1st example".name
println resource.examples."1st example".sublist."0.1"
println resource.examples."1st example".sublist."0.1".foo

class CustomResolver extends Resolver {

    /*
     * Do not resolve float and timestamp
     */

    protected void addImplicitResolvers() {
        addImplicitResolver(Tag.BOOL, BOOL, "yYnNtTfFoO");
        addImplicitResolver(Tag.INT, INT, "-+0123456789");
        addImplicitResolver(Tag.MERGE, MERGE, "<");
        addImplicitResolver(Tag.NULL, NULL, "~nN\0");
        addImplicitResolver(Tag.NULL, EMPTY, null);

    }
}

有什么想法吗?

【问题讨论】:

  • 由于sublist 的值是一个序列,因此您似乎根本不需要指明您想要哪个元素。现在只有一个元素并不能保证永远不会有。我希望println resource.examples."1st example".sublist."0.1".foo 会引发错误。
  • 顺便说一句,你的第 8 个代码块中的 "0.1" 不应该是 "blah" 吗?
  • 谢谢@Anthon。我已经更正了“blah”错误(我在本地将 0.1 重命名为 blah 并删除了 CustomResolver 以查看是否是问题所在,并在我进行编辑时不小心将其保留);好地方。我想我现在明白了。 sublist 包含一系列映射,其中第一个映射以 0.1 作为键,映射 foo:bar 作为值?
  • 没错,子列表在这里包含一系列块样式的地图(只需要破折号而不是[ ])。有时,使用例如 JSON 来查看(块样式)YAML 文件会有所帮助。 online yaml parser(注意粘贴的内容)只是为了看看那里有什么。再说一遍:IMO 在正确的位置遗漏序列的索引应该会引发错误,而不是透明地创建列表。但也许这是一个特点 %-)
  • @Anthon 我同意。我宁愿它也抛出一个异常,因为这会突出我对数据的误解。也感谢 JSON 提示。

标签: java groovy yaml snakeyaml


【解决方案1】:

问题在于您如何访问 yaml

examples 首先包含 list,然后才包含 object 和键 1st example

对于您的情况,请尝试以下访问:

println resource.info.summary
println resource.examples[0]."1st example"
println resource.examples[0]."1st example".name
println resource.examples[0]."1st example".sublist[0]
println resource.examples[0]."1st example".sublist[0]."0.1"
println resource.examples[0]."1st example".sublist[0]."0.1".foo

要了解列表访问器的工作原理,请查看以下示例:

@Grab(group='org.yaml', module='snakeyaml', version='1.18')
import org.yaml.snakeyaml.Yaml

def Yaml yaml = new Yaml()
def resource = yaml.load(new StringReader('''---
info:
  summary: Snakeyaml Issue
examples:
  - 1st example:
      name: Example 1
  - 1st example:
      name: Example 2
  - 1st example:
      xname: Example 3
  - 2nd example:
      name: Example 4
'''))

println resource.examples."1st example"
//prints>  [[name:Example 1], [name:Example 2], [xname:Example 3], null]

println resource.examples."1st example".name
//prints> [Example 1, Example 2, null]

【讨论】:

  • 这是一个非常好的例子。谢谢@daggett。现在说得通了
  • @daggett 你知道在正确的位置省略序列索引时创建列表是否是一项功能?你真的可以通过println resource.examples."1st example".sublist."0.1".foo[0][0] 得到bar 吗?
  • 是的,你可以这样做,但对我来说最好在数组出现的地方展开。
  • 我同意。我需要序列索引出现在类似的小型 Python 程序中,可从 C++(或其他语言 here 调用,但我在点之间指定它们,就像映射键一样。
猜你喜欢
  • 2013-06-11
  • 2021-12-27
  • 2018-08-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-05-08
  • 1970-01-01
  • 2011-08-29
相关资源
最近更新 更多