Snakeyaml似乎不必要地在列表中包装简单值

时间:2017-07-03 08:59:24

标签: java groovy yaml snakeyaml

我正在尝试使用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

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

为了完整性,我用来说明问题的groovy代码如下所示(我从网上获取了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);

    }
}

有什么想法吗?

1 个答案:

答案 0 :(得分: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]