代码之家  ›  专栏  ›  技术社区  ›  Simon

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

  •  1
  • Simon  · 技术社区  · 9 年前

    我正在尝试使用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代码(我从web上抓取了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 回复  |  直到 9 年前
        1
  •  1
  •   daggett    9 年前

    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]