YAML跟随引用如何覆盖前面的引用?

时间:2016-11-03 01:57:21

标签: yaml

merge:
  - &LEFT { x: 1, y: 1, r: 1 }
  - &BIG { x: 2, y: 2, r: 2 }
  - &SMALL { x: 3, y: 3, r: 3}

  - # Override
    << : [ *BIG, *LEFT, *SMALL ]
    x: 1
    label: big/left/small

我得到了输出:

{
    merge:
    [
         { x: 1, y: 1, r: 1 },
         { x: 2, y: 2, r: 2 },
         { x: 3, y: 3, r: 3 },
         { x: 1, y: 2, r: 2, label: 'big/left/small' } 
    ] 
}

但是结果不符合我的期望,合并对象中的最后一个我希望它是

{ x: 1, y: 3, r: 3, label: 'big/left/small' }.

如何处理YAML语法?

1 个答案:

答案 0 :(得分:0)

您不能使用YAML语法执行此操作,并且您的期望在多个级别上没有根据。

  1. 锚定元素(无论是否为序列元素)在合并别名或任何其他别名中使用时也不会神奇地消失,也不会以锚点为基础
  2. 顶层映射键(merge)没有神奇地消失,因为它的值是包含带有合并指示符的元素的序列标量
  3. Merge Key Language-Independent Type文档没有表明这样的删除,YAML规范也没有。根据YAML规范,锚点(和别名)通常不会以您用于加载YAML的语言的形式保留。因此,通常无法找到锚定元素并在加载后删除它们。

    一个通用的解决方案是让另一个顶级密钥default密钥与#34;定义&#34;锚点和仅与merge键关联的值一起工作:

    import ruamel.yaml
    
    yaml_str = """\
    default:
      - &LEFT { x: 1, y: 1, r: 1 }
      - &BIG { x: 2, y: 2, r: 2 }
      - &SMALL { x: 3, y: 3, r: 3}
    
    merge:
      # Override
      << : [ *BIG, *LEFT, *SMALL ]
      x: 1
      label: big/left/small
    """
    
    data = ruamel.yaml.load(yaml_str)['merge']
    print(data)
    

    给出:

    {'x': 1, 'r': 2, 'y': 2, 'label': 'big/left/small'}
    

    (输出中键的顺序当然是随机的)